vue组件通信的几种方式

2020-12-29  本文已影响0人  仔崽06

1.props/@on+$emit

用于实现父子组件通信.

//父组件.vue
<children :title="title"></children>

//子组件.js
export default {
  props:{
     title:{
        type:String,
        default:''
     }
  },
  data(){
     return {
     }
  }
}
//父组件.vue 接收子组件改变的值
<children @handleTitile="handleTitle"></children>

//子组件传给父组件值
export default {
  props:{
     title:{
        type:String,
        default:''
     }
  },
  data(){
     return {
     }
  },
 methods:{
   this.$emit('handleTitle','我是子组件传来的标题')
 }
}

2.$attrs、 $listenners(vue2.4以上版本新增)

可以实现跨级组件的通信

$attrs (跨级属性传递)
//父组件.vue
<template>
   <children class="child-tpl" title="标题" desc="描述" :data="data"></children>
</template>
<script>
import children from './children.vue'
export default {
    components:{
        children
    },
    data(){
        return{
            data:[1,2,3,4,5]
        }
    }
}
</script>

//子组件.vue v-bind父组件传来的$attrs可以省去prop继续往下传递父组件传来的值.
<template>
    <div>
        子组件
        <grandson v-bind="$attrs"></grandson>
    </div>
</template>
<script>
import grandson from './grandson.vue'
export default {
    components:{
        grandson
    },
    inheritAttrs:false, //dom节点是否显示父组件传来的属性
    data(){
        return{
            
        }
    },
    mounted(){
        console.log(this.$attrs) //子组件 {title: "标题", desc: "描述", data: Array(5)}
    }
}
</script>
//孙子组件.vue
<template>
    <div>孙子组件</div>
</template>
<script>
export default {
    inheritAttrs:false,
    data(){
        return{
            
        }
    },
    mounted(){
        console.log(this.$attrs) //孙子组件 {title: "标题", desc: "描述", data: Array(5)}
    }
}
</script>
$listeners(跨级事件传递)
//父组件.vue
<template>
    <children @changeTitle="changeTitle" @update.native="update"></children>
</template>
<script>
import children from './children.vue'
export default {
    components:{
        children
    },
    data(){
        return{
            data:[1,2,3,4,5]
        }
    },
    methods:{
        changeTitle(){
            console.log('changeTitle')
        },
        update(){
            console.log('update') 
        }
    }
}
</script>
//子组件.vue 需要用v-on向下传递
<template>
    <div>
        子组件
        <grandson v-on="$listeners"></grandson>
    </div>
</template>
<script>
import grandson from './grandson.vue'
export default {
    components:{
        grandson
    },
    inheritAttrs:false, //dom节点是否显示父组件传来的属性
    data(){
        return{
            
        }
    },
    mounted(){
        console.log(this.$listeners) //子组件{changeTitle: ƒ}
    }
}
</script>
//孙子组件.vue
<template>
    <div>
        孙子组件
        <el-button @click="changeTitle">点击</el-button>
    </div>
</template>
<script>
export default {
    data(){
        return{
            
        }
    },
    methods:{
        changeTitle(){
            this.$listeners.changeTitle()
        }
    },
    mounted(){
        console.log(this.$listeners) //孙组件{changeTitle: ƒ}
    }
}
</script>

3.provide/inject

以允许一个祖先组件向其所有的子孙后代注入一个依赖,可以注入属性和方法.实现跨级父子组件通信.绑定原始值并不是响应式的,所以孙子组件改变值,父组件是不会重新渲染的.

//父组件.vue
<template>
    <div>
        {{title}}
       <children @changeTitle="changeTitle" @update.native="update"></children>
    </div>
</template>
<script>
import children from './children.vue'
export default {
    components:{
        children
    },
    data(){
        return{
            title:'标题'
        }
    },
    provide(){
        return{
            detail:{
                title:this.title,
                change:(val)=>{
                   return console.log(val)  //我改变了
                }
            }
        }
    }
}
</script>
//孙子组件

<template>
    <div>
        孙子组件
        <el-button @click="changeTitle">点击</el-button>
    </div>
</template>
<script>
export default {
    data(){
        return{
            
        }
    },
    inject:['detail'],
    methods:{
        changeTitle(){
            this.$listeners.changeTitle()
        }
    },
    mounted(){
        console.log(this.detail) //{title: "标题", change: ƒ}
        this.detail.title='我修改了标题' //父组件并不会从新渲染
        this.detail.change('我改变了')
    }
}
</script>

4.EventBus

//eventBus.js
import Vue from 'vue';
export const EventBus=new Vue()
//main.js
import {EventBus} from './eventBus.js'
Vue.prototype.$eventBus=EventBus
//父组件.vue
 this.$eventBus.$on('update',val=>{
     console.log(val)  //123
 })
//孙子组件.vue
methods:{
    changeTitle(){
       this.$eventBus.$emit('update',this.data)
    }
},
//移除监听事件
 this.$eventBus.$off('update',null)

5.Vuex状态管理(具体看官网)

6.Vue.observable实现mixin vuex(vue2.6新增)

将一个对象可以响应

//store.js
import Vue from 'vue';
export const state=Vue.observable({
    count:0
})

export const mutations={
    increment() {
        state.count++
    },
    decrement() {
        state.count--
    }
}
<template>
    <div>
        {{count}}
    </div>
</template>
<script>
import {state} from '@/observer/store.js'
export default {
    data(){
        return{
        }
    },
    computed:{
         count(){return state.count}
    }
}
</script>
<template>
    <div>
         <el-button @click="increment">点击</el-button>
    </div>
</template>
<script>
import {mutations} from '@/observer/store.js'
export default {
    data(){
        return{

        }
    },
    methods:{
        increment(){
            mutations.increment()
        }
    }
}
</script>

7.refs/children/parent/root

给子组件定义refs,父组件可以直接使用$refs操作子组件的方法和属性

//子组件
<children ref="list"></children>
//父组件
this.$refs['list'].getList()

8.v-model

//父组件.vue
<template>
    <div>
       <children v-model="title" @changeTitle="changeTitle" @update.native="update"></children>
    </div>
</template>
//子组件.vue
<template>
    <div>
        子组件{{value}}
        <el-button @click="changeTitle">修改</el-button>
    </div>
</template>
<script>
export default {
    props:{
        value:{
            type:String,
            default:''
        }
    },
    data(){
        return{} 
    },
    methods:{
        changeTitle(){
            this.$emit('input','1233')
        }
    }
}

9.sync修饰符

//父组件.vue
<template>
    <div>
       <children :title.sync="title" @changeTitle="changeTitle" @update.native="update"></children>
    </div>
</template>
//子组件.vue
<template>
    <div>
        子组件{{title}}
        <el-button @click="changeTitle">修改</el-button>
    </div>
</template>
<script>
export default {
    props:{
        title:{
            type:String,
            default:''
        }
    },
    data(){
        return{} 
    },
    methods:{
        changeTitle(){
            this.$emit('update:title','1233')
        }
    }
}

上一篇 下一篇

猜你喜欢

热点阅读