记录一次因为vue2中 provide没有响应式导致的bug

203 阅读1分钟

provide & inject

常规模式下使用:

在这种模式下,一旦ParentView中的name改变,ChildView是无法进行更新的

// Parent
export default {
  name: 'ParentView',
  provide: {
    parentName: this.name
  },
  data () {
    return {
      name: '张三'
    }
  }
}
 // Child
export default {
  name: 'ChildView',
  inject: ['parentName'],
  data () {
    return {}
  }
}

利用箭头函数每次获取最新值

// Parent
export default {
  name: 'ParentView',
  provide () {
    parentName: () => this.name
  },
  data () {
    return {
      name: '张三'
    }
  }
}
 // Child
export default {
  name: 'ChildView',
  inject: ['parentName'],
  data () {
    return {}
  },
  mounted () {
    console.log(this.parentName())
  }
}

利用对象浅拷贝

这种情况下,ChildView可以直接修改provide的值(如果是引用对象修改,可能直接丢失上下文),不建议使用。

// Parent
export default {
  name: 'ParentView',
  provide () {
    parentName: this.nameObj
  },
  data () {
    return {
      nameObj: {
        name: '张三'
      }
    }
  }
}
 // Child
export default {
  name: 'ChildView',
  inject: {
    parentName: {
      default:()=>{}
    }
  },
  data () {
    return {}
  },
  mounted () {
    console.log(this.parentName.name)
  }
}

利用this其实跟上述原理一样。

这种情况下,整个组件实例对象会一直传递,不建议使用。

// Parent
export default {
  name: 'ParentView',
  provide () {
    parentInstance: this
  },
  data () {
    return {
      name: '张三'
    }
  }
}
 // Child
export default {
  name: 'ChildView',
  inject: ['parentInstance'],
  data () {
    return {}
  },
  mounted () {
    console.log(this.parentInstance.name)
  }
}