1. 程式人生 > 程式設計 >vue 使用 v-model 雙向繫結父子元件的值遇見的問題及解決方案

vue 使用 v-model 雙向繫結父子元件的值遇見的問題及解決方案

場景

今天在使用 v-model 進行元件雙向資料繫結的時候遇到了一個奇怪的問題,網頁本身執行正常,瀏覽器一直出現警告資訊。

[vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead,use a data or computed property based on the prop's value. Prop being mutated: "value"

引發這個警告的是一個自定義元件 RxSelect

Vue.component("RxSelect",{
 model: {
 prop: "value",event: "change",},props: {
 value: [Number,String],map: Map,template: `
  <select
   v-model="value"
   @change="$emit('change',value)"
  >
   <option
   v-for="[k,v] in map"
   :value="k"
   :key="k"
   >{{v}}</option>
  </select>
  `,});

吾輩使用的程式碼看起來程式碼貌似沒什麼問題?http://www.cppcns.comhttp://www.cppcns.com

<main id="app">
 當前選擇的性別是: {{map.get(sex)}}
 <div>
 <rx-select :map="map" v-model="sex" />
 </div>
</main>

javascript 程式碼

new Vue({
 el: "#app",data: {
 map: new Map().set(1,"保密").set(2,"男").set(3,"女"),sex: "",});

經測試,程式本身執行正常,父子元件的傳值也沒什麼問題,雙向資料繫結確實生效了,然而瀏覽器就是一直報錯。

嘗試解決

吾輩找到一種方式

  1. 為需要雙向繫結的變數在元件內部 data 宣告一個變數 innerValue,並初始化為 value
  2. select 上使用 v-model繫結這個變數 innerValue
  3. 監聽 value 的變化,在父元件中 value 變化時修改 innerValue 的值
  4. 監聽 innerValue 的變化,在變化時使用 this.$emit('changeSLgfB',val) 告訴父元件需要更新 value 的值
Vue.component("RxSelect",data() {
 return {
  innerValue: this.value,};
 },watch: {
 value(val) {
  this.innerValue = val;
 },innerValue(val) {
  this.$emit("change",val);
 },template: `
 <select v-model="innerValue">
 <option
  v-for="[k,v] in map"
  :value="k"
  :key="k"
 >{{v}}</option>
 </select>
 `,});

使用程式碼完全一樣,然而元件 RxSelect 的程式碼卻多了許多。。。

解決

一種更優雅的方式是使用 computed 計算屬性以及其的 get/set,程式碼增加的程度還是可以接受的

Vue.component("RxSelect",computed: {
 innerValue: {程式設計客棧
  get() {
  return this.value;
  },set(val) {
  this.$emit("change",val);
  },});

以上就是vue 使用 v-model 雙向繫結父子元件的值遇見的問題及解決方案的詳細內容,更多關於vue 使用 v-model 雙向繫結www.cppcns.com父子元件的值的資料請關注我們其它相關文章!