Vue js: Как использовать функцию смешивания в двух компонентах? По Ошибке выполнения

#javascript #vue.js #components #mixins

Вопрос:

У меня есть 2 компонента: родительский и дочерний и один миксин. Я пытаюсь использовать одну функцию в обоих из них. Вызовите функцию mixin из дочернего компонента, который находится в родительском компоненте. Эта функция mixin также изменяет var данных родительского компонента, на который в дочернем элементе ссылаются в реквизитах.

Однако в этой строке кода:

 this.modals.filter = 'block'; occurs error: TypeError: Cannot set properties of undefined (setting 'filter')  

Я не могу понять, почему, поскольку modals.filter уже упоминается в реквизитах?

 lt;!DOCTYPE htmlgt; lt;html lang="en"gt;  lt;headgt;  lt;meta charset="UTF-8" /gt;  lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /gt;  lt;titlegt;Testlt;/titlegt;  lt;script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"gt;lt;/scriptgt;  lt;/headgt;  lt;bodygt;  lt;div id="example" style="width:100%;height:100%"gt;  lt;parentgt;lt;/parentgt;  lt;/divgt;  lt;/bodygt;  lt;scriptgt;  var myMixin = {   methods: {  powerbiFilterModal: function() {  this.modals.filter = 'block';  if (this.embed.channelName, this.filters.columnName, this.filters.tableName) {  // Some other functions  // ...  console.log(this.embed.channelName, this.filters.columnName, this.filters.tableName);  // Hide modal  this.modals.filter = 'none';  // Clear inputs  this.embed.channelName = '';  this.filters.columnName = '';  this.filters.tableName = '';  }  }  }  };  Vue.component('child', {  mixins: [myMixin],  template: `  lt;div :style="{ display: filterOverlay }"gt;  lt;span class="close" style="align-self: flex-end; cursor: pointer;" @click="closeModal"gt;xlt;/spangt;  lt;span class="label" style="align-self: center; margin-bottom: 4%"gt;Filter Settings: lt;/spangt;  lt;input type="text" placeholder="Define channel name" v-model.trim="channelName"gt;  lt;input type="text" placeholder="Define filter name" v-model.trim="columnName"gt;  lt;input type="text" placeholder="Define table to filter" v-model.trim="tableName"gt;  lt;button @click="powerbiFilterModal"gt;Subscribe amp; Sendlt;/buttongt;  lt;/divgt;  `,  props: {  filterOverlay: {  type: String,  required: false,  default: 'none'  },  channelName: {  type: String,  required: false  },  columnName: {  type: String,  required: false  },  tableName: {  type: String,  required: false  }   },  methods: {  closeModal: function() {  this.$emit('emitEv', 'none');  }  }  });    Vue.component('parent', {  mixins: [myMixin],  template: `  lt;divgt;  lt;button @click="powerbiFilterModal"gt;Set Filterslt;/buttongt;  lt;child @emitEv="changeOverlay" v-bind:filter-overlay="modals.filter"gt;Childlt;/childgt;  lt;/divgt;  `,  data: function() {  return {  modals: {  filter: 'none'  },  embed: {  channelName: ''  },  filters: {  columnName: '',  tableName: ''  }  }  },  methods: {  changeOverlay: function(value) {  this.modals.filter = value;  }  }  });  new Vue({  el: "#example"  });  lt;/scriptgt; lt;/htmlgt;  

Комментарии:

1. В ребенке this.modals не определено

2. Довольно странно использовать одно и то же сочетание в дочернем и родительском компонентах одновременно, вместо этого вы могли бы вызвать событие нажатия кнопки из дочернего компонента, а затем в родительском вызове powerbiFilterModal

3. @Radeanu не могли бы вы добавить, как это может быть реализовано? Я проверил с помощью emit click, но как функция может быть запущена с помощью такого события?

Ответ №1:

Поясняю свой комментарий

Дочерний компонент

 Vue.component("child", {  // mixins: [myMixin], remove mixin from child  template: `  lt;divgt;  lt;!-- bla bla bla --gt;  lt;button @click="$emit('fire')"gt;Subscribe amp; Sendlt;/buttongt;  lt;/divgt;  ...  ` });  

Родительский компонент

 Vue.component("parent", {  mixins: [myMixin],  template: `  lt;divgt;  lt;button @click="powerbiFilterModal"gt;Set Filterslt;/buttongt;   lt;!-- HERE we listen for event (fire) from child and call powerbiFilterModal method from mixin --gt;  lt;child @fire="powerbiFilterModal" @emitEv="changeOverlay" v-bind:filter-overlay="modals.filter"gt;Childlt;/childgt;  lt;/divgt;  `,  data: function () {  return {  modals: {  filter: "none"  },  embed: {  channelName: ""  },  filters: {  columnName: "",  tableName: ""  }  };  },  methods: {  changeOverlay: function (value) {  this.modals.filter = value;  }  } });  

Ответ №2:

powerbiFilterModal() является ссылкой this.modals , что нормально, если она используется в родительском компоненте, но у дочернего компонента таких данных нет, поэтому mixin вызовет ошибку, если он будет вызван в дочернем компоненте.