VUE-父子組件通信 及 v-model實現通信


一、父組件向子組件傳值

1、首先創建父組件(parent)和子組件(child),並在父組件中注冊子組件

2、在父組件調用子組件標簽中添加一個自定義屬性(msg)

// 父組件
	<template>
        <div class="parent">
            <Child :msg="parentMsg"></Child>
        </div>
    </template>
    <script>
        import Child from './child.vue';
        export default {
            data() {
                return {
                    parentMsg: "我是傳給子組件的值"
                };
            },
            components: {
                Child
            },
        }
	</script>

3、在子組件的props中將父組件中自定義屬性(msg)添加進去,則該屬性在子組件中可以像data中定義的屬性一樣使用

// 子組件
 	<template>
        <div class="child">
            <p>{{ msg }}</p>
        </div>
    </template>
    <script>
        export default {
            props: {
                msg:{
                    type:String,
                    default:""
                }
            }
        }
    </script>

二、子組件向父組件傳值

1、在子組件中創建一個按鈕,給按鈕綁定一個點擊事件

2、在響應 點擊事件的函數中使用$emit來發送一個自定義事件(listenChildEvent)給父組件,並傳遞一個參數

	<template>
        <div class="child">
            <p>{{ msg }}</p>
            <button @click="sendMsg">向父組件傳值</button>
        </div>
    </template>
    <script>
        export default {
            props: {
                msg:{
                    type:String,
                    default:""
                }
            },
            methods:{
                sendMsg(){
                    this.$emit("listenChildEvent","this message is from child");
                }
            }
        }
    </script>

3、在父組件調用子組件標簽中,監聽該自定義事件(listenChildEvent)並添加一個響應該事件的處理方法,並接收子組件傳過來的數據

<template>
        <div class="parent">
            <Child :msg="parentMsg" @listenChildEvent="acceptMsgFromChild"></Child>
        </div>
    </template>
    <script>
        import Child from './child.vue';
        export default {
            data() {
                return {
                    parentMsg: "我是傳給子組件的值"
                };
            },
            components: {
                Child
            },
            methods:{
                acceptMsgFromChild(data){
                    console.log(data);//或者將接受值處理
                }
            }
        }
    </script>

三、使用v-model實現父子組件通信

1、v-model一般用於表單的雙向數據綁定

<template>
  <div>
    <input type="text"
           v-model="msg">
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  data () {
    return {
      msg: ''
    }
  }
}
</script>

2、v-model原理

由此看出,v-model是v-bindv-on:input的結合,即監聽了表單的input事件,然后修改value屬性對應的值

<template>
  <div>
    <input type="text"
           :value="msg"
           @input="bind">
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  data () {
    return {
      msg: ''
    }
  },
  methods: {
    bind () {
      this.msg = event.target.value
    }
  }
}
</script>

3、v-model除了在輸入表單上可以使用之外,在組件上也可以使用,以實現父子組件的雙向數據綁定

// -------------------------------父組件
<template>
  <div>
    <!-- 在父組件中用v-model相當於,v-bind綁定了value,以及執行了v-on:input事件 -->
    <child v-model="flag"></child>
    <div>{{flag}}</div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      flag: ''
    }
  },
  components: {
    child
  }
}
</script>

// -------------------------------子組件
<template>
  <div>
      <div class="btn" @click="confirm">確定</div>
  </div>
</template>
<script>
export default {
// 用props接收父組件傳遞的value值,從而實現雙向數據綁定
  props: {
    value: {
      type: Boolean,
      default: true
    }
  },
  methods: {
    // 通過$emit觸發父組件的input事件,並將第二個參數作為值傳遞給父組件
    confirm () {
      this.$emit('input', false)
    }
  }
}
</script>

最后,父組件中的flag默認為true,點擊了子組件中的“確定”后,子組件將false傳遞給了父組件的flag

4、v-model添加model選項

以上這種方式實現的父子組件的v-model通信,限制了popos接收的屬性名必須為value和emit觸發的必須為input,這樣容易有沖突,特別是在表單里面。所以,為了更優雅的使用v-model通信,可以在子組件中使用model選項

// 子組件
<template>
  <div>
      <div class="btn" @click="confirm">確定</div>
  </div>
</template>
<script>
export default {
// model選項用來避免沖突,prop屬性用來指定props屬性中的哪個值用來接收父組件v-model傳遞的值,例如:這里用props中的flag1來接收父組件傳遞的v-model值;event屬性可以理解為父組件@input的別名,從而避免沖突,即emit時要提交的事件名。
  model: {
	prop: 'flag1',
	event: 'changed'
  }
// 用props接收父組件傳遞的value值,從而實現雙向數據綁定
  props: {
    value: {
      type: Boolean,
      default: true
    }
  },
  methods: {
    // 通過$emit觸發父組件的input事件,並將第二個參數作為值傳遞給父組件
    confirm () {
      this.$emit('input', false)
    }
  }
}
</script>

5、v-model實現動態傳值

<template>
  <div>
    <new-input v-model="name"></new-input>{{name}}
  </div>
</template>
<script>
import Vue from 'vue'
Vue.component('new-input', {
  props: {
    value: {
      type: String
    }
  },
  template: '<label><input type="text" v-model="newValue" /> 你的名字:</label>',
  computed: {
    newValue: {
      get: function () {
        return this.value
      },
      set: function (value) {
        this.$emit('input', value)
      }
    }
  }
})

export default {
  data () {
    return {
      name: 'nick'
    }
  }
}
</script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM