其实是前两天了解了v-mdel的原理
<!-- v-model原理-->
<div id="demo">
<input :value="value" @input="price=$event.target.value">
</div>
<script>
new Vue({
el:'#demo',
data:{
price:1000
}
})
</script>
然后想使用v-model原理 应用到父子组件的通信中(父传子,子传父)
先展示一下代码:
<body>
<!-- 本组件 -->
<div id="demo">
<!-- 父传子 把变化的变量传递 -->
<currency-input :value="price" @input="(val) => (price = val)">
</currentcy-input>
</div>
<script>
// 全局组件
Vue.component('currency-input', {
template: `
<span>
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
</span>
`,
props: ['value'],
})
//vue实例
var demo = new Vue({
el: '#demo',
data: {
price: 1000
}
})
</script>
</body>
在浏览器中的展示:
在父组件中修改应用的子组件的input中的值(子传父)和data中的值(父传子)都能实现双向绑定
在子组件中修改input中的值能实现(子传父)
但是修改 props中的值就会报如下错:
原因:
父组件通过props传值给子组件,子组件改变props的属性值导致;,先看一眼官方文档:
父子组件中的数据流是单向的,父子之间形成了一个单向绑定:父级data的更新会向下流动到子组件中,但是反过来子修改props则不行。(父组件更新,子组件中的props值也会更新,但子组件不能修改props值再传给父组件);
解决方案:
将传递给子组件的数据改为对象形式,在子组件中用对象属性去渲染:
<!-- 本组件 -->
<div id="demo">
<!-- 父传子 把变化的变量传递 -->
<currency-input :value="price" @input="(val) => (price = val)">
</currentcy-input>
</div>
<script>
// 全局组件
Vue.component('currency-input', {
template: `
<span>
<input
:value="value.num"
@input="$emit('input', $event.target.value)"
>
</span>
`,
props: ['value'],
})
//vue实例
var demo = new Vue({
el: '#demo',
data: {
price: {
num: 1000
}
}
})
</script>
将传过去的数据改为对象,再用对象属性去渲染,确实不会报警告了!!!
这样虽然解决但是根据官方文档的翻译,我们可以理解为props中的属性最好避免改动,已经提醒你了,出错了算你自己的。所以方案二是最优方案
解决方案二:
我们可以在data
中重新定义相应的属性来接收props
中的属性。
<!-- 本组件 -->
<div id="demo">
<!-- 父传子 把变化的变量传递 -->
<currency-input :value="price" @input="(val) => (price = val)">
</currentcy-input>
</div>
<script>
// 全局组件
Vue.component('currency-input', {
template: `
<span>
<input
:value="price"
@input="$emit('input', $event.target.value)"
>
</span>
`,
props: ['value'],
data: function () {
return {
price: this.value
}
}
})
//vue实例
var demo = new Vue({
el: '#demo',
data: {
price: 1000
}
})
</script>