Избегайте мутирования prop напрямую, поскольку значение будет перезаписано
У меня очень распространенная проблема с обновлением до Vue 2.0
Я получаю предупреждение:
Избегайте прямого изменения свойства, так как значение будет перезаписываться при каждом повторном рендеринге родительского компонента. Вместо этого используйте данные или вычисляемое свойство на основе значения проп. Подставка изменена: "имя пользователя" (находится в компоненте)
Я прочитал документацию много раз, но до сих пор не могу понять, как это исправить.
username
и password
объявляются в основном приложении Vue.
Вот мой код:
var GuestMenu = Vue.extend({
props : ['username', 'password'],
template: '
<div id="auth">
<form class="form-inline pull-right">
<div class="form-group">
<label class="sr-only" for="UserName">User name</label>
<input type="username" v-model="username" class="form-control" id="UserName" placeholder="username">
</div>
<div class="form-group">
<label class="sr-only" for="Password">Password</label>
<input type="password" v-model="password" class="form-control" id="Password" placeholder="Password">
</div>
</form>
</div>',
});
App = new Vue ({
el: '#app',
data:
{
topMenuView: "guestmenu",
contentView: "guestcontent",
username: "",
password: "",
}
})
Я пробовал v-bind
но, похоже, он не работает, и я не могу понять, почему. Это должно привязать значение к родителю (основное приложение Vue)
Ответы
Ответ 1
Начиная с Vue 2.3.0 вы можете использовать модификатор .sync
:
Пример из https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier:
<text-document :title.sync="title"></text-document>
и в вашем контроллере...
this.$emit('update:title', newTitle)
Ответ 2
Vue.js рассматривает это как анти-шаблон. Например, объявление и установка некоторых реквизитов, таких как
this.propsVal = 'new Props Value'
Итак, чтобы решить эту проблему, вам нужно взять значение из реквизита в данные или вычислить свойство экземпляра Vue. как...
props: ['propsVal'],
data: function() {
return {
propVal: this.propsVal
};
},
methods: {
...
}
и вы можете использовать свой реквизит, как обычно.
Ответ 3
Вы должны создать вычисляемое свойство с помощью метода get и set, а затем использовать $emit
для обновления свойства, например:
var GuestMenu = Vue.extend({
props: ['username', 'password'],
template: '
<div id="auth">
<form class="form-inline pull-right">
<div class="form-group">
<label class="sr-only" for="UserName">User name</label>
<input type="username" v-model="usernameInput" class="form-control" id="UserName" placeholder="username">
</div>
<div class="form-group">
<label class="sr-only" for="Password">Password</label>
<input type="password" v-model="passwordInput" class="form-control" id="Password" placeholder="Password">
</div>
</form>
</div>',
computed: {
usernameInput: {
get: function(){
return this.username;
},
set: function(newValue){
this.$emit('update:username', newValue)
}
},
passwordInput: {
get: function(){
return this.password;
},
set: function(newValue){
this.$emit('update:password', newValue)
}
},
}
});
Ответ 4
Я не уверен, чего именно вы хотите достичь, но я возьму из этого два варианта.
Первый: все дело в том, чтобы избавиться от этого предупреждения.
data () {
return {
childVal: this.parentVal
}
}
Второй: вы хотите общаться между родителем и ребенком.
Если я правильно понял, это базовый пример <input>
в дочернем компоненте, взаимодействующем с его родителем.
Родительский HTML:
<p>{{ user }}</p>
<child-component v-model="user">
Родитель JS:
data () {
return {
user: 'John'
}
}
Дочерний HTML:
<input v-bind:value="value" @input="$emit('input', $event.target.value)">
Детский JS:
props: ['value']
Рабочий пример: http://jsfiddle.net/kf3aLr1u/
Вы также можете узнать больше об этом в документации https://vuejs.org/v2/guide/components.html.
Ответ 5
computed
свойство с соответствующим get
и set
сработало для меня:
computed: {
dialogDataProp: {
get: function() {
return this.dialog;
},
set: function() {}
}
}
Код выше для переключения диалогового окна.
Ответ 6
Когда вы используете v-bind
, свойство связывается с использованием двух направлений, поэтому вы получаете предупреждение.
Если вам нужно передать начальное имя пользователя из родительского компонента Vue, вы можете использовать v-bind
с другим свойством data, таким как _username
, и скопировать исходное значение из свойства во внутренние данные при создании компонента:
props : ['username', 'password'],
data () {
return {
_username: this.username,
_password: this.password
}
}
Изменить: вы можете также использовать $watch для обновления данных компонента _username/_password при изменении свойств.
Ответ 7
если вы хотите мутировать реквизит - используйте объект.
<component :user="global.user"></component>
компонент:
props: ['user'],
methods: {
setUser: function() {
this.user.username= "User";
this.user.password= "myPass123";
}
}