Избегайте мутирования 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)

Ответ 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";
      }
    }