Component Usage FAQ
This document addresses common questions and solutions related to component usage in uni-app development.
Basic Component Issues
Q: Unable to modify component styles
Problem Description: Cannot modify default component styles, or style modifications are ineffective.
Solutions:
Use class selectors to override styles (increase selector specificity):
css/* Increase specificity with parent selector */ .page .btn { background-color: #ff0000; }
Use
!important
to increase style priority:css.btn { background-color: #ff0000 !important; }
Use inline styles:
html<button class="btn" style="background-color: #ff0000;">Button</button>
For mini-program native components, use official style variables:
css/* WeChat mini-program button style variables */ page { --button-height: 88rpx; --button-background-color: #ff0000; }
Use conditional compilation for different platforms:
css/* #ifdef MP-WEIXIN */ button { background-color: #ff0000; } /* #endif */ /* #ifdef H5 */ button { background-color: #00ff00; } /* #endif */
Q: Component events not triggering
Problem Description: Bound event handlers are not being triggered.
Solutions:
Check if event names are correct:
html<!-- Correct usage --> <button @tap="handleTap">Button</button> <button @click="handleClick">Button</button> <!-- Incorrect usage --> <button @tap="handleTap()">Button</button> <!-- Don't call functions in template -->
Check if event handlers are properly defined:
jsexport default { methods: { // Correct definition handleTap(e) { console.log('Button clicked', e); } } }
Check for event bubbling prevention:
html<!-- Prevent event bubbling --> <view @tap.stop="handleViewTap"> <button @tap="handleButtonTap">Button</button> </view>
For custom components, ensure events are properly emitted:
js// In child component methods: { handleClick() { this.$emit('myevent', { data: 'some data' }); } }
html<!-- In parent component --> <custom-component @myevent="handleMyEvent"></custom-component>
Check for nested component event issues:
html<!-- Use .native modifier to listen to native events on component root element --> <custom-component @tap.native="handleTap"></custom-component>
Q: Component display abnormalities
Problem Description: Components display incorrectly, such as wrong size, position, or content.
Solutions:
Check if component properties are correctly set:
html<!-- Correctly set image properties --> <image src="/static/logo.png" mode="aspectFit" style="width: 200rpx; height: 200rpx;"></image>
Check if data binding is correct:
html<!-- Ensure title variable exists and has value --> <text>{{ title || 'Default Title' }}</text>
Use v-if and v-show to control display:
html<!-- Don't render when content doesn't exist --> <view v-if="content">{{ content }}</view> <!-- Hide but still render when content doesn't exist --> <view v-show="content">{{ content }}</view>
Check for style conflicts:
css/* Use namespace to avoid style conflicts */ .my-component .title { font-size: 32rpx; }
For mini-program native component layering issues:
css/* Adjust z-index to solve layering issues */ .cover-view { z-index: 10; }
Form Component Issues
Q: Input fields cannot get focus
Problem Description: Input, textarea and other input fields cannot get focus normally.
Solutions:
Use focus property:
html<input :focus="isFocus" @blur="handleBlur" />
jsexport default { data() { return { isFocus: false } }, methods: { setFocus() { this.isFocus = true; }, handleBlur() { this.isFocus = false; } } }
Use uni.createSelectorQuery to get element and set focus:
jsfocusInput() { const query = uni.createSelectorQuery().in(this); query.select('.input').boundingClientRect(data => { // Ensure element exists if (data) { // Set focus uni.createSelectorQuery().in(this).select('.input').fields({ context: true, }, res => { res.context && res.context.focus(); }).exec(); } }).exec(); }
Check z-index and overlay issues:
css.input-wrapper { position: relative; z-index: 10; /* Ensure input is on top layer */ }
Handle keyboard popup issues:
json// pages.json { "pages": [ { "path": "pages/index/index", "style": { "app-plus": { "softinputMode": "adjustResize", "softinputNavBar": "none" } } } ] }
Q: Form data two-way binding issues
Problem Description: Issues occur when using v-model for two-way data binding.
Solutions:
Correctly use v-model:
html<input v-model="inputValue" />
jsexport default { data() { return { inputValue: '' } } }
For complex forms, use v-model.lazy to reduce update frequency:
html<input v-model.lazy="inputValue" />
Use value + event instead of v-model:
html<input :value="inputValue" @input="inputValue = $event.target.value" />
For mini-program platforms, handle event object differences:
html<input :value="inputValue" @input="handleInput" />
jsmethods: { handleInput(e) { // Compatible with different platform event objects this.inputValue = e.detail.value || e.target.value; } }
For custom components, correctly implement v-model:
js// Custom component export default { props: { value: { type: String, default: '' } }, methods: { handleInput(e) { const value = e.detail.value; this.$emit('input', value); } } }
html<!-- In custom component --> <input :value="value" @input="handleInput" /> <!-- Using custom component --> <custom-input v-model="inputValue"></custom-input>
Q: Form submission and validation issues
Problem Description: Form validation fails or submission is unsuccessful.
Solutions:
Implement basic form validation:
jsmethods: { submitForm() { // Validate form if (!this.username) { uni.showToast({ title: 'Please enter username', icon: 'none' }); return; } if (this.password.length < 6) { uni.showToast({ title: 'Password must be at least 6 characters', icon: 'none' }); return; } // Submit form uni.request({ url: 'https://api.example.com/login', method: 'POST', data: { username: this.username, password: this.password }, success: (res) => { // Handle success response }, fail: (err) => { // Handle error } }); } }
Use third-party validation library:
js// Using async-validator import Schema from 'async-validator'; export default { methods: { validateForm() { const descriptor = { username: [ { required: true, message: 'Please enter username' }, { min: 3, max: 20, message: 'Username length should be 3-20 characters' } ], password: [ { required: true, message: 'Please enter password' }, { min: 6, message: 'Password must be at least 6 characters' } ], email: [ { type: 'email', message: 'Please enter a valid email address' } ] }; const validator = new Schema(descriptor); validator.validate(this.formData, (errors, fields) => { if (errors) { // Show first error uni.showToast({ title: errors[0].message, icon: 'none' }); } else { // Validation passed, submit form this.submitForm(); } }); } } }
Handle form reset:
html<form @submit="handleSubmit" @reset="handleReset"> <input name="username" v-model="formData.username" /> <input name="password" v-model="formData.password" type="password" /> <button form-type="submit">Submit</button> <button form-type="reset">Reset</button> </form>
jsmethods: { handleSubmit(e) { // Prevent default submit behavior e.preventDefault && e.preventDefault(); this.validateForm(); }, handleReset() { this.formData = { username: '', password: '', email: '' }; } }
Handle file upload:
html<button @tap="chooseImage">Choose Image</button> <image v-if="imageUrl" :src="imageUrl" mode="aspectFit"></image>
jsmethods: { chooseImage() { uni.chooseImage({ count: 1, success: (res) => { const tempFilePath = res.tempFilePaths[0]; this.imageUrl = tempFilePath; // Upload image uni.uploadFile({ url: 'https://api.example.com/upload', filePath: tempFilePath, name: 'file', success: (uploadRes) => { const data = JSON.parse(uploadRes.data); this.formData.imageId = data.id; }, fail: (err) => { uni.showToast({ title: 'Image upload failed', icon: 'none' }); } }); } }); } }
List Component Issues
Q: scroll-view scrolling issues
Problem Description: scroll-view component cannot scroll normally or scrolling effect is abnormal.
Solutions:
Ensure fixed height is set:
html<scroll-view scroll-y="true" class="scroll-container"> <!-- Content --> </scroll-view>
css.scroll-container { height: 500rpx; /* Must set fixed height */ }
Use scroll-into-view to scroll to specified element:
html<scroll-view scroll-y="true" class="scroll-container" :scroll-into-view="scrollToId" > <view id="item1" class="item">Item 1</view> <view id="item2" class="item">Item 2</view> <view id="item3" class="item">Item 3</view> </scroll-view>
jsexport default { data() { return { scrollToId: '' } }, methods: { scrollToItem(id) { this.scrollToId = id; } } }
Listen to scroll events:
html<scroll-view scroll-y="true" class="scroll-container" @scroll="handleScroll" > <!-- Content --> </scroll-view>
jsmethods: { handleScroll(e) { const scrollTop = e.detail.scrollTop; console.log('Scroll position:', scrollTop); } }
Solve scroll stuttering issues:
css/* Enable hardware acceleration */ .scroll-container { -webkit-overflow-scrolling: touch; /* iOS smooth scrolling */ transform: translateZ(0); /* Enable hardware acceleration */ }
Handle pull-to-refresh and load more:
html<scroll-view scroll-y="true" class="scroll-container" @scrolltolower="loadMore" :refresher-enabled="true" @refresherrefresh="refresh" :refresher-triggered="isRefreshing" > <!-- Content --> </scroll-view>
jsexport default { data() { return { list: [], page: 1, isRefreshing: false } }, methods: { // Load more loadMore() { this.page++; this.loadData(); }, // Refresh refresh() { this.isRefreshing = true; this.page = 1; this.list = []; this.loadData().finally(() => { this.isRefreshing = false; }); }, // Load data async loadData() { try { const res = await uni.request({ url: `https://api.example.com/list?page=${this.page}` }); if (this.page === 1) { this.list = res.data; } else { this.list = [...this.list, ...res.data]; } } catch (err) { uni.showToast({ title: 'Load failed', icon: 'none' }); } } } }
Q: Long list performance issues
Problem Description: Long list rendering is stuttering or memory usage is too high.
Solutions:
Use virtual list optimization:
html<recycle-list class="list" :list="list" :item-size="100"> <cell v-for="(item, index) in list" :key="index"> <view class="item"> <text class="title">{{ item.title }}</text> <text class="desc">{{ item.desc }}</text> </view> </cell> </recycle-list>
Paginated data loading:
jsexport default { data() { return { list: [], page: 1, pageSize: 20, hasMore: true, loading: false } }, onLoad() { this.loadData(); }, onReachBottom() { if (this.hasMore && !this.loading) { this.loadMore(); } }, methods: { async loadData() { if (!this.hasMore || this.loading) return; this.loading = true; try { const res = await uni.request({ url: 'https://api.example.com/list', data: { page: this.page, pageSize: this.pageSize } }); const data = res.data; if (this.page === 1) { this.list = data.list; } else { this.list = [...this.list, ...data.list]; } this.hasMore = data.hasMore; this.page++; } catch (err) { uni.showToast({ title: 'Load failed', icon: 'none' }); } finally { this.loading = false; } }, loadMore() { this.loadData(); }, refresh() { this.page = 1; this.hasMore = true; this.list = []; this.loadData(); } } }
Use computed properties to filter data:
jsexport default { data() { return { rawList: [], keyword: '' } }, computed: { filteredList() { if (!this.keyword) return this.rawList; return this.rawList.filter(item => item.title.includes(this.keyword) || item.desc.includes(this.keyword) ); } } }
Optimize list item rendering:
html<view class="list"> <view v-for="(item, index) in list" :key="item.id" class="item" :class="{ 'even': index % 2 === 0 }" > <!-- Use simple structure --> <text class="title">{{ item.title }}</text> <!-- Avoid using complex components in list items --> </view> </view>
Use v-once to optimize static content:
html<view class="list"> <view v-for="(item, index) in list" :key="item.id" class="item" > <!-- Static content rendered only once --> <text class="label" v-once>Title:</text> <text class="title">{{ item.title }}</text> </view> </view>
Q: swiper component issues
Problem Description: swiper component switching is abnormal or display is incorrect.
Solutions:
Ensure correct height is set:
html<swiper class="swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="500"> <swiper-item v-for="(item, index) in banners" :key="index"> <image :src="item.image" mode="aspectFill" class="swiper-image"></image> </swiper-item> </swiper>
css.swiper { height: 300rpx; } .swiper-image { width: 100%; height: 100%; }
Handle dynamic content loading:
html<swiper class="swiper" :indicator-dots="true" :current="current" @change="handleChange" v-if="banners.length > 0" > <swiper-item v-for="(item, index) in banners" :key="index"> <image :src="item.image" mode="aspectFill" class="swiper-image" @load="imageLoaded" ></image> </swiper-item> </swiper>
jsexport default { data() { return { banners: [], current: 0, imagesLoaded: 0 } }, methods: { handleChange(e) { this.current = e.detail.current; }, imageLoaded() { this.imagesLoaded++; } } }
Handle circular scrolling issues:
html<swiper class="swiper" :indicator-dots="true" :autoplay="true" :circular="true" :interval="3000" :duration="500" > <!-- Content --> </swiper>
Handle stuttering issues:
html<swiper class="swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="500" :display-multiple-items="1" :next-margin="nextMargin" :previous-margin="previousMargin" > <!-- Content --> </swiper>
jsexport default { data() { return { nextMargin: '50rpx', previousMargin: '50rpx' } } }
Custom Component Issues
Q: Component communication issues
Problem Description: Parent-child components cannot communicate normally or data transfer fails.
Solutions:
Use props to pass data to child components:
html<!-- Parent component --> <child-component :title="title" :list="list"></child-component>
js// Child component export default { props: { title: { type: String, default: 'Default Title' }, list: { type: Array, default: () => [] } } }
Use events to pass data to parent components:
js// Child component methods: { sendData() { this.$emit('update', { value: this.value }); } }
html<!-- Parent component --> <child-component @update="handleUpdate"></child-component>
js// Parent component methods: { handleUpdate(data) { console.log('Received data from child component:', data); } }
Use ref to directly access child components:
html<!-- Parent component --> <child-component ref="childComp"></child-component>
js// Parent component methods: { callChildMethod() { this.$refs.childComp.childMethod(); } }
Use provide/inject for deep component communication:
js// Ancestor component export default { provide() { return { theme: this.theme, updateTheme: this.updateTheme }; }, data() { return { theme: 'light' } }, methods: { updateTheme(newTheme) { this.theme = newTheme; } } }
js// Descendant component export default { inject: ['theme', 'updateTheme'], methods: { changeTheme() { this.updateTheme('dark'); } } }
Use Vuex or uni-app global state management:
js// store.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { count: 0, user: null }, mutations: { increment(state) { state.count++; }, setUser(state, user) { state.user = user; } }, actions: { login({ commit }, userData) { // Async login return new Promise((resolve, reject) => { uni.request({ url: 'https://api.example.com/login', method: 'POST', data: userData, success: (res) => { commit('setUser', res.data.user); resolve(res.data); }, fail: reject }); }); } } });
js// Using in components import { mapState, mapMutations, mapActions } from 'vuex'; export default { computed: { ...mapState(['count', 'user']) }, methods: { ...mapMutations(['increment']), ...mapActions(['login']), async handleLogin() { try { await this.login({ username: 'test', password: '123456' }); uni.showToast({ title: 'Login successful' }); } catch (err) { uni.showToast({ title: 'Login failed', icon: 'none' }); } } } }
Q: Component lifecycle issues
Problem Description: Component lifecycle hooks don't execute as expected or execution order is abnormal.
Solutions:
Understand component lifecycle order:
jsexport default { beforeCreate() { console.log('beforeCreate'); }, created() { console.log('created'); }, beforeMount() { console.log('beforeMount'); }, mounted() { console.log('mounted'); }, beforeUpdate() { console.log('beforeUpdate'); }, updated() { console.log('updated'); }, beforeDestroy() { console.log('beforeDestroy'); }, destroyed() { console.log('destroyed'); } }
Use onReady instead of mounted for view rendering completion logic:
jsexport default { mounted() { // View might not be fully rendered yet console.log('mounted'); }, onReady() { // View has been fully rendered console.log('onReady'); this.initChart(); } }
Handle cleanup work when component unmounts:
jsexport default { data() { return { timer: null } }, mounted() { // Set timer this.timer = setInterval(() => { console.log('Timer executing'); }, 1000); }, beforeDestroy() { // Clear timer if (this.timer) { clearInterval(this.timer); this.timer = null; } } }
Use nextTick to handle operations after view updates:
jsmethods: { updateData() { this.list = [...this.list, { id: Date.now(), text: 'New Item' }]; // Wait for view update this.$nextTick(() => { // View has been updated const lastItem = document.querySelector('.item:last-child'); if (lastItem) { lastItem.scrollIntoView({ behavior: 'smooth' }); } }); } }
Understand the difference between page and component lifecycles:
jsexport default { // Vue component lifecycle created() { console.log('Component created'); }, mounted() { console.log('Component mounted'); }, // uni-app page lifecycle onLoad() { console.log('Page onLoad'); }, onShow() { console.log('Page onShow'); }, onReady() { console.log('Page onReady'); }, onHide() { console.log('Page onHide'); }, onUnload() { console.log('Page onUnload'); } }
Q: Component reuse and performance issues
Problem Description: Component reuse leads to performance degradation or state confusion.
Solutions:
Use key attribute to ensure proper component reuse:
html<custom-component v-for="(item, index) in list" :key="item.id" :data="item" ></custom-component>
Avoid complex calculations in templates:
html<!-- Not recommended --> <view>{{ getComplexData(item) }}</view> <!-- Recommended --> <view>{{ item.processedData }}</view>
jsexport default { computed: { processedList() { return this.list.map(item => ({ ...item, processedData: this.getComplexData(item) })); } }, methods: { getComplexData(item) { // Complex calculation return result; } } }
Use keep-alive to cache component state:
html<keep-alive> <component :is="currentComponent"></component> </keep-alive>
Use v-show instead of frequently toggled v-if:
html<!-- Use v-show for frequent toggling --> <view v-show="isVisible" class="panel">Content</view> <!-- Use v-if when condition rarely changes --> <view v-if="isLoggedIn" class="user-panel">User Info</view>
Use functional components to optimize simple components:
js// Functional component Vue.component('my-component', { functional: true, props: { title: String }, render(h, context) { return h('view', { class: 'my-component' }, [ h('text', context.props.title) ]); } });
Third-party Component Issues
Q: uni-ui component usage issues
Problem Description: Issues encountered when using uni-ui component library.
Solutions:
Correctly install and import uni-ui:
js// Install // npm install @dcloudio/uni-ui // Global registration in main.js import uniCard from '@dcloudio/uni-ui/lib/uni-card/uni-card.vue' Vue.component('uni-card', uniCard) // Or import on demand in components import { uniCard } from '@dcloudio/uni-ui' export default { components: { uniCard } }
Handle easycom configuration:
json// pages.json { "easycom": { "autoscan": true, "custom": { "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue" } } }
Handle style issues:
js// Import base styles in App.vue <style> @import '@dcloudio/uni-ui/lib/uni-scss/index.scss'; </style>
Handle component events:
html<uni-calendar :insert="false" :lunar="true" :start-date="'2019-3-2'" :end-date="'2019-5-20'" @change="change" @confirm="confirm" />
jsexport default { methods: { change(e) { console.log('Date changed', e); }, confirm(e) { console.log('Confirm selection', e); } } }
Custom themes:
scss// uni.scss $uni-primary: #007aff; $uni-success: #4cd964; $uni-warning: #f0ad4e; $uni-error: #dd524d;
Q: Map component issues
Problem Description: Issues with display or interaction when using map components.
Solutions:
Correctly set map dimensions:
html<map id="map" class="map" :latitude="latitude" :longitude="longitude" :markers="markers" :scale="scale" ></map>
css.map { width: 100%; height: 300px; }
Handle map controls:
html<map id="map" class="map" :latitude="latitude" :longitude="longitude" :markers="markers" :scale="scale" :show-location="true" :enable-zoom="true" :enable-scroll="true" @markertap="onMarkerTap" @regionchange="onRegionChange" ></map>
jsexport default { data() { return { latitude: 39.909, longitude: 116.39742, scale: 16, markers: [{ id: 1, latitude: 39.909, longitude: 116.39742, title: 'Marker', iconPath: '/static/marker.png', width: 32, height: 32 }] } }, methods: { onMarkerTap(e) { console.log('Marker tapped', e); }, onRegionChange(e) { console.log('Map region changed', e); } } }
Use map context:
jsexport default { data() { return { mapContext: null } }, onReady() { // Create map context this.mapContext = uni.createMapContext('map', this); }, methods: { moveToLocation() { // Move to current location this.mapContext.moveToLocation(); }, getCenterLocation() { // Get center location this.mapContext.getCenterLocation({ success: (res) => { console.log('Center location', res.latitude, res.longitude); } }); } } }
Handle permission issues:
jsexport default { onLoad() { // Check location permission uni.getSetting({ success: (res) => { if (!res.authSetting['scope.userLocation']) { uni.authorize({ scope: 'scope.userLocation', success: () => { this.initMap(); }, fail: () => { uni.showModal({ title: 'Notice', content: 'Location permission is required to use map features', confirmText: 'Go to Settings', success: (res) => { if (res.confirm) { uni.openSetting(); } } }); } }); } else { this.initMap(); } } }); }, methods: { initMap() { // Initialize map } } }
Handle platform differences:
jsexport default { data() { return { // Different map configurations for different platforms mapConfig: { // #ifdef MP-WEIXIN controls: [{ id: 1, position: { left: 10, top: 10, width: 40, height: 40 }, iconPath: '/static/location.png', clickable: true }], // #endif // #ifdef APP-PLUS polyline: [{ points: [ { latitude: 39.909, longitude: 116.39742 }, { latitude: 39.90, longitude: 116.39 } ], color: '#FF0000DD', width: 4 }] // #endif } } } }
Common Issue Troubleshooting Process
When encountering component issues, follow these steps for troubleshooting:
Check basic configuration:
- Confirm components are correctly imported and registered
- Check if property and event names are correct
- Confirm data binding is correct
Check console errors:
- Look for error messages in console
- Analyze error stack to locate issues
- Check warning messages
Use developer tools:
- Use Vue Devtools to check component state
- Use mini-program developer tools to debug components
- Use breakpoint debugging to trace execution flow
Simplify the problem:
- Create minimal reproduction example
- Gradually remove complex logic to find root cause
- Try using basic components instead of complex ones
Component Debugging Techniques
Debugging Custom Components
Use console.log to output key information:
jsexport default { props: { value: String }, watch: { value(newVal, oldVal) { console.log('value changed:', oldVal, '->', newVal); } }, mounted() { console.log('Component mounted, props:', this.$props); }, updated() { console.log('Component updated'); } }
Use Vue Devtools for debugging:
- Use Vue Devtools in H5 to inspect component tree
- View component props, data, computed properties
- Monitor event triggers
Add debug styles:
css.debug-component { border: 1px solid red; }
html<view class="my-component" :class="{ 'debug-component': isDebug }"> <!-- Component content --> </view>
Use conditional breakpoints:
jsmethods: { handleClick() { // Set breakpoint under specific conditions if (this.count > 5) { console.log('Breakpoint location'); // Set breakpoint here } } }
Debugging Third-party Components
Check component documentation and examples:
- Read official documentation to understand component usage
- Refer to example code for correct usage
- Check common issues and solutions
Check version compatibility:
- Confirm component version is compatible with framework version
- Check changelog for updates
- Try upgrading or downgrading component version
View component source code:
- Analyze component implementation principles
- Understand component internal working mechanisms
- Find potential problem points
Create simplified test cases:
- Test components in new projects
- Gradually add complexity to find problem trigger conditions
- Exclude interference from other project factors
Best Practices
Component Design Principles
Single Responsibility Principle:
- Each component should only be responsible for one function
- Avoid creating large and comprehensive complex components
- Split complex components into multiple simple components
Reusability:
- Design general components rather than specific scenario components
- Use props to configure component behavior
- Avoid tight coupling between components
Testability:
- Component logic should be clear and easy to test
- Avoid side effects, use pure functions
- Separate business logic from UI rendering
Maintainability:
- Component structure should be clear with concise code
- Add necessary comments and documentation
- Follow consistent naming and style conventions
Component Performance Optimization
Avoid unnecessary rendering:
- Use v-once to render static content
- Use v-if and v-show appropriately
- Use key to optimize list rendering
Reduce computation:
- Use computed to cache calculation results
- Avoid complex calculations in templates
- Use watch to monitor data changes
Lazy loading:
- Use dynamic components for on-demand loading
- Use v-if to conditionally render non-critical components
- Implement component lazy loading
Optimize update mechanisms:
- Use immutable data patterns
- Avoid deeply nested data structures
- Use Object.freeze to freeze immutable objects
Component Library Development
Unified design specifications:
- Define consistent visual styles
- Unified interaction patterns
- Consistent naming conventions
Good documentation:
- Detailed API descriptions
- Rich example code
- Frequently asked questions
Version management:
- Follow semantic versioning standards
- Maintain detailed changelogs
- Consider backward compatibility
Test coverage:
- Unit tests ensure functionality correctness
- Visual regression tests ensure style consistency
- Cross-platform compatibility testing
Reference Resources
- uni-app Official Component Documentation
- uni-ui Component Library
- Vue.js Component Documentation
- WeChat Mini Program Component Documentation
For more component guidance, refer to the API Reference and Best Practices Guide.