Emptyform
@Emptyform

Как избавиться от ошибки про мутацию при передаче значения в поле редактирования компоненты?

Передаю значение, которое выводится в Инпут, а по клику на кнопке передаю содержимое инпута вверх родителю.
Все бы хорошо, но в лог сыпятся предупреждения про мутацию:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "pname"

Попробовал прикрутить computed, не помогло. Видимо не так делаю.

Подскажите что тут не верно, плиз:
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <script src="https://unpkg.com/vue"></script>
</head>

<body>

<div id="app">
    <todo-add
        v-on:todo-new="addNewTodo"
        :pname="newTodoName"
    ></todo-add>
    <p><pre>{{todosObj}}</pre></p>
</div>

<script>
    Vue.component('todo-add', {
        props: ['pname'],
        template:
        `<ul>
            <input v-model="todoName" autofocus></input>
            <button v-on:click="add">Add New Todo</button>
        </ul>`,
        computed: {
            todoName: {
                set: function(val) {
                    this.pname = val;
                },
                get: function() {
                    return this.pname.trim();
                }
            }
        },
        methods: {
            add: function() {
                console.log(`emit: this.name = ${this.pname}`);
                this.$emit('todo-new', this.todoName);
            }
        }
    });

    var app = new Vue({
        el: "#app",
        data: {
            newTodoName: '',
            todoArr: [
                {id: 1, name: "aaaaaa"},
            ]
        },
        methods: {
            addNewTodo: function(name) {
                let newItem = {id: this.todoArr.length+1, name: name}
                this.todoArr.push(newItem);
                this.newTodoName = ''; // чистим поле ввода
            }
        },
        computed: {
            todosObj: function() {
                return JSON.stringify(this.todoArr, null, 4);
            }
        }
    });
</script>

</body>
</html>
  • Вопрос задан
  • 2516 просмотров
Пригласить эксперта
Ответы на вопрос 2
0xD34F
@0xD34F Куратор тега Vue.js
Очевидно, сделать pname вместо параметра свойством компонента.

UPD. Например.

<div id="app">
  <todo-add @todo-new="addNewTodo"></todo-add>
  <pre>{{ todoJson }}</pre>
</div>

Vue.component('todo-add', {
  template: `
<div>
  <input v-model="name" autofocus></input>
  <button @click="add">Add New Todo</button>
</div>`,
  data: () => ({
    name: '',
  }),
  methods: {
    add() {
      const name = this.name.trim();
      if (name) {
        this.$emit('todo-new', name);
        this.name = '';
      }
    },
  },
});

new Vue({
  el: '#app',
  data: {
    todoArr: [
      { id: 1, name: 'hello, world!!' },
    ],
  },
  methods: {
    addNewTodo(name) {
      this.todoArr.push({
        id: 1 + Math.max(0, ...this.todoArr.map(n => n.id)),
        name,
      });
    },
  },
  computed: {
    todoJson() {
      return JSON.stringify(this.todoArr, null, 2);
    },
  },
});

Ответ написан
@s_lukinin
Создайте свойство компонента со значением параметра https://vuejs.org/v2/guide/components-props.html#O...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы