如何“修改”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,也能够使用这种方法验证,你们能够自行验证,就再也不赘述~

感谢阅读

相关文章
相关标签/搜索