Однонаправленный поток данных

Последнее обновление: 29.09.2017

При использовании props в компонентах следует учитывать, что данные в props представляют однонаправленный поток данных от родительского компонента к дочерним компонентам. Изменение свойства родителя приведет к изменению в дочерних компонентах. Однако дочерние компоненты не могут изменить свойство родителя. То есть поток данных идет только в одном направлении: родителя к потомкам. Кроме того, если мы попробуем изменить в дочерних компонентах значения, переданные через props, то на консоль браузера будет выведено предупреждение о том, что это не следует делать.

Более того при любом обновлении родительского компонента у дочерних компонентов обновляются значения, передаваемые через props. Например, рассмотрим следующую ситуацию:

<!DOCTYPE html>
<html>
<head>
<title>Компоненты Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
	<h2>Hello, {{name}}</h2>
    <useredit :user="name"></useredit>
	<button v-on:click="resetName">Set Name</button>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script>
Vue.component('useredit', {
	props: ["user"],
	template: '<div><input type="text" v-model="user" /><p>Name: {{user}}</p></div>'
});
new Vue({
    el: "#app",
    data: {
        name: 'Tom'
    },
	methods:{
		resetName: function(){
			this.name = 'Bob';
		}
	}
});
</script>
</body>
</html>

Из родителя - объекта Vue в компонент useredit через props передается значение name. В этом компоненте мы можем попробовать управлять переданным значением через поле ввода и механизм двусторонней привязки:

<input type="text" v-model="user" />

Но если мы попробуем изменить через поле ввода данное значение, то оно изменится только в рамках компонента useredit, а на консоль будет выведено предупреждение:

Mutating props in Vue.js

Значение свойства name в родительском объекте Vue никак не будет затронуто. Почему так происходит? Дело в том, что данные простых типов - String, Number, Boolean передаются по значению, то есть в дочерний компонент передается копия значения. И в данном случае в компонент useredit как раз передается копия строки name. Соответственно все действия с этой копией никак не повлияют на родительский объект.

В отличие от простых типов сложные объекты и массивы передаются по ссылке. Поэтому из дочерних компонентов мы можем изменять массивы или сложные объекты, которые определены в родительских объектах.

Более того в объекте Vue посредством нажатия кнопки мы можем вызвать метод resetName, который изменит свойство name с Tom на Bob:

Mutating props in components in Vue.js

То есть несмотря на то, что внутри компонента useredit мы меняем значение из props, но изменение родителя - объекта Vue приведет к изменению дочернего компонента.

Однако могут быть ситуации, когда нам все таки нужно изменить значения в props и при этом не допустить изменения этих значений извне. Что делать в этом случае? В этом случае мы можем определить локальную переменную. Через props устанавливается ее начальное значение, и затем компонент работает только с этой переменной:

<div id="app">
	<h2>Hello, {{name}}</h2>
    <useredit :user="name"></useredit>
	<button v-on:click="resetName">Set Name</button>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script>
Vue.component('useredit', {
	props: ["user"],
	data: function () {
	  return { userName: this.user}
	},
	template: '<div><input type="text" v-model="userName" /><p>Name: {{userName}}</p></div>'
});
new Vue({
    el: "#app",
    data: {
        name: 'Tom'
    },
	methods:{
		resetName: function(){
			this.name = 'Bob';
		}
	}
});
</script>

Теперь все действия будут идти с локальной переменной userName. Значения из props в компоненте не будут изменяться, а изменения в родительском компоненте никак не повлияют на значение переменной userName.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850