实例演示
父组件
<template>
<div>
<Demo4 :number="1"></Demo4>
</div>
</template>
<script>
import Demo4 from './components/Demo4'
export default {
components: {
Demo4
}
}
</script>
子组件
<template>
<div>
<h1>{{ number }}</h1>
</div>
</template>
<script>
export default {
props: ['number'] // props 接受父组件传递过来的值
}
</script>
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样是为了防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
父组件传递给子组件的值,是存在与父组件的 data 中的,也就是说,父组件会将 data 中的值同时传递给多个子组件,那么多个子组件则是共享了父组件 data 中的值,因此如果子组件可以直接修改父组件传递过来的值,那么则会造成其他子组件的值发生变化,这样是不被允许的,因此 vue 使用单向数据流的方式来进行父向子传值,避免发生此种问题。
每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告,例如:
子组件
<template>
<div>
<h1 @click="handleClick">{{ number }}</h1>
</div>
</template>
<script>
export default {
props: ['number'],
methods: {
handleClick () {
this.number++
}
}
}
</script>
因为单向数据流的限制,我们虽然无法直接修改父组件传递到子组件的值,但是我们是可以通过间接的方式修改的,我们将父组件传递过来的值,重新赋值到子组件中的 data 里的一个变量即可实现数据的修改,例如:
<template>
<div>
<h1 @click="handleClick">{{ count }}</h1>
</div>
</template>
<script>
export default {
props: ['number'],
data () {
return {
count: 0
}
},
mounted () {
this.count = this.number
},
methods: {
handleClick () {
this.count++
}
}
}
</script>
还有一个需要注意的地方,就是如果父组件向子组件传递的一个对象数据,也就是引用传递的话,直接在子组件修改对象数据内的元素数据是没有问题,但是如果直接修改父组件传递给子组件的引用值则会触发警告,例如:
父组件:
<template>
<div>
<Demo4 :user="user"></Demo4>
</div>
</template>
<script>
import Demo4 from './components/Demo4'
export default {
data () {
return {
user: {
id: 1,
name: 'lanyulei'
}
}
},
components: {
Demo4
}
}
</script>
子组件:
<template>
<div>
<h1 @click="handleClick">{{ user.name }}</h1>
</div>
</template>
<script>
export default {
props: ['user'],
methods: {
handleClick () {
this.user.name = 'lanyulei1'
}
}
}
</script>
直接修改引用值的情况,则触发警告,如下:
handleClick () {
this.user = {id: 2, name: 'lanyulei2'}
}