目录
一、.sync修饰符
作用
之前组件进行双向绑定时,需要通过proos进行父传子,再通过$emit实现子传父,这种方法很繁琐
为了方便起见,Vue为这种模式提供了一种缩写,即 .sync 修饰符
使用场景
双向数据绑定
使用方法
<Son :val.sync="name"></Son>
案例
需求:父子组件数据双向绑定
使用props + $emit
与使用.sync修饰符
代码对比
App.vue
<template>
<div>
<Father />
</div>
</template>
<script>
import Father from "./components/Father.vue";
export default {
name:'App',
components:{Father},
}
</script>
Father.vue
// 父组件:使用props + $emit
<template>
<div class="parent">
<h3>父组件接收子组件的值为:{{name}}</h3>
<Son :val="name" @update="newName" />
</div>
</template>
<script>
import Son from './Son'
export default {
components:{Son},
data () {
return {
name:'憨瓜'
}
},
methods:{
newName(val){
this.name = val
}
}
}
</script>
// 父组件:使用.sync修饰符
<template>
<div>
<h3>父组件接收子组件的值为:{{name}}</h3>
<Son :val.sync="name"></Son>
</div>
</template>
<script>
import Son from './Son'
export default {
components:{Son},
data () {
return {
name:'憨瓜'
}
}
}
</script>
Son.vue
// 子组件:使用props + $emit
<template>
<label class="child">
输入框:
<input :value=val @input="nameIpt($event)"/>
</label>
</template>
<script>
export default {
name:'Son',
props:['val'],
methods:{
nameIpt(event){
this.$emit("update",event.target.value)
}
}
}
</script>
// 子组件:使用.sync修饰符
<template>
<label >
输入框: <input :value="val" @input="nameIpt"/>
</label>
</template>
<script>
export default {
name:"Son",
props:['val'],
methods:{
nameIpt(event){
this.$emit("update:val",event.target.value)
}
}
}
</script>
运行结果
.sync修饰符的优势
1、写法上更简化,代码量更少;
2、父组件不用再定义方法检测值变化,.sync相当于在父组件定义了一个来监听子组件修改值的事件。
二、$attrs
作用
之前父组件传递数据,子组件通过props接收,如果传递多个,也需要一个个接收,写法比较丑陋
为了方便起见,Vue为提供了一种新的属性,即 $attrs
使用场景
$attrs
获取父传子中未在props 配置项
定义的值
多使用于传递原生属性
使用方法
v-bind = "$attrs"
案例
需求:父组件向子组件传递多个属性
Father.vue
<template>
<div>
<h3>通过$attrs传递原生属性</h3>
<Son title="加油,离奇6厘米" placeholder="请输入文字" type="text"/>
</div>
</template>
<script>
import Son from "./Son";
export default {
name: 'Father',
components:{Son},
}
</script>
Son.vue
<template>
<div>
<label>输入框:<input v-bind="$attrs" /></label>
<h4>父传过来的title值为:{{$attrs.title}}</h4>
</div>
</template>
<script>
export default {
name:'Son',
mounted(){
console.log(this.$attrs);
}
}
</script>
运行结果
$attrs注意点
1、无论什么情况下,$attrs
都不会绑定原生的class和style属性
2、如果子组件中有props配置项,那么$attrs
只接收props绑定之外的属性
3、当一个组件没有声明任何 props 时,$attrs
会包含所有父作用域的绑定
代码验证
Son.vue通过props配置项接收父组件所有属性
<template>
<div>
<label>输入框:<input v-bind="$attrs" /></label>
<h4>父传过来的title值为:{{$attrs.title}}</h4>
</div>
</template>
<script>
export default {
name:'Son',
props:["value","title","placeholder","type"],
mounted(){
console.log(this.$attrs);
}
}
</script>
运行结果:$attrs为一个空对象
三、$listeners
作用
与$attrs
属性一样,$listeners
也是为了在自定义组件中使用原生事件而产生的。
使用场景
子组件需要调用父组件的方法
多使用于传递原生事件
使用方法
v-on = "$listeners"
案例
需求:子组件获取父组件中的方法
Father.vue
<template>
<div>
<h3>通过$listeners获取原生事件</h3>
<Son @click="getMsg"/>
</div>
</template>
<script>
import Son from "./Son";
export default {
name: 'Father',
components:{Son},
methods:{
getMsg(){
console.log('我是父组件传递过来的方法')
}
}
}
</script>
Son.vue
<template>
<div>
<label>输入框:<input v-on="$listeners" /></label>
</div>
</template>
<script>
export default {
name:'Son',
mounted(){
console.log(this.$listeners);
}
}
</script>
运行结果
$listeners注意点
1、如果是孙组件要访问父组件的属性和调用方法,直接一级一级传下去就可以
2、$listeners
不包含父组件中添加 .native 修饰器
的v-on事件监听器
验证
Father.vue中click事件添加事件修饰符.native
<Son @click.native="getMsg"/>
运行结果:$listeners
属性为空对象
以上为三种方法,个人总结,如有不对的地方,请指教。