【Vue】四種父組件與子組件雙向數據綁定的方法

前言:見多了父組件向子組件傳遞數據,子組件向父組件傳遞數據,現在來玩玩父組件與子組件之間雙向數據綁定,還有通過.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方法方法來通過子組件給父組件傳值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章