#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 вызовет ошибку, если он будет вызван в дочернем компоненте.