You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// src/core/instance/state.js 源码路径functioninitProps(vm: Component,propsOptions: Object){constpropsData=vm.$options.propsData||{}constprops=vm._props={}// cache prop keys so that future props updates can iterate using Array// instead of dynamic object key enumeration.constkeys=vm.$options._propKeys=[]constisRoot=!vm.$parent// root instance props should be convertedif(!isRoot){toggleObserving(false)}for(constkeyinpropsOptions){keys.push(key)constvalue=validateProp(key,propsOptions,propsData,vm)/* istanbul ignore else */if(process.env.NODE_ENV!=='production'){consthyphenatedKey=hyphenate(key)if(isReservedAttribute(hyphenatedKey)||config.isReservedAttr(hyphenatedKey)){warn(`"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`,vm)}defineReactive(props,key,value,()=>{if(!isRoot&&!isUpdatingChildComponent){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: "${key}"`,vm)}})}else{defineReactive(props,key,value)}// static props are already proxied on the component's prototype// during Vue.extend(). We only need to proxy props defined at// instantiation here.if(!(keyinvm)){proxy(vm,`_props`,key)}}toggleObserving(true)}// src/core/observer/index.js/** * Define a reactive property on an Object. */exportfunctiondefineReactive(obj: Object,key: string,val: any,customSetter?: ?Function,shallow?: boolean){constdep=newDep()constproperty=Object.getOwnPropertyDescriptor(obj,key)if(property&&property.configurable===false){return}// cater for pre-defined getter/settersconstgetter=property&&property.getconstsetter=property&&property.setif((!getter||setter)&&arguments.length===2){val=obj[key]}letchildOb=!shallow&&observe(val)Object.defineProperty(obj,key,{enumerable: true,configurable: true,get: functionreactiveGetter(){constvalue=getter ? getter.call(obj) : valif(Dep.target){dep.depend()if(childOb){childOb.dep.depend()if(Array.isArray(value)){dependArray(value)}}}returnvalue},set: functionreactiveSetter(newVal){constvalue=getter ? getter.call(obj) : val/* eslint-disable no-self-compare */if(newVal===value||(newVal!==newVal&&value!==value)){return}/* eslint-enable no-self-compare */if(process.env.NODE_ENV!=='production'&&customSetter){customSetter()}// #7981: for accessor properties without setterif(getter&&!setter)returnif(setter){setter.call(obj,newVal)}else{val=newVal}childOb=!shallow&&observe(newVal)dep.notify()}})}
为何不能修改:为了保证数据的单向流动,便于对数据进行追踪,避免数据混乱。官网有详细的信息 prop
vue如何知道修改了父组件传来的props?
下面的代码就是实现Vue提示修改props的操作,在组件
initProps
方法的时候,会对props进行defineReactive操作,传入的第四个参数是自定义的set函数,该函数会在触发props的set方法时执行,当props修改了,就会运行这里传入的第四个参数,然后进行判断,如果不是root根组件,并且不是更新子组件,那么说明更新的是props,所以会警告如果传入的props是基本数据类型,子组件修改父组件传的props会警告,并且修改不成功,如果传入的是引用数据类型,那么修改改引用数据类型的某个属性值时,对应的props也会修改,并且vue不会抱警告。
The text was updated successfully, but these errors were encountered: