vue中sync,v-model----双向数据绑定

需求:父子组件同步数据
实现方式:sync或者v-model
一、sync
原理:
通常我们要父子组件中的数据时刻保持同步,可以这样:
父组件中的template:
<sycn-son :foo="fatherFoo"></sycn-son>

 

 
子组件注册foo数据:
props:{
foo: String
},

 

 
子组件改变:通过点击按钮,触发update事件,将值传入
<button @click="updateFoo">点击改变</button>

 

 
methods:{
    updateFoo(){
    this.$emit('update','foo被子组件改变啦')
    }
}

 

 
父组件接收:
<sycn-son :foo="fatherFoo" v-on:update="sonFoo => fatherFoo = sonFoo"></sycn-son>

 

 
效果:
未点击:
 
点击改变:
父组件来点击改变:
 
这样就实现了父子组件同步数据,sync就是这样的原理,vue提供了sync修饰符简化了上面的代码
因此就可以这样写:
父组件:
<sycn-son :foo.sync="fatherFoo"></sycn-son>

 

 
子组件:
updateFoo(){
    this.$emit('update:foo','foo被子组件改变啦')
}

 

 
效果:依旧如上图
代码:
父组件:
<template>
<div>
<sycn-son :foo.sync="fatherFoo"></sycn-son>
<br>
父组件的foo:{{fatherFoo}}
<button @click="syncFatherUpdate">父组件来点击改变</button>
</div>
 
</template>
 
<script>
import sycnSon from './sycnSon'
export default {
name: 'sycnFather',
components:{
  sycnSon
},
data () {
  return {
    fatherFoo:'我是一开始的foo'
  }
},
methods:{
  syncFatherUpdate (){
    this.fatherFoo = '被父组件改变'
  }
 
 }
}
</script>

 

 
子组件:
<template>
<div>
子组件的foo:{{foo}}
<button @click="updateFoo">点击改变</button>
</div>
</template>
 
<script>
export default {
name: 'sycnSon',
props:{
    foo: String
},

methods:{
    updateFoo(){
        this.$emit('update:foo','foo被子组件改变啦')
}
}
}
</script>    

 

 
注意:
当sync修饰的prop是个对象或者数组,虽然对象/数组是引用类型的,你直接修改子组件,会同时修改父组件的数据,但是会让数据流变得更加难以分析!所以要深度复制对象给一个新值,再改变新值传给父组件。
JSON.parse(JSON.stringify(this.analysisData))

 

 
 
二、v-model---只介绍父子组件双向绑定
v-model通常用于表单元素的双向绑定,v-model 是 .sync的一种体现。约定俗成是用于表单类型的双向绑定。可不可以用于其他的组件呢,当然可以,只是没有sync这么直观
1. 表单类型的双向绑定:
子组件:
<input :value="value" @input="$emit('input', $event.target.value)">
@input是自带的oninput事件,当输入框改变时,调用里面的事件。
 
父组件:
<model-son v-model="fatherMsg"></model-son>
相当于:
 
效果:
未改变输入框:
改变输入框:
点击父组件来点击改变:
 完整代码:
父组件:
<template>
<div>
    <model-son v-model="fatherMsg"></model-son>
    <br>
    父组件:{{fatherMsg}}
    <button @click="modelFatherUpdate">父组件来点击改变</button>
    
</div>

</template>

<script>
import modelSon from './modelSon'
export default {
  name: 'modelFather',
  components:{
      modelSon
  },
  data () {
    return {
        fatherMsg:'父组件一开始定义的fatherMsg'
    }
  },
  methods:{
    modelFatherUpdate (){
        this.fatherMsg = 'fatherMsg被父组件改变'
    }

  }
}
</script>

 

子组件:

<template>
<div>
  子组件的msg:
  <input :value="value" @input="$emit('input', $event.target.value)">
</div>

</template>

<script>
export default {
  name: 'modelSon',
  // 必须是value
  props:{
      value:String
  },
}
</script>

注意:注册必须是value

 
2.自定义组件v-model双向绑定
官网:
子组件:首先要注册,和说明model
model: {
    prop: 'msg',
    event: 'change'
},
props:{
    msg:String
},

 

使用model解释:prop属性说,我要将msg作为该组件被使用时v-model能取到的值,也就是一开始的值
event说,我emit ‘change’ 的时候,传入的参数值就是父组件v-model要收到的值。
 
父组件:使用v-model绑定自己的数据
<model-son v-model="fatherMsg"></model-son>
 
效果:
未点击时:
 
点击改变:
 
父组件来点击改变:
完整代码:
父组件:
<template>
<div>
<model-son v-model="fatherMsg"></model-son>
<br>
父组件:{{fatherMsg}}
<button @click="modelFatherUpdate">父组件来点击改变</button>
 
</div>
 
</template>
 
<script>
import modelSon from './modelSon'
export default {
    name: 'modelFather',
components:{
    modelSon
},
data () {
    return {
        fatherMsg:'父组件一开始定义的fatherMsg'
    }
},
methods:{
    modelFatherUpdate (){
        this.fatherMsg = 'fatherMsg被父组件改变'
        }
 
    }
}
</script>
         

 

子组件:
<template>
<div>
子组件的msg:{{msg}}
<button @click="modelUpdate">点击改变</button>
</div>
 
</template>
 
<script>
export default {
    name: 'modelSon',
    model: {
        prop: 'msg',
        event: 'change'
    },
    props:{
        msg:String
    },
methods:{
    modelUpdate (){
        this.$emit('change','msg被子组件改变了!')
}
 
}
}
</script>        

 

 
待补充。。。
 
 
 
 
 
 
 
 
 
 
posted @ 2018-09-18 23:38  echo'coding'  阅读(5805)  评论(0编辑  收藏  举报