我是靠谱客的博主 冷静朋友,最近开发中收集的这篇文章主要介绍Vue组件通信,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

自定义事件(子组件的数据传给父组件)

如果要传递的话要用到this.emit(‘自定义事件名称’,‘要传的数据’)

<div id="app">
        <parentcom></parentcom>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('parentcom',{
            template : `
                <div>
                    <div>父组件</div>
                    <childcom @transmission="transmissionHandle"></childcom>
                    <p>我是来自子组件的:{{myname}}</p>    
                </div>
            `,
            data(){//在组件里data是一个函数,所以必须return
                return{
                    myname : ''
                }
            },
            methods:{
                transmissionHandle(name){//如果子组件传的有第二个参数,括号里就得有东西去接
                    console.log('我进来啦!!');
                    console.log('我是来自子组件的:',name);
                    this.myname = name;
                }
            }
        })
        Vue.component('childcom',{
            template : `
                <div>
                    <p>子组件</p>
                    <button @click="clickHandle">点我</button>    
                </div>
            `,
            data(){
                return{
                    name : 'hsy'
                }
            },
            methods:{
                clickHandle(){
                    this.$emit('transmission',this.name)//第一个是自定义事件的名称,第二个是要传的数据
                }
            }
        })
        const app = new Vue({
            el:'#app'
        })
    </script>

如果子传父的话用v-model的的示例:

<div id="app">
        <parentcom></parentcom>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('parentcom',{
            template : `
                <div>
                    <div>父组件</div>
                    <childcom @transmission="transmissionHandle"></childcom>
                    <p>我是来自子组件的:{{myname}}</p>    
                </div>
            `,
            data(){//在组件里data是一个函数,所以必须return
                return{
                    myname : ''
                }
            },
            methods:{
                transmissionHandle(name){//如果子组件传的有第二个参数,括号里就得有东西去接
                    console.log('我进来啦!!');
                    console.log('我是来自子组件的:',name);
                    this.myname = name;
                }
            }
        })
        Vue.component('childcom',{
            template : `
                <div>
                    <p>子组件</p>
                    <button @click="clickHandle">点我</button>    
                </div>
            `,
            data(){
                return{
                    name : 'hsy'
                }
            },
            methods:{
                clickHandle(){
                    this.$emit('transmission',this.name)//第一个是传给父组件的事件函数的名字,第二个是参数
                }
            }
        })
        const app = new Vue({
            el:'#app'
        })
    </script>

修饰符sync子传父示例

<div id="app">
        <parentcom></parentcom>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        // <comp :foo.sync="bar"></comp>
        // <comp :foo="bar" @update:foo="val" => bar = val></comp>
        Vue.component('parentcom',{
            template : `
                <div>
                    <div>父组件</div>
                    <p>{{counter}}</p>
                    <childcom :foo.sync="counter"></childcom>
                </div>
            `,
            data(){
                return{
                    myname : '',
                    counter: 1
                }
            }
        })
        Vue.component('childcom',{
            template : `
                <div>
                    <p>子组件</p>
                    <button @click="clickHandle">点我</button>    
                </div>
            `,
            data(){
                return{
                    counter2:1
                }
            },
            methods:{
                clickHandle(){
                    this.counter2++;
                    this.$emit('update:foo',this.counter2)
                }
            }
        })
        const app = new Vue({
            el:'#app'
        })
    </script>

非父子组件通信(兄弟组件)

兄弟组件通信需要一个中间商赚差价,中间商的data,methods等都是公用的,兄弟之间都可以用,比如说在中间商的data里面有一个name,那么用’中间商的名字’.name就能得到
用代码做示例就是

<div id="app">
        <com1></com1>
        <com2></com2>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const bus = new Vue();//中间商
        Vue.component('com1',{
            template : `
                <div>
                    <div>组件1</div>
                    <p>当前数据为{{name}}</p>
                </div>
            `,
            data(){
                return{
                    name : 'gws'
                }
            },
            mounted(){//挂载之后监听数据
                bus.$on('comtwo',(str)=>{//括号里接受监听到的数据
                    console.log('这是我监听到的数据',str);
                    this.name = str;
                })
            }
        })
        Vue.component('com2',{
            template : `
                <div>
                    <div>组件2</div>
                    <button @click="clickHandle">组件2的按钮</button>
                </div>
            `,
            data(){
                return{
                    name:'hsy'
                }
            },
            methods:{
                clickHandle(){
                    bus.$emit('comtwo',this.name)
                }
            }
        })
        const app = new Vue({
            el: '#app'
        })
    </script>

然后说一嘴,父链子链还没有总结,但是因为并不推荐使用,因为它们是类似DOM节点的操作,所以现在了解原理就行

插槽

英文名叫做slot,它的入门用法

<div id="app">
        <com1>this a 插槽</com1>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const bus = new Vue();//中间商
        Vue.component('com1',{
            template : `
                <div>
                    <div>组件1</div>
                    <slot>暂无内容</slot><!--插槽-->
                </div>
            `
        })
        const app = new Vue({
            el: '#app'
        })
    </script>

具名插槽
本来都是单个插槽的,在slot便签里面用name取一个名字就可以有多个插槽,向具名插槽提供内容的时候要用template里面使用v-slot指令,并且以v-slot的参数形式提供其名称,也可以用"#"替换,比如说v-slot:header可以简写成#header

<div id="app">
        <com1>
            <template v-slot:header>
                <div>头部</div>
            </template>
            <template v-slot:footer>
                <div>尾部</div>
            </template>
        </com1>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('com1',{
            template : `
                <div>
                    <slot name='header'>头部默认</slot>
                    <div>组件1</div>
                    <slot name='footer'>尾部默认</slot>
                </div>
            `
        })
        const app = new Vue({
            el: '#app'
        })
    </script>

访问插槽

访问slot的方法: s l o t s ∗ 效 果 : 通 过 ∗ slots* 效果:通过* slotsslots可以访问某个具名的slot

动态组件

is特性的写法

<div id="app">
        <button @click="clickHandle">切换</button>
        <component :is="com"></component>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('com1',{
            template : `
                <div>组件1</div>
            `
        })
        Vue.component('com2',{
            template : `
                <div>组件2</div>
            `
        })
        const app = new Vue({
            el: '#app',
            data : {
                com : 'com1'
            },
            methods:{
                clickHandle(){
                    this.com == 'com1' ? this.com = 'com2' : this.com = 'com1';
                }
            }
        })
    </script>

可以用keep-alive把动态组件包起来,keep-alive会保持动态组件之前的状态

<div id="app">
        <button @click="clickHandle">切换</button>
        <keep-alive>
            <component :is="com"></component>
        </keep-alive>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('com1', {
            template: `
                <div @click='itemClick'>
                    <div class='item'>HTML</div>
                    <p v-if='isShow[0]'>HTML 是一门文本标记语言。</p>
                    <div class='item'>CSS</div>
                    <p v-if='isShow[1]'>CSS 负责网页的样式。</p>
                    <div class='item'>JavaScript</div>
                    <p v-if='isShow[2]'>JavaScript 可以为网页添加动态的效果。</p>
                </div>
            `,
            data(){
                //控制文字是否显示
                return {
                    isShow: [false, false, false]
                }
            },
            methods: {
                itemClick: function () {
                    switch (event.target.innerHTML) {
                        case 'HTML': {
                            Vue.set(this.isShow, 0, !this.isShow[0]);
                            break;
                        }
                        case 'CSS': {
                            Vue.set(this.isShow, 1, !this.isShow[1]);
                            break;
                        }
                        case 'JavaScript': {
                            Vue.set(this.isShow, 2, !this.isShow[2]);
                            break;
                        }
                    }
                }
            }
        })

        //组件2
        Vue.component('com2', {
            template: `
                <div>{{content}}</div>
            `,
            data(){
                return {
                    content : '组件2'
                }
            }
        })
        const app = new Vue({
            el: '#app',
            data: {
                com: 'com1'
            },
            methods: {
                clickHandle() {
                    this.com == 'com1' ? this.com = 'com2' : this.com = 'com1';
                }
            }
        })
    </script>

混入技术

类似于封装函数,减少代码的复用,非常灵活

<div id="app">
        <com1></com1>
        <com2></com2>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const myMix = {
            mounted(){
                console.log('组件加载完毕');
            }
        }
        Vue.component('com1', {
            mixins:[myMix],
            template: `
                <div>组件1</div>
            `,
        })

        //组件2
        Vue.component('com2', {
            mixins:[myMix],
            template: `
                <div>组件2</div>
            `,
        })
        const app = new Vue({
            el: '#app',
            
        })
    </script>

选项合并

组件数据和混入数据冲突时,组件数据优先

混入对象的钩子函数将在组件自身钩子函数之前调用

最后

以上就是冷静朋友为你收集整理的Vue组件通信的全部内容,希望文章能够帮你解决Vue组件通信所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部