「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
概述
props 的值是单向下行传递的,父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
重新赋值法
实现思路:
在子组件的data中定义一个变量,将props接收到的数据重新赋值给这个变量,在页面显示时直接与此变量进行双向数据绑定。
代码
父组件
<template>
<div>
<div class="fatherBox">
<h2>父组件</h2>
<childTemp :data="showLabel"></childTemp>
</div>
</div>
</template>
<script>
import childTemp from '../compontent/childTemp.vue'
export default {
components:{childTemp}
data() {
return {
showLabel:'我是父组件的数据'
}
},
}
</script>
<style scoped>
.fatherBox{
width: 500px;
height: 200px;
margin: 30px auto;
background:rgb(135, 135, 196);
}
</style>
子组件
<template>
<div>
<div class="childBox">
<h2>子组件</h2>
<h3>父组件传来的值-----------{{this.data}}</h3>
<h3>子组件修改后的值---------{{this.showLabel}}</h3>
</div>
</div>
</template>
<script>
export default {
props:['data'],
data() {
return {
showLabel: this.data,
}
},
mounted() {
this.showLabel = '我是子组件的数据'
},
}
</script>
<style scoped>
.childBox{
width: 350px;
height: 120px;
margin: 30px auto;
background: thistle;
}
</style>
显示如下:
.sync修饰符法
实现思路
在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源。所以官方推荐以 update:myPropName
的模式触发事件取而代之
众所周知Props是单向下行传递数据,所以我们可以将.sync修饰符理解为单向上行传递数据。
代码
父组件
<template>
<div>
<div class="fatherBox">
<h2>父组件</h2>
<childTemp v-bind:content.sync="showLable"></childTemp>
<!-- // 一个组件上的 v-model默认对应其子组件的props的value -->
</div>
</div>
</template>
<script>
import childTemp from '../compontent/childTemp.vue'
export default {
data() {
return {
showLable:'我是父组件的数据'
}
},
components:{childTemp}
}
</script>
<style scoped>
.fatherBox{
width: 500px;
height: 200px;
margin: 30px auto;
background:rgb(135, 135, 196);
}
</style>
子组件
<template>
<div>
<div class="childBox">
<button @click="btnTest">我是子组件,{{ showlable }}</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showlable: this.data,
}
},
props:['data'],
watch: {
data(val) {
this.showlable = val;
}
},
methods: {
btnTest() {
this.showlable = '哈哈,在子组件中改变了父组件传递过来的数据';
// 更新content值
this.$emit('update:data',this.showlable);
}
},
}
</script>
<style scoped>
.childBox{
width: 350px;
height: 120px;
margin: 30px auto;
background: thistle;
}
</style>
显示效果如下
点击后
.sync使用注意
注意带有
.sync
修饰符的v-bind
不能和表达式一起使用 (例如v-bind:title.sync=”doc.title + ‘!’”
是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似v-model
。
将
v-bind.sync
用在一个字面量的对象上,例如v-bind.sync=”{ title: doc.title }”
,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。