Vue中子元件通過v-model動態修改父元件中的值
阿新 • • 發佈:2022-05-20
父子通訊中的子傳父-使用v-model實現雙向資料繫結
-
現有需求:通過子元件中的輸入框來動態繫結父元件中data中的資料。
-
程式碼實現
-
- 父元件使用porps來向子元件傳值
- 子元件通過自己定義的兩個屬性(number1,number2)來接受父元件的值(num1,num2)
- 通過v-model屬性將輸入框與子元件的number1和number2來進行繫結
-
-
結果
-
上面功能的實現的確沒有問題,但思路有問題,而且在一般情況下,vue是不建議通過這種方式來直接修改父元件中的值的。
-
程式碼如下:
-
-
<body> <div id="app"> <cpn :number1="num1" :number2="num2"></cpn> </div> <template id="cpm"> <div> <h2>props:{{number1}}</h2> <h2>data:{{dnumber1}}</h2> <input type="text" v-model="number1"> <h2>props:{{number2}}</h2> <h2>data:{{dnumber2}}</h2> <input type="text" v-model="number2"> </div> </template> <script> const app = new Vue({ el: '#app', data: { num1: 1, num2: 0 }, components: { cpn: { template: '#cpm', props: { number1: Number, number2: Number }, }, }, }) </script> </body>
- 執行截圖
反思:這樣雖然可以實現子元件向元件傳值,但這種方法在vue看來是極為不推薦的。
- 程式碼改進
- 程式碼實現
- 在上面的基礎上,我在子元件中定義兩個data屬性(dnumber1,dnumber2),用來儲存父元件傳過來的值
- 將input繫結的屬性從number1改為dnumber1,number2同理
- 程式碼實現
<body> <div id="app"> <cpn :number1="num1" :number2="num2"></cpn> </div> <template id="cpm"> <div> <!-- 用來檢視父子元件中,值的變化情況 --> <h2>props:{{number1}}</h2> <h2>data:{{dnumber1}}</h2> <input type="text" v-model="dnumber1"> <!-- 用來檢視父子元件中,值的變化情況 --> <h2>props:{{number2}}</h2> <h2>data:{{dnumber2}}</h2> <input type="text" v-model="dnumber2"> </div> </template> <script> const app = new Vue({ el: '#app', data: { num1: 1, num2: 0 }, components: { cpn: { template: '#cpm', props: { number1: Number, number2: Number }, data() { return { dnumber1: this.number1, dnumber2: this.number2 } } }, }, }) </script> </body>
- 執行截圖
反思:這樣是不報錯了,但是父元件中的值沒有被修改呀,看來得使用
自定義事件
來向父元件傳值了!
-
程式碼改進
-
自元件使用
$emit
自定義事件建立一個自定義事件dnumber1change
,dnumber2change
,並將dnumber1,和dnumber2傳遞過去。- 父元件定義監聽函式
number1chage
,number2change
,在這個函式中,將取得的值value
傳遞給父元件data
中的值,從而將num1
,和num2
的值進行修改。
- 父元件定義監聽函式
-
<body> <div id="app"> <cpn :number1="num1" :number2="num2" @dnumber1change="number1chage" @dnumber2change="number2change"></cpn> </div> <template id="cpm"> <div> <!-- 用來檢視父子元件中,值的變化情況 --> <h2>props:{{number1}}</h2> <h2>data:{{dnumber1}}</h2> <input type="text" :value="dnumber1" @input="num1Input"> <!-- 用來檢視父子元件中,值的變化情況 --> <h2>props:{{number2}}</h2> <h2>data:{{dnumber2}}</h2> <input type="text" :value="dnumber2" @input="num2Input"> </div> </template> <script> const app = new Vue({ el: '#app', data: { num1: 1, num2: 0 }, methods: { number1chage(value) { this.num1 = parseInt(value) }, number2change(value) { this.num2 = parseInt(value) } }, components: { cpn: { template: '#cpm', props: { number1: Number, number2: Number }, data() { return { dnumber1: this.number1, dnumber2: this.number2 } }, methods: { num1Input(event) { this.dnumber1 = event.target.value; // 為了父元件可以修改值,發出一個事件 this.$emit('dnumber1change', this.dnumber1); }, num2Input(event) { this.dnumber2 = event.target.value; // 為了父元件可以修改值,發出一個事件 this.$emit('dnumber2change', this.dnumber2); } } }, } }) </script> </body>
-
執行截圖
總結:v-model的本質
- < input type="text" v-model="dnumber1">
- < input type="text" v-bind:value="dnumber1" @input="dnumber1=$event.target.value">
下面的程式碼等同於上面的程式碼, 這也就是需求實現的
關鍵