vue中如何實現雙向綁定的3中方法(.sync/v-model和普通交互)

目錄

參考文章

需求

1、第一步、全局子組件定義child

2、第二步、放官網select例子

3、第三步、普通的父子交互方法

1.1在上面的基礎例子上的methods裏面添加commit方法:

1.2在父頁面中利用方法去獲取子頁面內容:

1.3實際效果gif

4、第四步、sync的watch方法

5、第五步、v-model的雙向綁定

1.1、聲明傳過來的值付賦給什麼屬性

1.2、this.$emit

 1.3、子頁面增加v-model和event綁定

總結

全局代碼

1、child.js

2、demo.html

3、效果圖



  • 參考文章

  1. vue 實現父組件和子組件之間的數據雙向綁定

  2. 深入理解vue 修飾符sync【 vue sync修飾符示例】

  3. 徹底明白VUE修飾符sync

  • 需求

當子頁面數據發生變化的時候,父頁面的結果也需要更新,由於數據是單向傳遞,是不可以直接需改父頁面的數據,那麼我們該怎麼操作呢?本篇文章可以利用2種方式(sync、v-model)實現效果都是一樣的,區別在於一個要在父頁面聲明傳遞的數據對象,一個是在子頁面去解析傳遞的對象是給什麼data裏面的屬性。

我們從官網element-ui中拿一個select下拉框來做實驗:

1、第一步、全局子組件定義child

Vue.component("child", {
    data: function () {
        return {}
    },
    template: ``,
    methods:{}
});

2、第二步、放官網select例子

Vue.component("child", {
    data: function () {
        return {
            options: [{
                value: '選項1',
                label: '黃金糕'
            }, {
                value: '選項2',
                label: '雙皮奶'
            }, {
                value: '選項3',
                label: '蚵仔煎'
            }, {
                value: '選項4',
                label: '龍鬚麪'
            }, {
                value: '選項5',
                label: '北京烤鴨'
            }],
            value: ''
        }
    },
    template: `
                <div>
                    <el-select v-model="value" placeholder="請選擇">
                        <el-option
                          v-for="item in options"
                          :key="item.value"
                          :label="item.label"
                          :value="item.value">
                        </el-option>
                    </el-select>
                </div>
               `,
    methods: {
        
    }
});

3、第三步、普通的父子交互方法

1.1在上面的基礎例子上的methods裏面添加commit方法:

 methods: {
        commit() {
            this.$emit('output', this.value);
        },
    }

1.2在父頁面中利用方法去獲取子頁面內容:

<p style="font-size: 13px">父組件2:{{foo}}</p>
<child :give="foo" @output="output"></child>

......

let vue = new Vue({
    el: '#app',
    data: {
        foo: null,
    },
    methods: {
    output(data){
        this.foo = data;
        console.log('通過方法獲取子對象屬性變化:', foo);
    },

......

1.3實際效果gif

4、第四步、sync的watch方法

這裏give是外部需要傳入的數據,this.value是子頁面不斷修改的數據。

如果當你寫完這個,你的html頁面就可以利用下面➷➷➷➷➷➷實現數據交互。從這個我們可以知道當使用sync的時候要在父頁面明確聲明你傳值給誰

<child :give.sync="foo"></child>
props: ['give'],
    watch: {
        'give': function (newVal, oldVal) {
            this.value = newVal;
        },
        value: function (newVal, oldVal) {
            this.$emit("update:give", newVal);
        }
    },

5、第五步、v-model的雙向綁定

1.1、聲明傳過來的值付賦給什麼屬性

解釋例子傳參,

model: {
    prop: '父接收屬性',
    event: 'commit(普通方法定義接收值)'
},

如在上面所說的最普通實現父子交互是:

<child :give="foo" @output="output"></child>

 從這個我們可以將參數補充進去:

model: {
    prop: 'give',// 即:give
    event: 'output'// 即@output
},

1.2、this.$emit

如果你在使用v-model中沒有添加commit方法是需要添加的

 methods: {
        commit() {
            this.$emit('output', this.value);
        },
    }

 1.3、子頁面增加v-model和event綁定

​​​​​​......

<el-select v-model="value" placeholder="請選擇" @change="commit">

......

上面3個效果都是等同的,看你想要用什麼去實現了。

  • 總結

1、普通方法

使用簡單,但是需要在父頁面中定義接收方法,需要子methods裏面使用emit,如果說自定義組件比較多,父頁面的方法就會很臃腫;

<child :give="foo" @output="output"></child>

2、sync

使用簡單,但是需要在父頁面中定義具體傳參值,在watch中使用emit,如果自定義組件比較多,每個頁面傳值定義的單詞又不一樣,容易暈眩;

<child :give.sync="foo"></child>

3、v-model

使用簡單,父頁面幾乎不需要幹什麼,將具體綁定都什麼對象由子頁面去分析,需要定義model,在methods裏面使用emit,也比較簡潔。

<child v-model="foo"></child>
  • 全局代碼

  • 1、child.js

Vue.component("child", {
    data: function () {
        return {
            options: [{
                value: '選項1',
                label: '黃金糕'
            }, {
                value: '選項2',
                label: '雙皮奶'
            }, {
                value: '選項3',
                label: '蚵仔煎'
            }, {
                value: '選項4',
                label: '龍鬚麪'
            }, {
                value: '選項5',
                label: '北京烤鴨'
            }],
            value: ''
        }
    },
    props: ['give'],
    watch: {
        'give': function (newVal, oldVal) {
            this.value = newVal;
        },
        value: function (newVal, oldVal) {
            this.$emit("update:give", newVal);
        }
    },
    model: {
        prop: 'give',
        event: 'commit'
    },
    template: `
                <div>
                    <el-select v-model="value" placeholder="請選擇" @change="commit">
                        <el-option
                          v-for="item in options"
                          :key="item.value"
                          :label="item.label"
                          :value="item.value">
                        </el-option>
                    </el-select>
                </div>
               `,
    methods: {
        commit() {
            this.$emit('output', this.value);
        },
    }
});

  • 2、demo.html

<script th:src="@{~/js/components/jt/child.js}"></script>
<child :give="foo" @output="output"></child>
<child :give.sync="foo"></child>
<child v-model="foo"></child>
<script type="text/javascript">
    let vue = new Vue({
        el: '#app',
        data: {
            foo: null,
        },
        methods: {
            output(data){
                this.foo = data;
                console.log('通過方法獲取子對象屬性變化:', this.foo)
            },
        }
    })
</script>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head th:replace="common/header :: header">
</head>
<head>
    <meta charset="UTF-8">
    <!-- import CSS -->
    <link rel="stylesheet" th:href="@{~/css/ui/reset.css}">
    <link rel="stylesheet" th:href="@{~/css/ui/index.css}">

    <script th:src="@{~/js/components/jt/child.js}"></script>
</head>
<body>
<div id="app">
    <p style="font-size: 13px">父組件2:{{foo}}</p>
    普通方法:<child :give="foo" @output="output"></child>
    sync:<child :give.sync="foo"></child>
    v-model:<child v-model="foo"></child>
</div>
</body>
<script type="text/javascript">
    let vue = new Vue({
        el: '#app',
        data: {
            foo: null,
        },
        methods: {
            output(data){
                this.foo = data;
                console.log('通過方法獲取子對象屬性變化:', this.foo);
            },
        }
    })
</script>
</html>
  • 3、效果圖

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