前言:见多了父组件向子组件传递数据,子组件向父组件传递数据,现在来玩玩父组件与子组件之间双向数据绑定,还有通过.sync修饰符,来优化这种写法。

 

方法一:对象的引用关系

<body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<div id="box">
    <new-input v-bind:person="freddy" ></new-input>
    {{freddy.name}}
</div>
<script>
Vue.component('new-input',{
    props: ['person'],
    template:'<label><input type="text" v-model="person.name" /> 你的名字:</label>'	
});
new Vue({
    el:'#box',	
    data: {
	freddy: {
	    name:'nick'	
	}		
    }
});
</script>
</body>

运行结果:

该方法运用的是对象的引用关系,来实现的。虽然实现起来很简单,但是还是存在数据混乱的隐患。使用时要比较小心。

 

方法二:父子组件之间的数据传递

<body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<div id="box">
    <new-input v-bind:name="name" v-on:update:name="getNewName"></new-input>
    {{name}}
</div>
<script>
Vue.component('new-input',{
    props: ['name'],
    data: function(){
        return {
	    newName: this.name
	}	
    },
    template:'<label><input type="text" @keyup="changeName" v-model="newName" /> 你的名字:</label>',
    methods: {
	changeName: function(){
	    this.$emit('update:name',this.newName);
	}
    }	
});
new Vue({
    el:'#box',	
    data: {
	name:'nick'		
    },
    methods:{
	getNewName: function(newName){
	    this.name = newName;
	}	
    }
});
</script>
</body>

运行结果:

稍微提一下的是,通过props,父组件向子组件传递了那么name值,然后通过注册'update:name'事件给父组件传递新的name值。

这里为什么要注册一个'update:name'这么复杂的事件名称呢?这其实跟下面要说的.sync修饰符有关

还有一点比较重要的是

<new-input v-bind:name="name" v-on:update:name="getNewName"></new-input>

可以简写成

<new-input v-bind:name="name" v-on:update:name="name = $event"></new-input>

 

方法三: .sync

<body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<div id="box">
    <new-input v-bind:name.sync="name"></new-input>
    {{name}}
</div>
<script>
Vue.component('new-input',{
    props: ['name'],
    data: function(){
	return {
	    newName: this.name
	}	
    },
    template:'<label><input type="text" @keyup="changeName" v-model="newName" /> 你的名字:</label>',
    methods: {
	changeName: function(){
	    this.$emit('update:name',this.newName);
	}
    }	
});
new Vue({
    el:'#box',	
    data: {
	name:'nick'		
    },
    methods:{
	getNewName: function(newName){
	    this.name = newName;
	}	
    }
});
</script>
</body>

运行结果

通过与方法一进行比较:会发现

<new-input v-bind:name="name" v-on:update:name="name = $event"></new-input>

被简化成了

<new-input v-bind:name.sync="name"></new-input>

而其他代码不变。

所以我们在使用.sync修饰符的时候,只需要注意,v-bind:xx,v-on:update:xx,v-bind:xx.sync的差异就行了。

而且注册事件的时候一定要用this.$emit( 'update:xx' );

 

方法四: v-model

<body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<div id="box">
    <new-input v-model="name"></new-input>
    {{name}}
</div>
<script>
Vue.component('new-input',{
    props: ['value'],
    template:'<label><input type="text" v-model="newValue" /> 你的名字:</label>',
    computed:{
	newValue: {
	    get:function() {
		return this.value; 
	    },
	    set:function(value) {
		this.$emit('input', value);
	    }
	}
    },
});
new Vue({
    el:'#box',	
    data: {
	name:'nick'		
    }
});
</script>
</body>

要理解该方法的关键是要知道v-model是怎么去实现的。

模仿v-model

<body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<div id="box">
    <input :value="name" @input="changeValue($event.target.value)"/>
    {{ name }}
</div>
<script>
new Vue({
    el:'#box',	
    data: {
	name:'nick'		
    },
    methods:{
	changeValue:function(value){
	    this.name = value;
	}	
    }
});
</script>
</body>

这时就可以看出来了,我们通过['value']可以获取到父组件给子组件传递的值,也可以用过注册input方法方法来通过子组件给父组件传值。

Logo

前往低代码交流专区

更多推荐