如何「修改」Vue中的prop

在Vue中,prop是能夠接受由父組件傳遞給子組件的屬性,但prop沒法進行修改的(因此我加了引號,嘿嘿)。html

若是prop被強制修改,會有警告⚠️vue

[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.markdown

因此,咱們只能「變相」地修改prop~ide

固然,若是你對以上的話一臉懵逼能夠看看官網文檔關於Prop的內容函數

1.使用父子組件傳值修改

上面的警告大概意思說:單獨在子組件中修改數值,在父組件從新渲染更新的時候仍是傳同樣的值進去,形成一個重寫的狀況。oop

說得白話一點:哪一個組件定義數值,應該哪一個組件定義方法(函數)進行修改。ui

和Vuex的狀態管理相似,爲何state中的數值只能由mutation進行修改操做,最核心的緣由——可回溯。this

只由一個「管理員」進行修改操做,避免多個不一樣身份進行修改操做,這樣就不會「亂套」了,而在狀態追溯時候只要看mutation作了什麼操做,這樣就會一目瞭然。spa

那天然,若是傳遞給子組件的prop數據是在父組件上定義,那修改的prop的數據的方法(函數)能夠在父組件中定義。雙向綁定

<!--父組件-->
<template>  <div>  <Child :propNum="num" @propFun="changeNum"/>  </div> </template>  <script> // 引入 src/components/Child // 引入要根據文件目錄進行修改 import Child from '@/components/Child' export default {  components: { // 註冊組件  Child  },  data () {  return { // 定義num數值  num: 0  }  },  methods: { // 定義修改數值方法  changeNum () {  this.num = this.num + 1  }  } } </script> 複製代碼
<!--子組件-->
<template>  <div>  <span>  {{propNum}}  </span>  <button type="button" @click="onClick">  add  </button>  </div> </template>  <script> export default {  props: {  propNum: { // 接受父子組件傳遞的屬性  type: Number,  default: 0  }  },  methods: {  onClick () { // 在點擊按鈕觸發,父組件傳遞給子組件的方法  this.$emit('propFun')  }  } } </script>  複製代碼

2.使用.sync修飾

注意!是vue 2.30以上才能使用,由於剛開始的vue2.0廢除的這個修飾符 官網文檔

這裏也寫一個和上述相似的例子

<!--父組件-->
<template>  <div>  <Child :propNum.sync="num"/>  </div> </template>  <script> // 引入 src/components/Child // 引入要根據文件目錄進行修改 import Child from '@/components/Child' export default {  components: {  Child  },  data () {  return {  num: 0  }  } } </script>  複製代碼
<!--子組件-->
<template>  <div>  <span>  {{propNum}}  </span>  <button type="button" @click="onClick">  add  </button>  </div> </template>  <script> export default {  props: {  propNum: {  type: Number,  default: 0  }  },  methods: {  onClick () {  const num = this.propNum + 1 // 定義num數值  this.$emit('update:propNum', num) // 傳遞更新數值  }  } } </script> 複製代碼

3.使用自定義組件的v-model

和vue封裝好v-mode的不一樣,如下使用的是自定義組件的v-model

固然仍是要注意使用版本:2.20+

<!--父組件-->
<template>  <div>  <Child v-model="num"/>  </div> </template>  <script> // 引入 src/components/Child // 引入要根據文件目錄進行修改 import Child from '@/components/Child' export default {  components: {  Child  },  data () {  return {  num: 0  }  } } </script>  複製代碼
<!--子組件-->
<template>  <div>  <span>  {{propNum}}  </span>  <button type="button" @click="onClick">  add  </button>  </div> </template>  <script> export default {  model: {  prop: 'propNum', // v-model選擇prop中傳遞名  event: 'changeNum' // 定義事件  },  props: {  propNum: {  type: Number,  default: 0  }  },  methods: {  onClick () {  const num = this.propNum + 1  this.$emit('changeNum', num) // 使用$emit觸發事件並傳值  }  } } </script> 複製代碼

4.總結

以上三種方法均可以「變相修改」props,其中使用父子組件傳值是引用「定義狀態同時定義修改狀態方法」,然後兩中.sync和v-model則是使用「雙向綁定」。

彷佛第一種好像還能夠理解,但後兩種又怎麼驗證呢?,其實只在父和子組件加上使用watch,如在使用.sync修飾符上加watch:

<!--父組件-->
<template>  <div>  <Child :propNum.sync="num"/>  </div> </template>  <script> // 引入 src/components/Child // 引入要根據文件目錄進行修改 import Child from '@/components/Child' export default {  components: {  Child  },  data () {  return {  num: 0  }  },  watch: { // 監聽父組件num屬性  num: {  handler () {  console.log('父組件num', this.num)  }  }  } } </script>  複製代碼
<!--子組件-->
<template>  <div>  <span>  {{propNum}}  </span>  <button type="button" @click="onClick">  add  </button>  </div> </template>  <script> export default {  props: {  propNum: {  type: Number,  default: 0  }  },  methods: {  onClick () {  const num = this.propNum + 1 // 定義num數值  this.$emit('update:propNum', num) // 傳遞更新數值  }  },  watch: { // 監聽子組件propNum屬性  propNum: {  handler () {  console.log('子組件propNum', this.propNum)  }  }  } } </script>  複製代碼

運行,點擊add按鈕就有如下結果

相似使用自定義組件但v-model,也能夠使用這種方法驗證,你們能夠自行驗證,就再也不贅述~

感謝閱讀

相關文章
相關標籤/搜索