七、UniAPP 自定义组件与通信
(1)自定义组件概念
组件是
vue
技术中非常重要的部分,组件使得与ui相关的轮子可以方便的制造和共享,进而使得vue使用者的开发效率大幅提升,在项目的component
目录下存放组件,uni-app
只支持vue
单文件组件(.vue 组件)组件可以使用「全局注册」和「页面引入」两种方式进行使用,使用分为三步:
导入
import xxx from 'xxx'
注册
Vue.use('xx',xx)
components:{ xxx }
使用
<xx />
新建子组件
<template>
<view>
<text class="red">子组件</text>
<view>{{msg}}</view>
<view>
<button @click="sayHelloToFather">按钮</button>
</view>
</view>
</template>
<script>
export default {
props:['msg'],
data() {
return {
};
},
methods:{
sayHelloToFather(){
this.$emit('childEvent','子组件传递给父页面的信息')
//uni.$emit('getInfo', '樱桃小丸子')
}
}
}
</script>
<style scoped>
.red{
color: red;
}
</style>
父页面引入子组件
<template>
<view class="content">
<text>父页面</text>
、
<child :msg="title" @childEvent="sayHello"></child>
</view>
</template>
<script>
import Child from '@/components/child.vue'
export default {
data() {
return {
title: '我是父组件定义的数据信息'
}
},
components:{
Child
},
onShow(){
console.log('Index page show')
},
onLoad() {
console.log(getCurrentPages())
},
onPullDownRefresh(){
console.log('页面下拉刷新了')
},
methods: {
sayHello(msg){
this.title = msg
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
(2)父子组件通信
- 父组件通过自定义属性向子组件传递数据
- 子组件通过
props
接收父组件传递的数据- 父组件通过自定义事件标签向子组件传递事件
- 子组件通过触发父组件定义事件方式修改父组件数据
<child :msg="title" @childEvent="sayHello"></child>
(3)slot 数据分发与作用域插槽
- 父组件通过调用子组件内部嵌套 html 内容作为
slot
分发给子组件- 子组件通过在
slot
标签上添加属性,向父组件通信数据,作用域插槽
vue 实现了一套内容分发的 API,将 slot
元素作为承载分发内容的出口。
它允许你像这样合成组件:
<template>
<view>
<componentA>
Your Profile
</componentA>
</view>
</template>
在 <componentA>
的模板中可能会写为:
<template>
<view>
<!-- 我是子组件componentA -->
<view >{{title}}</view>
<slot></slot>
</view>
</template>
当组件渲染的时候,<slot></slot>
将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 HTML
:
<template>
<view>
<!-- 我是父组件 -->
<componentA>
<view>Your Profile</view>
<!-- 添加一个 uni-icons 图标 -->
<uni-icons type="contact" size="30"></uni-icons>
</componentA>
</view>
</template>
如果 <componentA>
的 template
中没有包含一个 <slot>
元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
(4)全局事件定义及通信
- 在整个应用的任何地方均可以使用
uni.$on
创建一个全局事件- 在整个应用的任何地方也均可以使用
uni.$emit
来触发全局事件,实现多组件见的数据通信
创建全局事件
<template>
<view>
<text>我</text>
<text>{{name}}</text>
</view>
</template>
<script>
export default {
data() {
return {
name: 'aaaa'
}
},
onLoad(){
uni.$on('getInfo', name =>{
uni.showToast({
icon:'none',
title: '全局事件被触发了',
duration: 2000
});
//console.log('Me 页面中的全局事件被触发了')
this.name = name
})
},
methods: {
}
}
</script>
<style>
</style>
触发事件
<script>
export default {
data() {
return {
};
},
methods:{
sayHelloToFather(){
uni.$emit('getInfo', '张三')
}
}
}
</script>