分析

vue中父组件向子组件传值时,其父子prop之间形成单向下行绑定,反过来则不行,这样可以防止子组件意外改变父组件的值,怕子组件污染父组件,造成不可控; 此外,每次父组件的数据发生更新时,子组件的值都会更新到最新的数据,但不能直接在子组件内部改变prop(父组件传过来的值),否则浏览器就会发出警告

但我们可能会遇到,需要在子组件修改父组件值的需求,这里介绍三种方法实现:

实现

方法一:通过$emit派发一个自定义事件,父组件收到后,由父组件进行修改

子组件:接受父组件传来的cateId值,但是子组件使用本身的计算属性myCateId进行绑定和修改,一旦值发生改变,便通过向上提交函数this.$emit('changeCate', val)向父组件提交

<!-- 注意子组件里是绑定的计算属性,不是父组件传来的prop里的值 -->
<treeselect
  v-model="myCateId"
  :options="cates"
  :load-options="loadCates"
  placeholder="请选择类别"
/>

export default {
	props: {
		cateId: {
			type: Number,
			default: null
		}
	},
	data() {
		return {
		  cates: [] // 类别列表
		}
	},
	computed: {
		myCateId: {
			get() {
			  return this.cateId
			},
			set(val) {
			  this.$emit('changeCate', val)
			}
		}
	}
}

父组件:引用子组件,并定义改变函数,接受子组件传来的改变值对本身的值进行修改

<!-- 父组件引用子组件 -->
<CateSelect
	:cate-id="form.categoryId"
	style="width: 370px;"
	@changeCate="changeCate"
/>

changeCate(val) {
  this.form.categoryId = val
},
方法二:只要prop是对象或者数组,在子组件里面就可以修改从而改变父组件的值

在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

父组件:引用子组件,定义引用类型数据并传递到子组件

<preview :pre="pre" />

data() {
 return {
    pre: {
      isShow: false,
      flName: '',
      flType: ''
    }
  }
},

子组件:直接修改父组件传来的引用类型数据,则父组件的数据也会被修改

<div @click="changePre"></div>

props: {
  pre: {
    // 控制该组件是否显示
    isShow: {
      type: Boolean,
      default: false
    },
    // 浏览文件名(服务器存储的加上UUID的文件名)
    flName: {
      type: String,
      default: null
    },
    // 浏览文件类型,true为图片,false为文档
    flType: {
      type: String,
      default: false
    },
    type: Object,
    default: null
  }
},
methods: {
  changePre() {
    this.pre.isShow = true
  }
}

建议

注意:虽然有两种方法可以实现子组件修改父组件值,但是官方是不推荐在子组件内修改通过prop传入的父组件的值,推荐使用vuex

Logo

前往低代码交流专区

更多推荐