#typescript #vue.js #inheritance #vuejs2 #vue-component
Вопрос:
У меня есть два несвязанных компонента контекста, которые разделяют логику и шаблон таким образом, что кажется, что один расширяет другой.
Представьте, что вы бросаете и выбираете такие компоненты, как этот:
// pick.js import Vue from 'vue' import Component from 'vue-class-component' @Component export default class Pick extends Vue { template: 'lt;pgt;{{name}}lt;/pgt;', created() { console.log('Hello Pick'); } data: { name: 'pick', count: 0 }, methods: { add: function () { this.count ; } } } // drop.js import Vue from 'vue' import Component from 'vue-class-component' @Component export default class Drop extends Vue { template: 'lt;pgt;{{name}}lt;/pgt; lt;span v-if="isUserFriendly"gt;Greetings!!!lt;/spangt;', created() { console.log('Hello Drop'); } data: { name: 'drop', isUserFriendly: false, count: 0, drops: 0 }, methods: { add: function () { this.count ; this.drops ; }, remove: function () { this.count--; }, } }
Интуитивно можно сказать, что Drop расширяет выбор, добавляя некоторые функции и изменяя шаблон. Это кажется хорошим решением, но потом я подумал про себя, что для достижения этого шаблон выбора должен выглядеть так:
lt;pgt;{{name}}lt;/pgt; lt;span v-if="isUserFriendly"gt;Greetings!!!lt;/spangt;
Помните, я говорил о несвязанных компонентах контекста? Теперь Pick должен знать о дружественных отношениях с пользователями, что неприемлемо, и я не думаю, что это правильное решение. Более того, это создаст накладные расходы в будущем, поскольку наследование может быть трудно поддерживать (представьте, что нужно расширить больше компонентов и поделиться логикой).
Как вы думаете, какой подход здесь будет наилучшим? Может быть, есть другой способ, с которым я не знаком?
Спасибо за помощь!
Ответ №1:
Компонентный состав-распространенный способ сделать это. Компонент Drop содержит надмножество функций, т. е. компонент pick должен быть обернут таким образом, чтобы обеспечить желаемый результат и поведение.
Для отношений «родитель-потомок» фрагменты данных передаются в виде реквизитов и событий, а фрагменты представления передаются в виде слотов.
Дополнительная логика остается в родительском компоненте.
В дочернем компоненте ( Pick
):
lt;divgt; lt;pgt;{{name}}lt;/pgt; lt;slot name="extraText"/gt; lt;/divgt;
и
add: function () { this.count ; this.$emit('add'); }
В родительском компоненте ( Drop
):
lt;Pick @add="drops "gt; lt;template v-slot:extraTextgt; lt;spangt;Greetings!!!lt;/spangt; lt;/templategt; lt;/Pickgt;
Комментарии:
1. Мне очень нравится такой подход! Что делать, если add() будет совершенно другим, так как DROP содержит другую реализацию add (), которая не связана с реализацией Pick. Я не хочу, чтобы, например, сейчас вызывался этот.count
2. Тогда, вероятно, дочерний компонент должен быть более простой реализацией, как выбор, так и удаление расширят его функциональность.