目录
组件通信(超全)
props
适用场景:父子组件通信
注意事项:
1、如果父传子传递的是函数,本质是子组件给父组件传递数据
2、如果父组件给子组件传递的数据是非函数,本组件就是父组件给子组件传递数据
书写方式:['todos'],{type:Array},{type:Array,default:[]}
小提示:路由的props
书写方式:布尔值,对象,函数形式
自定义事件
适用场景:子组件给父组件传递数据
书写方式:$on , $emit
事件注意事项:
(1)事件分为系统事件和自定义事件
(2)事件源、事件类型、事件回调
(3)当给组件添加事件,由于该组件非原生DOM节点,所以此时绑定的事件都非原生DOM事件,而是自定义事件。当给组件添加click事件时,可以添加native属性,则可将自定义事件改为原生DOM事件,即给子组件的根组件绑定了原生DOM事件,利用了事件的委派。@click.native
(vue3此功能已经被移除)
全局事件总线
适用场景:万能
书写方式:$bus
原理:Vue.prototype.$bus = this
pubsub-js
适用场景:万能
注意:在React框架中使用比较多
书写方式:发布与订阅
Vuex
适用场景:万能
插槽
适用场景:父子组件通信
插槽类型:默认插槽、具名插槽、作用域插槽
注意:传递的是结构
作用域插槽:子组件的数据来源于父组件,子组件是决定不了自身结构与外观。
子组件:
<ul>
<!-- todos是父组件利用props传递给子组件的一个数组 -->
<li v-for="(item,index) in todos" :key="index">
<!-- 子组件将数据回传给父组件 -->
<slot :todo="item"></slot>
</li>
</ul>
父组件:
<List :todos="todos">
<!-- 子组件决定不了结构与外观,所以需要父组件传 -->
<template slot-scope="todo">
<span :style="color:todo.todo.isComlete?'green':'red'">{{todo.todo.text}}</span>
</template>
</List>
todo.todo.text中第一个todo是子组件传递过去的名字也是一个对象,效果:
{todo:{id:1,text:'aaa',isComlete:true}}
,第二个是传递过去的item,text是item的一个属性。父组件接收是也可以解构赋值即slot-scope="{text,index}"
,就不用多次写todo.todo了。注意:解构时K V一致
插槽是父子组件之间结构的传递。
v-model
它是v-model是Vue框架中指令,它主要是结合表单元素一起使用(文本框、复选框、单选等等),主要的作用是收集表单数据。
原生DOM当中是有input事件,它经常结合表单元素一起使用,当表单元素文本内容发生变化时就会触发一次回调。所以可以通过value与input事件实现v-model功能。
<input type='text' :value='msg' @input='msg = $event.target.value'/>
深入学习v-model实现父子组件数据同步(实现父子通信):
父组件:
<ZiZujian :value='msg' @input='msg=$event'/>
也可简化为:
<ZiZujian v-model='msg'/>
:value是父组件给子组件传递的props
@input是自定义事件
子组件:
<input type='text' :value='value' @input="$emit('input',$event.target.value)">
...
props:['value']
:value是动态属性
@input是原生DOM事件
v-model实现原理:
value与input事件实现的,而且还需要注意可以通过v-model实现父子组件数据同步。
属性修饰符sync
不使用sync属性修饰符
父组件:
<ZiZUjian :money='money' @update:money='money = $event'/>
:money父组件给子组件传递的props
@update:money给子组件绑定的自定义事件,只不过名字叫做update:money
子组件:
<button @click='$emit('update:money',money-100)'>花钱</button>
…
props['money']
该方式与v-model很相似,可以实现父子组件数据同步
使用sync属性修饰符
父组件改成如下,子组件不变
<ZiZUjian :money.sync='money'/>
:money.sync
1、父组件给字符串传递props【money】
2、给当前子组件绑定了一个自定义事件,而且事件名称即为update:money
$attrs 与 $listeners
$attrs属于组件自身的属性,可以获取到父组件传递过来的props数据。
要实现的功能:当使用封装的按钮时向子组件传递相应参数(即对按钮进行二次封装)
注:子组件可以利用props接收父组件传递的数据,但此时接收到的属性,在 $attrs属性当中无法获取到。此时可以巧妙地利用a标签实现按钮带有提示功能。
<a :title=
'title'>
<el-button v-bind='$attrs'></el-button>
</a>
v-bind='$attrs’将 $attrs接受到的所有属性都绑定到元素上,此时不能用:简写
<ZiZujian type='success' icon='el-icon-delete' size='mini' title='提示按钮' @click='handler'></ZiZujian>
@click代表的是自定义事件
$listeners它也是组件实例自身的属性,可以获取到父组件给子组件传递的自定义事件,所以此时可以用以下方式触发自定义事件,v-on不能用@替换
<a :title='title'>
<el-button v-bind='$attrs' v-on='$listeners'></el-button>
</a>
$attrs 与 $listeners是组件实例的属性,可以获取到父组件给子组件传递的props与自定义事件。
$children 与 $parent
ref可以获取到真实的DOM节点,也可以获取到子组件标签(操作子组件的数据与方法)
$children为组件实例自身拥有一个属性,可以获取到当前组件当中全部的子组件。此时可以利用forEach遍历所有子组件,并让其分别做出同样的操作。
this.$children.forEach(item=>{
this.money -= 200
})
$children
获取到的是一个数组,但是不能使用$children[0]
这种写法获取某一子组件,因为当子组件过多时,索引值为0的那一项不一定就是我们所期待的那一项。
$parent可以在子组件获取到父组件,可以操作父组件的数据与方法
this.$parent.money += moeny
混入mixin
mixin可以把多个组件JS部分重复、相似地方封装成一个混入。
新建一个js文件,对外暴露一个对象,可以放置组件重复的JS业务逻辑。
export default {
methods:{
giveMoney(money){
this.money -= money
this.$parent.money += money
}
}
}
在需要使用该部分代码地方引入:
import myMixin from '@/pages/myMixin/myMixin.js'
使用:mixins:[myMixin]