VUE组件之间的通信

来源:互联网 发布:知远战略与防务网站 编辑:程序博客网 时间:2024/06/01 09:10

一、 组件component

1. 什么是组件?

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码组件是自定义元素(对象)

2. 定义组件的方式

方式1:先创建组件构造器,然后由组件构造器创建组件    var mycomponent=Vue.extend({        template:''    })    Vue.component('组件名',mycomponent)方式2:直接创建组件    Vue.component('组件名',{        template:''    })

3. 组件的分类

分类:全局组件、局部组件全局组件:    Vue.component('组件名',{        template:''    })局部组件:    在vue实例中写components:{        mycomponent: {            template:'',            data() { // data必须是函数,值需return返回,data属性默认为当前组件私有,其他组件不能调用                return {}            }        }    }

4. 引用模板

将组件内容放到模板<template>中并引用html:    <template id='template'>        <div></div>有且只有一个根元素    </template>vue:    Vue.component('组件名',{        template: '#template'    })

5. 动态组件

<component :is="">组件 多个组件使用同一个挂载点,然后动态的在它们之间切换

如:<div id="itany"><button @click="flag='my-hello'">显示hello组件</button><button @click="flag='my-world'">显示world组件</button><div><!-- 使用keep-alive组件缓存非活动组件,可以保留状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建 --><keep-alive><component :is="flag"></component></keep-alive></div></div><script>var vm=new Vue({el:'#itany',data:{flag:'my-hello'},components:{'my-hello':{template:'<h3>我是hello组件:{{x}}</h3>',data(){return {x:Math.random()}}},'my-world':{template:'<h3>我是world组件:{{y}}</h3>',data(){return {y:Math.random()}}}}});</script>

<keep-alive>    <component></component></keep-live>   使用keep-alive组件缓存非活动组件,可以保留状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建

二、 组件间数据传递

1. 父子组件

在一个组件内部定义另一个组件,称为父子组件子组件只能在父组件内部使用默认情况下,子组件无法访问父组件中的数据,每个组件实例的作用域是独立的父组件调用子组件需要在父组件的template中调用即:<template>    <h1>我是父组件</h1>    <my-word></my-word> // 此处调用子组件</template>

2. 组件间数据传递 (通信)

2.1 子组件访问父组件的数据

a)在调用子组件时,绑定想要获取的父组件中的数据b)在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据总结:父组件通过props向下传递数据给子组件注:组件中的数据共有三种形式:data、props、computed如:父组件:    html部分:<my-hello :msg='msg'></my-hello>    vue: data(){ return { msg: 'lll'}}子组件:    html部分: {{msg}}    vue: props:{ ['msg']} 接收父组件传递的值props注:    props的type是对象或者数组默认值必须使用函数的形式来返回    props:{        name: {            type: String, // 类型            default: '默认值',            required: true, // 是否是必须有的值            validator(){} // 判断值的函数        }    }

2.2 父组件访问子组件的数据

a)在子组件中使用vm.$emit(事件名,数据)触发一个自定义事件,事件名自定义b)父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法,用来获取数据总结:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件父组件:    html:        <h1>{{msg}}</h1>        <my-word @e-word="getData"></my-word>    vue:         methods:{            getData(msg){ this.msg=msg}        }子组件:    html:        <button @click="sendData">发送数据</button>    vue:        methods:{            sendData(){                this.$emit('e-word',this.msg)// 传递多个值以,隔开            }        }

3. 单向数据流

props是单向绑定的,当父组件的属性变化时,将传导给子组件,但是不会反过来而且不允许子组件直接修改父组件中的数据,报错解决方式:    方式1:如果子组件想把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据        如:            父组件:                html:                    <my-hello :age="age"></my-hello>            子组件:                html:<button @click='change'>改变值</button>                vue:                 new Vue({                     data:{                         uage:this.age                     },                     props:                            ['age'],                     methods:{                         change(){                            this.uage=18                         }                     }                 })    方式2:如果子组件想修改数据并且同步更新到父组件,两个方法:        a.使用.sync(1.0版本中支持,2.0版本中不支持,2.3版本又开始支持)            需要显式地触发一个更新事件            父组件:                html:                    <my-hello :name.sync="name" ></my-hello>            子组件:                html:                    <h1>{{name}}</h1>                    <button @click='change'></button>                vue:                    props:['name'],                    methods:{                        change(){                            this.$emit('update:name','alice')                        }                    }                    b.可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(因为对象是引用类型,指向同一个内存空间),推荐               父组件:                html:                    <my-word :user='user'></my-word>                vue:                    data(){                        return{                            user:{                                name: 'karry',                                age: 18                            }                        }                    }            子组件:                html:                    <h1>{{user.name}}</h1>                    <button @click="change"></button>                vue:                    props:['user']                    methods:{                        change(){                            this.user.name='roy'                        }                    }

4. 非父子组件间的通信

非父子组件间的通信,可以通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件var Event=new Vue();Event.$emit(事件名,数据);Event.$on(事件名,data => {});

<div id="itany"><my-a></my-a><my-b></my-b><my-c></my-c></div><template id="a"><div><h3>A组件:{{name}}</h3><button @click="send">将数据发送给C组件</button></div></template><template id="b"><div><h3>B组件:{{age}}</h3><button @click="send">将数组发送给C组件</button></div></template><template id="c"><div><h3>C组件:{{name}}{{age}}</h3></div></template><script>//定义一个空的Vue实例var Event=new Vue();var A={template:'#a',data(){return {name:'tom'}},methods:{send(){Event.$emit('data-a',this.name);}}}var B={template:'#b',data(){return {age:20}},methods:{send(){Event.$emit('data-b',this.age);}}}var C={template:'#c',data(){return {name:'',age:''}},mounted(){ //在模板编译完成后执行Event.$on('data-a',name => {this.name=name;// console.log(this);});Event.$on('data-b',age => {this.age=age;});}}var vm=new Vue({el:'#itany',components:{'my-a':A,'my-b':B,'my-c':C}});</script>

三、 slot内容分发

本意:位置、槽作用:用来获取组件中的原内容,类似angular中的transclude指令<style>.s2{width:100px;background:red;margin-left:10%;}</style><body><div id="itany"><my-hello><ul slot="s1"><li>aaa</li><li>bbb</li><li>ccc</li></ul><ol slot="s2"><li>111</li><li>222</li><li>333</li></ol></my-hello></div><template id="hello"><div><div  class="s2"><slot name="s2"></slot></div><h3>welcome to itany</h3><!-- <slot>如果没有原内容,则显示该内容</slot> --><slot name="s1"></slot></div></template><script>var vm=new Vue({el:'#itany',components:{'my-hello':{template:'#hello'}}});</script></body>
原创粉丝点击