甜点

文章 评论 浏览 28

甜点 2022-05-04 13:57:00

说子组件不可以修改父组件传递的props是不够严谨的,我们在用this[key]来修改props的时候,完全可以改变该组件的vm._props,只是父组件传递的数据源是不会改变的,保证了数据源的唯一性。
原因就是要看vue源码中对props初始化的函数iniProps上。

 function initProps (vm: Component, propsOptions: Object) {
   //获取父组件传入的props对象。
   const propsData = vm.$options.propsData || {}
   /*这里没有用 defineReactive 函数直接处理 propsDatas, 而是用一个新变量来接受props来接受 
  defineReactive的处理 */
  const props = vm._props = {}
  const keys = vm.$options._propKeys = []
  const isRoot = !vm.$parent
  
  if (!isRoot) {
    toggleObserving(false)
  }
  for (const key in propsOptions) {
    keys.push(key)
    const value = validateProp(key, propsOptions, propsData, vm)
   
    if (process.env.NODE_ENV !== 'production') {
      const hyphenatedKey = 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)
    }
  
    if (!(key in vm)) {
      /*把_props的属性经过属性代理 ,方便我们可以用 this[key] 直接访问 vm下边的_props 里边的属性*/
      proxy(vm, `_props`, key)
    }

综上,也就是说我们在用 this[key] = newVal来改变组件中的props的时候,实际改变的是vm下边的_props, 而由父组件传来的propsOptions并没有发生改变,这里应该注意的是当this._props[key]是基础数据类型的时候,this._props[key] 就是 propsData[key] 的拷贝值,当this._props[key]为引用类型的时候,this._props[key] 和 propsData[key] 指向的是同一个栈内存,**也就是说我们修改this._props[key]下的属性时候, propsData[key]也发生了改变,也就是父元素的数据发生了改变
那么如果修改了,Vue是怎么监控的呢,就是要看defineReactive函数

第 40 题:在 Vue 中,子组件为何不可以修改父组件传递的 Prop,如果修改了,Vue 是如何监控到属性的修改并给出警告的

甜点 2022-05-04 13:55:51

'变蓝变红变绿变蓝变'.match(/(变蓝)|((?!变蓝).)+/g)

第 90 题:实现模糊搜索结果的关键词高亮显示

甜点 2022-05-04 13:38:18

@NewNewKing 非常感谢指出~ 确实是写错了

JavaScript 专题之类型判断(下)

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文