vue-组件和组件的通信
组件
组件封装了一个html css js 等功能
组件分为全局的组件和局部的组件
局部组件:当你加载使用局部组件的页面时,才会被加载
全局组件:无论你使用不适用都会被加载
组件树:
就如树形结构一样,在一个父级组件中承载着多个其他的不同 的子组件,这些子组件中又承载着其他的组件。
局部组件
据组件:键子,挂子,用子 3步进行创建。
1.创建一个子组件
2.挂载到父组件中,父组件中就存在子组件的样式
当进行挂载时,将挂载的组件名字vue对象值放到 components 对象中进行挂载
注意:
1.创建组件是,不能使用大写的名字进行命名
2.允许驼峰体进行编写组件进行命名,如果使用模板语法的情况下不需要在乎
3.局部组件的data函数必须要写,就算没有值,也要写,不写就会报错
代码:
< div id="app"> < A_pp > //1创建一个子组件 //为什么子组件中,data是一个函数,而不是对象:原因好维护,创建子组件是需要进行创一个data函数 let A_pp = { // 每个组件维护他的自己一块实例,以免数据的冲突 data(){ return { msg:"我是app组件" } }, // 给按钮创建一个事件,点击后重新给msg进行赋值 template: ` < div > < h3 > {{msg}} < button @click='show'>按钮 `, methods:{ // 声明事件 show(){ this.msg = '学习组件' } } } //创建一个vue对象 new Vue({ el: "#app", data: { //对应数据 }, //2.将组件挂载到vue中 components不能写错 components: { // 对象,可以挂载多个组件 // 挂载组件 相当于APP:APP A_pp } })
全局组件
创建 挂载 使用 也是3步
使用全局组件需要使用vue的实例化对象进行创建
注意:
1.全局组件创建使用的方法component
2.全局组件可以不需要写data函数,局部组件必须写,要不然就会无法加载
全局组件使用的关键子component(第一个参数:全局组件的名字,第二个参数{模板语法,data函数,或者其他的。})
3.全局组件不用在其他组件中进行挂在,直接使用组件名称在template进行使用就行
如何创建一个组件:
< script src="../vue.js"> Vue.component('App',{ template: ` < div > 我是全局组件 `, }) // 是引用vue对象+component参数进行创建 // 参数1:组件名称 // 参数2:主要的函数,参数,等等
使用局部组件和全局组件配合使用
< div id="app"> < Vont > < script src="../vue.js"> //创建 一个全局组件 Vue.component('App',{ template: ` < div > 我是全局组件 `, }) //创建一个局部组件 let Vont = { data(){ return{ } }, // 使用全局组件 template: ` < div > < App > 我是局部组件 `, , } //创建vue对象,将局部组件进行挂靠 new Vue({ el: "#app", data: { }, components: { Vont } })
vue对象中挂载了局部组件,而局部组件中又使用了全局组件,这样的话,页面就会显示这两个局部的全局的内容。
组件通信:父级组件向子组件传值
1.在子组件需要进行声明一个ptops属性,接受挂载的父传入的值
2.在绑定完毕后,可以在就可以在tmeplate中进行使用
3.在父类中绑定子类中设置的props属性值给当前的父类的参数,进行使用
< div id="app"> < A_pp > //创建一个全局组件,利用props进行接受父组件中的传入的值 Vue.component('Child',{ template:` < div > < h3 >我是app的子组件 < h3 >{{chilDate}} `, //4.接受父类的值 定义参数props值,对象可以接受任意参数数组对象字符串 props:['chilDate'], // 设置接受的值,如果值存在进行接受,在子组件中进行使用 }) // 创建一个局部中的组件,将全局组件进行使用,并且将当前组件中的msg传入 let A_pp = { data(){ return { msg:'我要我的值传给父级组件' } }, //将子组件中将设定的参数进行绑定,绑定props中的变量绑定到子组件中,将这个值进行赋值父类的参数 template: ` < div > < child v-bind:chilDate='msg'> `, } // 创建vue 对象,将局部组件A_pp进行挂载 new Vue({ el: "#app", data: { }, components: { A_pp } })
组件通信:子组件对父组件进行传值
1.在父组件中绑定一个自定义事件(给子组件进行绑定)
2.在子组件中,触发原生的(js自带的事件)在事件函数中通过this.$emit()进行触发自定义事件
开发一个事件,触发事件进行获取子级的属性
子组件传入值,父组件接受值
< div id="app"> < A_pp > // 创建一个全局的组件 Vue.component('Child',{ template:` < div > < input type='text' @input='handleiput'/> `, methods:{ // 1.给子组件中的input框绑定事件,将输入input框中的值传给父组件显示 handleiput(e){ const val = e.target.value // 3.实时坚定input框中的最新的值 //console.log(e.target.value); // 可以触发子传父中的定义的自定义方法 // 参数1:被触发的函数名 参数2 将子级的某个参数 this.$emit('inputHandeler',val) } }, }) //创建一个局部组件 let A_pp = { data(){ return { newVal:'' } }, // 2.子类中的值传给父类进行使用 // 4.在child子级中的标签中设置一个自定义的事件 // 5. 这个input方法函数,就会接受到子级中传来的值 methods:{ input(newVal){ // newVal 就是子级通过$emit方法触发挂靠在父级中的子组件标签中的自定义inputHandeler事件,后触发当前input函数方法,接受的值 // 接受子级的值,进行赋值 this.newVal = newVal } }, template: ` < div > < div > 显示的数据子传入父级的数据显示位置:{{newVal}} < child @inputHandeler='input'> // 创建vue对象 new Vue({ el: "#app", data: { }, components: { A_pp } })
解释:
1.当进行父级传入值时需要使用this.$emit(参数1:自定义事件名,参数2:值)将函数进行抛出
2.全局组件child(子组件) 的input的标签绑定了一个input方法(聚点事件),当,就会执行对应的函数,将input中的值获取到(val变量),在将抛出inputHandeler的名自定义的方法,并且将val变量进行携带
3.在局部组件(父组件)A_pp中使用全局组件中时,绑定子传入的自定方法,设置一个函数(input)进行触发和接受子级传入值
组件通信:平行通信
在一个平行的组件中(兄弟组件中怎么实现进行通信)
1.需要设置一个公共的对象
2.使用 公共对象.$emit() 触发一个自定义事件 在通过 公共对象this.$on()接受这个事件,并且触发事件
这个公共对像公交车一样,被称为:中央事件总线
方法: $emit(自定义事件名,参数) $on(接受的自定义事件名,(接受参数)=>{} 回调函数)
< div id="app"> < App > // 创建一个公共对象 bus const bus = new Vue() //由这个对象进行兄弟组件之间的传值 // 创建两个兄弟组件 Vue.component('B',{ data(){ return{ conut:1 //记录数据,当点击a组件的按钮时b组件进行更新 } }, template:` < div > < spen >b组件的数量: < div >{{conut}} `, //使用vue生命周期中的方法:created 在初始化组件时,这个方法就会被调用 created(){ // b组件绑定 a组件触发 无法实现效果 // $on 绑定事件 参数1:函数名 参数2回调函数,n执行时emit是传入参数的值 // $emit 触发事件 bus.$on('add',(n)=>{ // this执行b对象 this.conut+=n }) } }) created,组件熏染完成执行的一个内部方法 Vue.component('A',{ data(){ return{ //记录数据,当点击a组件的按钮时b组件进行更新 } }, // 当点击按钮时,就会触发方法,对b组件的值进行更新 template:` < div > a组件的按钮: < button @click='handleclick'>加入购物车 `, // 触发事件的函数 methods:{ handleclick(){ // 触发事件 bus.$emit('add',1) // this指向了a } } }) /创建一个局部组件,将ab两个组件进行使用 const App = { data() { return { } }, // 一个a组件 // 一个b组件 template: ` < div > < A > < B > ` } //创建一个vue对象 new Vue({ el: "#app", data: { }, components:{ App } })
当点击a组件中的button按钮就会触发对一个的事件,就会触发$emit方法触发
b组件就是用声明请求周期的created方法 将emit自定义事件进行触发 on
组件通信:其他方法
使用 provide 和 inject
provide 提供变量
inject 注入变量
这个方式:父级组件使用provide提供变量 无论子组件嵌套了多少层 都可以使用 inject注入变量
< div id="app"> < App > //创建3个组件 Vue.component('B',{ // b组件的爹是a组件 b组件想使用app组件的参数 data(){ return{ } }, // 使用inject注入 inject:['msg'], // 可以是数据,也可以是别的 通过this created(){ console.log(this.msg); //如果是别的方法 this.msg }, // 使用模板和插入值 直接msg template:` < div > < div >{{msg}} ` }) Vue.component('A',{ // a 组件的爹是app组件 data(){ return{ } }, template:` < div > < B > `, created(){ // this 是 当前的a组件 console.log(this.$parent.title) // this.$parent 获取当前组件的父组件 console.log(this.$children) } }) const App = { data() { return { title:"老爹" } }, // 在app组件中使用provede(可以是个函数返回一个对象) provide(){ return{ // 返回一个对象 msg:'老爹的数据app组件的' } }, template: ` < div > < A > ` } // 创建vue对象 new Vue({ el: "#app", data: { }, components:{ App } })
只要父级组件使provide 提供了变量 他的子组件 或者子孙组件都可以使用inject进行获取