自定义组件v-model
原理分析
v-model = data
等价于
:value = “data”
@input = ()=>{this.data = $event.target.newValue}
如果要使用,整个双向绑定的过程如下
子组件中触发某个事件,发送了input事件和value新的值给父组件
父组件接受input事件,并将里面的新的值赋值给data
以此依靠v-bind完成对value的改变。
也就是说仍然是父组件先改变。
简单例子:
//子组件Tesy
<template>
<div>
<span>{{data}}</span>
<button @click="change">修改data</button>
</div>
</template>
<script>
export default {
name: 'Tesy',
props: {
data:String
},
methods:{
change(){
this.$emit('change', "我被修改了");
}
},
// 控制v-modal监听的数据和事件
model: {
prop: 'data',
event: 'change'
},
}
</script>
<style scoped>
</style>
// 父组件
<template>
<a-card :bordered="false">
<h1>我是父组件中的data:</h1>
<div>{{testData}}</div>
<tesy v-model="testData"></tesy>
</a-card>
</template>
export default {
name: 'index.vue',
data() {
return {
testData:"我没被修改",
}
}
结果:
点击后
没用警告完全正确
实际使用
在实际的使用中,情况会远比这复杂,因为通常子组件的值总是先于父组件变化,而非先发事件出去。这时我们怎么处理呢?
我的解决方案是建立一个中间层
比如在子组件中的参数为 value ,父组件中与其绑定的值为data。
我们的value因为某些原因一定先于data变化。
所以我们需要一个中间层来实现
流程解释:
1.data将值赋值给value
2.value将值赋给valueUse
3.我们在组件中使用valueUse作为数据操作的对象
4.监听valueUse,当valueUse发送改变时,向父组件传新值($emit)
5.父组件接受到目标事件,改变data,(这里也可以进行别的处理)
6.value被改变。
(可选)
7.如果需要的话,还可以监听value的变化去再去改变valueUse。
eUse发送改变时,向父组件传新值($emit)