关于props单向绑定,不太理解

我看官方文档中这么说,红标的地方,上面和下面我该相信哪段话呢?是否自相矛盾呢?

这两段话是不冲突的, props 数据流是单向的, 从父组件流向子组件,而子组件是不能通过 props 更新父组件的。JavaScript 中的基本类型完全符合上述单向数据流。 但是, 对于 JavaScript 中的引用类型, 因为父子组件引用的是同一个数据,当子组件修改数据以后, 会自然影响到父组件中的数据。所以, 如果想要断开这种引用关系, 可以在子组件中做一层深度复制, 这样引用就会断开。

表述的不是很好,希望对你有所帮助

好的呢,谢谢你的热心答复~

不冲突。单向数据流是 Vue 的逻辑概念,而对象引用是 JS 语言的物理概念

在这个问题上,你要区分两个概念对象:属性和状态。当属性引用了一个状态(而不是字面量)时,属性是子组件的,状态是父组件的。比如 <my-friend :name="fullName">name 是子组件 MyFriend 的属性,fullName 则是父组件的状态。

单向数据流的意思是,你不能且不应该在子组件中修改父组件的状态:

/* 父组件 */
this.fullName = 'Foo Bar' // OK
/* 子组件 */
this.props.name = 'Foo Quux' // BAD

当你这么做时 Vue 会发出警告。

但是,如果状态值是一个 JS 对象,Vue 不会警告你:

/* 父组件 */
const someone = {first: 'Foo', last: 'Bar'}
this.fullName = someone
/* 子组件 */
const elseone = this.props.name
elseone.last = 'Quux'
this.props.name = elseone

因为,在 Vue 看来,name 这个属性的值并没有发生变化,依然是 someone 引用的那个对象。elseone 复制了那个对象的引用,并没有改变引用本身,所以 Vue 无法识别出你在修改父组件的状态。

这么做实际上破坏了单向数据流的设计,只是由于 JS 的语言限制无法有效检测和阻止这个行为。第二个红框就是提醒你注意这个问题。

嗯,理解了。谢谢大佬

vue的父子组件数据流向就是这样,父级向子级传递数据,子级通过事件改变父级;
js,对象,vue监听不到内部变化。

这个和js的数据类型的处理方式有关系。

js 数据类型分为两大类,一个是基础类型,比如number、string、bool等;一个是引用类型,比如对象、数组等。

基础类型是传值的,引用类型是传递地址的。

vue对于props可否修改的限制,只能限制基础类型,无法限制引用类型。

这个是传值和传地址的本质问题,vue也无奈。

一般的属性都是单层的,然后你可以设置一个多层的属性试一试。


props:{
  name: '测试',
  blog: {
    title: '',
    dt: ''
  },
  list: []
}

这种结构的 props,然后你尝试修改一下各个属性,再看看父组件里面的对象的变化。