Vue.js Fluxo de Dados Unidirecional
No Vue.js, os dados fluem em uma única direção, do componente pai para os componentes filhos, por meio de props
props
props
Se um componente filho tentar alterar diretamente um valor recebido por props
No exemplo abaixo, um valor é passado do componente pai para o filho, que tenta modificá-lo por meio de um campo de entrada:
<!DOCTYPE html>
<html>
<head>
<title>Componentes Vue.js</title>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<h2>Hello, {{ name }}</h2>
<user-edit :user="name"></user-edit>
</div>
<script>
const app = Vue.createApp({
data() {
return { name: 'Tom' };
}
});
app.component('user-edit', {
props: ["user"],
template: '<div><input type="text" v-model="user" /><p>Name: {{ user }}</p></div>'
});
app.mount('#app');
</script>
</body>
</html>
O componente user-edit
name
props
v-model
props
O componente user-edit
name
props
v-model
props

Se for necessário permitir que o componente filho modifique o valor recebido por props
data()
props
<!DOCTYPE html>
<html>
<head>
<title>Componentes Vue.js</title>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<h2>Hello, {{ name }}</h2>
<user-edit :user="name"></user-edit>
</div>
<script>
const app = Vue.createApp({
data() {
return { name: 'Tom' };
}
});
app.component('user-edit', {
props: ["user"],
data() {
return { userName: this.user };
},
template: '<div><input type="text" v-model="userName" /><p>Name: {{ userName }}</p></div>'
});
app.mount('#app');
</script>
</body>
</html>
Agora, todas as modificações feitas no campo de entrada afetam apenas a variável userName
user-edit
props

Sincronizando Valores Entre Pai e Filho
A abordagem acima resolve o problema de tentar alterar diretamente uma prop em um componente filho. No entanto, ela apresenta um problema: se o valor da prop user
userName
Se for necessário manter os valores sincronizados quando o componente pai atualiza uma prop, a melhor abordagem é usar um watcher (watch
props
<!DOCTYPE html>
<html>
<head>
<title>Componentes Vue.js</title>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<div>
<h3>Vue App</h3>
<input type="text" v-model="name" />
<p>Hello, {{ name }}</p>
</div>
<user-edit :user="name"></user-edit>
</div>
<script>
const app = Vue.createApp({
data() {
return { name: 'Tom' };
}
});
app.component('user-edit', {
props: ["user"],
data() {
return { userName: this.user };
},
watch: {
user(newVal) {
this.userName = newVal;
}
},
template: '<div><h3>Component</h3><input type="text" v-model="userName" /><p>User name: {{ userName }}</p></div>'
});
app.mount('#app');
</script>
</body>
</html>
O watch
user
userName
