Vue3兄弟组件传值实现过程
作者:前端青山
Vue3兄弟组件传值通过状态提升实现,父组件Root与子组件Left、Right使用props和自定义事件双向绑定颜色,利用updated生命周期同步状态,核心步骤为定义组件、注册组件及事件传递
Vue3中没有明确的兄弟组件传值
可以使用状态提升,找到这两个组件的共同父级组件,然后通过父与子之间的传值实现
那么首先咱们先定义一个父组件Root 和两个子组件我们取名叫Left和Right,要实现的效果是两个取色器可以双向绑定,一方改变颜色另一方与其同步一致
它是利用第三方进行 子传父, 父传子,依次进行绑定
定义组件模板
<div id="app"> <my-root></my-root> </div> <template id="root"> </template> <template id="left"> </template> <template id="right"> </div> </template>
开始组件通信的四步骤:
- 1.定义组件模块
- 2.定义组件
- 3.注册组件
- 4.使用组件
const Left = { template:'#left', data(){ return{ leftColor:'#0ff'//初始化数据颜色 } }, } const Right = { template:'#right', data(){ return{ rightColor:'#00f'//初始化数据颜色 } }, } const Root = { template:'#root', data(){ return{ color:'' } }, components:{ MyLeft: Left, MyRight:Right, } } Vue.createApp({ components:{ MyRoot:Root } }).mount('#app')
接下来给父组件中添加子组件内容及数据,创建自定义事件change-color="getColor"获取当前颜色,:color="color":绑定事件color就是父组件默认颜色
<template id="root"> <my-left @change-color="getColor" :color="color"></my-left> <!-- 添加自定义事件 --> <my-right :color="color" @change-color="getColor"></my-right> </template>
给子组件Left 和 Right 添加内容,那么我这边是写了两个取色器的小盒子,取色器 v-model 双向绑定颜色变量名
<template id="left"> <div :style="{width:'100px',height:'100px',float:'left','background-color':leftColor}"> <input type="color" v-model="leftColor"> </div> </template> <template id="right"> <div :style="{width:'100px',height:'100px',float:'left','background-color':rightColor}"> <input type="color" v-model="rightColor"> </div> </template>
那么先来注册父组件,并且使用一个方法把自定义事件的函数getColor 给一个形参 val 设置当前颜色 this.color 为形参val
const Root = { template:'#root', data(){ return{ color:'' } }, methods:{ getColor(val){//自定义事件函数 this.color = val //当前颜色 } }, components:{//子组件left和right MyLeft: Left, MyRight:Right, } } Vue.createApp({ components:{ MyRoot:Root } }).mount('#app')
注册使用子组件Left
那么我们先监听当前变量值, 给一个函数leftColor(newval)利用子传父 $emit('自定义事件名',参数)来进行监听
此时页面还是无法双向绑定,所以我们要在生命周期钩子函数updated更新后进行渲染页面的方法,当前变量就等于当前绑定的color颜色值
反之,当我们需要实现左右两个取色器盒子同步绑定渲染,子组件传给父组件后,left传给父,父传给right,right传给父,父传给left,这里我们用到了父传子props['自定义属性']
const Left = { template:'#left', data(){ return{ leftColor:'#0ff'//初始化数据 } }, props:['color'],//父传子 watch:{//监听 leftColor(newval){ this.$emit('change-color',newval) //this.$emit('自定义事件',参数) 子传父 } }, updated(){//更新后 this.leftColor = this.color //当前盒子颜色等于color } }
那么右边与左边一样的逻辑 ,right传父,父传left,left传父,父给right
const Right = { template:'#right', props:['color'], data(){ return{ rightColor:'#00f' } }, watch:{ rightColor(newval){ this.$emit('change-color',newval) } }, updated(){ this.rightColor = this.color } }
那么整体代码如下
<body> <div id="app"> <my-root></my-root> </div> </body> <template id="root"> <my-left @change-color="getColor" :color="color"></my-left> <!-- 添加自定义事件 --> <my-right :color="color" @change-color="getColor"></my-right> </template> <template id="left"> <div :style="{width:'100px',height:'100px',float:'left','background-color':leftColor}"> <input type="color" v-model="leftColor"> </div> </template> <template id="right"> <div :style="{width:'100px',height:'100px',float:'left','background-color':rightColor}"> <input type="color" v-model="rightColor"> </div> </template> <script src="../lib/vue.global.js"></script> <script> const Left = { template:'#left', data(){ return{ leftColor:'#0ff'//初始化数据 } }, props:['color'],//父传子 watch:{//监听 leftColor(newval){ this.$emit('change-color',newval) //this.$emit('自定义事件',参数) 子传父 } }, updated(){//更新后 this.leftColor = this.color //当前盒子颜色等于color } } const Right = { template:'#right', props:['color'], data(){ return{ rightColor:'#00f' } }, watch:{ rightColor(newval){ this.$emit('change-color',newval) } }, updated(){ this.rightColor = this.color } } const Root = { template:'#root', data(){ return{ color:'' } }, methods:{ getColor(val){//自定义事件函数 this.color = val } }, components:{ MyLeft: Left, MyRight:Right, } } Vue.createApp({ components:{ MyRoot:Root } }).mount('#app') </script>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。