Вместо того, чтобы загрязнять ваш шаблон троичной логикой, вы должны вместо этого выполнить проверку внутри обработчика щелчков.Это не только делает ваш шаблон более читабельным, но и делает обслуживание кода более простым, поскольку вся логика вместо этого была абстрагирована и делегирована обратному вызову обработчика событий.
Быстрое решение
Поэтому быстрое решениечтобы фактически убедиться, что toggleSectionElements()
будет работать только при наличии правильного dataType
.Это может быть достигнуто с помощью защитного предложения:
toggleSectionElements() {
// Guard clause to prevent further code execution
if (this.dataType() !== 'section')
return;
// Magic here
}
Еще лучше то, что если для каждого dataType
должны быть назначены отдельные обработчики: вы можете создать фабричную функцию для этой цели:
methods: {
// This is just a factory function
toggleElements() {
switch (this.dataType()) {
case 'section':
return this.toggleSectionElements;
case 'element':
// Something else...
}
},
toggleSectionElements() {
// Magic for section element
}
}
Предложение: использование атомарных компонентов
Поскольку привязка обработчиков событий щелчка может быть дорогостоящей для элементов, которые в конечном итоге ничего не делают, вы также можете разбить компонент на более атомарный.Элемент коллекции будет отвечать за получение массива «section» или «element», и каждый «section» / «element» будет иметь свой собственный компонент, примерно такой:
- У вас естькомпонент коллекции, скажем,
<my-collection>
, который содержит все компоненты "section" и "element" - компонент "section" будет использовать
<my-section>
component - компонент "element" будет использовать
<my-element>
component
Это когда VueJS становится действительно мощным: вы можете использовать динамический компонент внутри <my-collection>
, чтобы определить, какой компонент использовать в зависимости от dataType
.
Это делается путем запуска v-for
через коллекцию, а затем с помощью v-bind:is="..."
, чтобы определить, должен ли определенный элемент коллекции использовать «section» или «element».Я понимаю, что это, вероятно, выйдет за рамки вашего первоначального вопроса, но стоит рассмотреть этот вариант:
const collectionComponent = Vue.component('my-collection', {
template: '#my-collection-component',
data: function() {
return {
collection: [{
dataType: 'section',
description: 'Hello I am section 1'
}, {
dataType: 'element',
description: 'Hello I am element 1'
}, {
dataType: 'section',
description: 'Hello I am section 2'
}, {
dataType: 'element',
description: 'Hello I am element 2'
}]
}
},
methods: {
componentToUse(dataType) {
return 'my-' + dataType;
}
}
});
const sectionComponent = Vue.component('my-section', {
template: '#my-section-component',
props: ['itemData'],
methods: {
toggle() {
console.log('Doing some magic.');
}
}
});
const elementComponent = Vue.component('my-element', {
template: '#my-element-component',
props: ['itemData']
});
new Vue({
el: '#app'
});
.box {
border: 1px solid #999;
cursor: pointer;
margin: 10px;
padding: 10px;
}
.box:hover {
background-color: #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<my-collection />
</div>
<script type="text/x-template" id="my-collection-component">
<div>
<component
v-for="(item, i) in collection"
v-bind:key="i"
v-bind:is="componentToUse(item.dataType)"
v-bind:itemData="item" />
</div>
</script>
<script type="text/x-template" id="my-section-component">
<div @click="toggle" class="box">
<h1>{{ itemData.dataType }}</h1>
<p>{{ itemData.description }}</p>
<p>Clicking on me will invoke a section-specific logic</p>
</div>
</script>
<script type="text/x-template" id="my-element-component">
<div class="box">
<h1>{{ itemData.dataType }}</h1>
<p>{{ itemData.description }}</p>
<p>Clicking on me will do nothing</p>
</div>
</script>