uni-app 中的组件和 Vue 中一样。
创建组件
在 uni-app 中通过创建一个
.vue
文件,即创建一个组件,其他组件可以将该组件通过import
的方式导入,在通过 components 进行注册即可。
- 在根目录下新建 components 目录,并新建
test.vue
组件。 - 在
pages/index.vue
页面中使用 test 组件。<template> <view> <!-- 使用组件 --> <test></test> </view> </template> <script> // 导入组件 import test from '../../components/test.vue' export default { // 注册组件 components: { test }, } </script>
组件的生命周期
uni-app 中组件的生命周期和 Vue.js相同。详情
DOM 仅在 H5 中支持,APP和小程序不支持。
生命周期钩子函数 | 说明 |
---|---|
beforeCreate | 在实例初始化之后被调用。 |
created | 在实例创建完成后被立即调用。 |
beforeMount | 在挂载开始之前被调用。 |
mounted | 挂载到实例上去之后调用。 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick。 详情 |
beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前。 |
updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。 |
destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 |
-
初始化阶段
beforeCreate / created
- 在Vue实例创建完成之前触发,还没有初始化data中的数据以及methods中的方法。
- 可以在这里 最早发起 Ajax 请求,从而初始化 data 数据。
-
挂载阶段
beforeMount / mounted
- 将 template 模板中的内容在内存中编译完成,会立即执行函数,并将模板结构替换到页面上。
-
更新阶段
beforeUpdate / updated
- 当 data 里数据改变,并更新页面元素时,会触发更新。
- 在 updated 中获取最新的dom元素。
-
销毁阶段
beforeDestroy / destroyed
- 手动清除计时器/定时器/全局事件。
- 手动清除计时器/定时器/全局事件。
<template>
<view id="myView">
<h3>test组件</h3>
</view>
</template>
<script>
export default {
name:"test",
data() {
return {
num: 3
};
},
// 初始化
beforeCreate() {
console.log('beforeCreate:实例已经开始初始化了', this.num)
},
created() {
console.log('实例创建完成', this.num)
},
// 挂载
beforeMount() {
console.log('beforeMount:DOM对象未渲染', document.getElementById('myView'))
},
mounted() {
console.log('mounted:DOM对象渲染完成', document.getElementById('myView'))
},
// 销毁
beforeDestroy() {
console.log('组件销毁之前')
},
destroyed() {
console.log('组件已销毁')
}
}
</script>
组件通讯
官方文档:详情
父向子通信
-
父组件通过
v-bind
给子组件传值。<template> <view> <test :title='title'></test> </view> </template> <script> import test from '../../components/test.vue'; export default { data() { return { title: 'Hello', } }, components: { test }, } </script>
-
子组件通过 props 接收父组件传来的值。
<template> <view id="myView"> 这是父组件传递过来的数据:{{title}} </view> </template> <script> export default { props: ['title'] } </script>
子向父通信
单向数据流:父组件向子组件发送事件,子组件触发。
-
子组件通过
this.$emit('事件名', 值)
触发事件,给父组件传值。<template> <view> <button type="default" @click="sendNum">给父组件传值</button> </view> </template> <script> export default { data() { return { num: 3 }; }, methods: { sendNum() { this.$emit('myEven', this.num) } } } </script>
-
父组件向子组件发送事件
@事件名='方法名'
调用方法接收子组件传递过来的值。<template> <view> <test @myEven='getNum'></test> </template> <script> import test from '../../components/test.vue'; export default { methods: { // 接收num值 getNum(num) { console.log(num) } }, components: { test }, } </script>
兄弟组件通讯
通过
uni.$on()
和uni.$emit()
进行通信。
需求:a 组件修改 b 组件的数据
-
在父组件中注册两个兄弟组件。
<template> <view> <testa></testa> <testb></testb> </view> </template> <script> import testa from './a.vue' import testb from './b.vue' export default { components: { testa, testb } } </script>
-
在 b 组件中,通过
uni.$on('事件名', ()={})
注册一个全局的事件。<template> <view> 这是b组件的数据:{{num}} </view> </template> <script> export default { data() { return { num: 10 }; }, created() { uni.$on('updateNum', num=> { this.num+=1 }) } } </script>
-
在 a 组件中,通过
uni.$emit('事件名', 参数)
触发 b 组件中的全局事件,修改 b 组件的值。<template> <view> <button type="default" @click="addNum">修改b组件的数据</button> </view> </template> <script> export default { methods: { addNum() { uni.$emit('updateNum', 10) } } } </script>