[Vue warn]: свойство или метод не определены в экземпляре, но используются во время рендеринга.

95
var MainTable = Vue.extend({
  template: "<ul>" +
    "<li v-for='(set,index) in settings'>" +
    "{{index}}) " +
    "{{set.title}}" +
    "<button @click='changeSetting(index)'> Info </button>" +
    "</li>" +
    "</ul>",
  data: function() {
    return data;
  }
});

Vue.component("main-table", MainTable);

data.settingsSelected = {};
var app = new Vue({
  el: "#settings",
  data: data,
  methods: {
    changeSetting: function(index) {
      data.settingsSelected = data.settings[index];
    }
  }
});

В приведенном выше коде ошибка ниже возникает при нажатии кнопки.

[Vue warn]: свойство или метод changeSetting не определены в экземпляре, но используются во время рендеринга. Обязательно объявите реактивные свойства данных в параметре данных. (найдено в <MainTable>)

Лоренцо Д'Исидоро
источник
У вашего компонента нет доступа к методам, определенным в вашем Vue. Вам нужно добавить метод changeSettingв MainTableкомпонент.
Берт

Ответы:

95

Проблема

[Vue warn]: Property or method "changeSetting" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in <MainTable>)

Ошибка возникает из-за changeSettingссылки на метод в MainTableкомпоненте здесь:

    "<button @click='changeSetting(index)'> Info </button>" +

Однако changeSettingметод не определен в MainTableкомпоненте. Он определяется здесь в корневом компоненте:

var app = new Vue({
  el: "#settings",
  data: data,
  methods: {
    changeSetting: function(index) {
      data.settingsSelected = data.settings[index];
    }
  }
});

Следует помнить, что на свойства и методы можно ссылаться только в той области, в которой они определены.

Все в родительском шаблоне компилируется в родительской области; все в дочернем шаблоне компилируется в дочерней области.

Вы можете узнать больше о масштабах компиляции компонентов в документации Vue .

Что я могу с этим поделать?

До сих пор было много разговоров об определении вещей в правильной области, поэтому исправление состоит в том, чтобы просто переместить changeSettingопределение в MainTableкомпонент?

Это кажется таким простым, но вот что я рекомендую.

Вы, вероятно, захотите, чтобы ваш MainTableкомпонент был тупым / презентационным компонентом. ( Вот что можно прочитать, если вы не знаете, что это, но tl; dr заключается в том, что компонент просто отвечает за рендеринг чего-либо - никакой логики). За логику отвечает элемент smart / container - в примере, приведенном в вашем вопросе, корневым компонентом будет компонент smart / container. С этой архитектурой вы можете использовать методы связи родитель-потомок Vue для взаимодействия компонентов. Вы передаете данные для свойстваMainTable via и отправляете действия пользователя из родительского объекта через события . Это может выглядеть примерно так:MainTable

Vue.component('main-table', {
  template: "<ul>" +
    "<li v-for='(set, index) in settings'>" +
    "{{index}}) " +
    "{{set.title}}" +
    "<button @click='changeSetting(index)'> Info </button>" +
    "</li>" +
    "</ul>",
  props: ['settings'],
  methods: {
    changeSetting(value) {
      this.$emit('change', value);
    },
  },
});


var app = new Vue({
  el: '#settings',
  template: '<main-table :settings="data.settings" @change="changeSetting"></main-table>',
  data: data,
  methods: {
    changeSetting(value) {
      // Handle changeSetting
    },
  },
}),

Вышеупомянутого должно быть достаточно, чтобы дать вам хорошее представление о том, что делать, и начать решение вашей проблемы.

Крыло
источник
3
На данный момент это наиболее предпочтительный подход? Вещи во Vue постоянно развиваются, поэтому я хотел бы спросить
Aseem
18

Если кто-то столкнется с той же глупой проблемой, что и я, убедитесь, что у вашего компонента правильно написано свойство data . (например, данные , а не дата )

<template>
    <span>{{name}}</span>
</template>

<script>
export default {
  name: "MyComponent",
  data() {
    return {
      name: ""
    };
  }
</script>
tno2007
источник
1
братан серьезно, я имею в виду серьезно Спасибо
Нони
2
Я здесь, в 2020 году, написал ДАТА
Пааксинг
lmfao этот комментарий только что спас меня
Крис Раваццано
Такая же ошибка возникает при неправильном написании имен свойств. Для меня это произошло потому, что я использовал множественное число datasв шаблоне.
Тотимедли
8

В моем случае причина была в том, что я забыл только закрытие

</script>

тег.

Но это вызвало то же сообщение об ошибке.

Франкфурт-Ларавель
источник
4

Вероятно, это вызвано орфографической ошибкой

Опечатка в закрывающем теге скрипта

</sscript>
нагрудники
источник
3

Если вы дважды используете vue instance. Тогда он выдаст вам эту ошибку. Например, в app.js и вашем собственном теге скрипта в файле просмотра. Просто используйте один раз

 const app = new Vue({
    el: '#app',
});
Хамза Хан
источник
2

Добавлю и свой бит, если кто-то будет бороться, как я, обратите внимание, что методы - это слово с учетом регистра:

<template>
    <span>{{name}}</span>
</template>

<script>
export default {
  name: "MyComponent",
  Methods: {
      name() {return '';}
  }
</script>

"Методы" должны быть "методами"

Даниэль Кац
источник
2

Скорее всего, это орфографическая ошибка зарезервированных переменных vuejs. Я попал сюда, потому что написал с ошибкой, computed:и vuejs не распознал мои вычисляемые переменные свойств. Так что, если у вас есть такая ошибка, сначала проверьте правописание!

махатманих
источник
2

Я получил эту ошибку, когда попытался назначить свойство компонента свойству состояния во время создания экземпляра.

export default {
 props: ['value1'],
 data() {
  return {
   value2: this.value1 // throws the error
   }
  }, 
 created(){
  this.value2 = this.value1 // safe
 }
}
Я хочу ответы
источник
2

У меня было два methods:в <script>, идет , чтобы показать, что вы можете потратить часы , глядя на то , что было такой простой ошибкой.

Learncodes123
источник
2

Моя проблема заключалась в том, что я размещал методы внутри своего объекта данных. просто отформатируйте его вот так, и все будет хорошо.

<script>
module.exports = {
    data: () => {
        return {
            name: ""
        }
    },
    methods: {
        myFunc() {
            // code
        }
    }
}
</script>
Pwntastic
источник
2

Если вы столкнулись с этой проблемой, убедитесь, что у вас нет

methods: {
...
}

или

computed: {
...
}

объявлен дважды

Чукс-младший
источник
1

В моем случае это было свойство, которое дало мне ошибку, правильное письмо и все же выдало мне ошибку в консоли. Я так много искал, и у меня ничего не работало, пока я не дал ему Ctrl + F5 и Voilá! ошибка была удалена. : 'v

Дженнифер Миранда Беус
источник