v-on 클릭, 조건이 충족된 경우에만 핸들러 추가
에반 씨의 조사 결과, 다음과 같은 제안이 발견되었습니다.https://github.com/vuejs/vue/issues/7349#issuecomment-354937350
그래서 망설임 없이 시도해 보았다.
컴포넌트 템플릿
<template>
<div v-on='{ click: dataType === `section` ? toggleSectionElements : null }'>
... magic
</div>
<template>
JS 로직
<script>
export default {
name: `product-section`,
props: [`section`, `sectionName`, `depth`],
methods: {
toggleSectionElements() {
... magic
}
},
computed: {
dataType() {
if (this.$props.section.sections || this.$props.depth === 0) {
return `section`
} else {
return `element`
}
}
}
}
</script>
그러나 설명된 경우 렌더링 중 오류가 발생합니다.
[Vue warn]: Invalid handler for event "click": got null
어떤 잘못을 했는지 누가 좀 제안해 주시겠어요?: 생각:
갱신하다
그 길Data Model
외관:
DataModel: {
mainSectionA: {
sections: {
sectionA: {
sections: {
elementA: { values: { ... } },
elementB: { values: { ... } }
}
values: { ... }
}
sectionB: {
elementA: { values: { ... } },
elementB: { values: { ... } }
}
},
values: { ... }
},
mainSectionB: {
sections: {
elementA: { values: { ... } },
elementB: { values: { ... } },
elementC: { values: { ... } },
... elements
},
values: { ... }
}
}
템플릿을 3차 논리로 오염시키는 대신 클릭 핸들러 내부에서 실제로 검사를 수행해야 합니다.템플릿의 가독성을 높일 뿐만 아니라 모든 로직이 추상화되어 이벤트 핸들러의 콜백에 위임되므로 코드를 쉽게 유지할 수 있습니다.
신속한 해결
따라서 빠른 해결책은 실제로 다음 사항을 확인하는 것입니다.toggleSectionElements()
올바른 경우에만 기능합니다.dataType
존재합니다.이는 guard 절을 사용하여 수행할 수 있습니다.
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
}
}
권장사항: 원자성분 사용
클릭 이벤트핸들러를 아무것도 하지 않는 요소에 바인드 하는 것은 비용이 많이 들기 때문에 컴포넌트를 분해하여 보다 원자적으로 만들 수도 있습니다.수집 요소는 "섹션" 또는 "요소"의 배열을 수신하는 역할을 하며, 각 "섹션"/"요소"는 다음과 같은 자체 구성요소를 가집니다.
- 수집 컴포넌트가 있습니다.
<my-collection>
모든 "섹션" 및 "섹션" 컴포넌트를 수용합니다. - "섹션" 컴포넌트는
<my-section>
요소 - "component" 컴포넌트는
<my-element>
요소
이때 VueJ가 매우 강력해집니다.내부에서는 다이내믹 컴포넌트를 사용할 수 있습니다.<my-collection>
사용할 컴포넌트를 결정합니다.dataType
맞닥뜨린.
이 조작은, 를 실행하는 것으로 행해집니다.v-for
수집을 통해, 그리고 나서v-bind:is="..."
특정 수집 항목이 "섹션" 또는 "섹션"을 사용해야 하는지 여부를 결정합니다.이 질문은 당초 질문의 범위를 벗어나는 것으로 생각됩니다만, 다음 사항을 고려해 보는 것이 좋습니다.
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>
아래와 같이 변경하기만 하면 동작합니다.
v-on="condition ? { mouseover: handler } : {}"
또는 핸들러가 마우스 오버라고 불리는 경우
v-on="condition ? { mouseover } : {}"
여기:
click: dataType === `section` ? toggleSectionElements : null
그렇지 않은 경우 null을 통과하지만 클릭 시 값은 함수를 예상합니다.비우기 함수를 시도할 수 있습니다.
click: dataType === `section` ? toggleSectionElements : ()=>{}
에서는 Vue 3을 통과할 수 .null
듣는 사람에게.이것을 옵션의 체인과 조합하면, 다음과 같이 할 수 있습니다.
@click="handler?.() || null"
이전 브라우저에서도 동일:
@click="handler ? handler() : null"
언급URL : https://stackoverflow.com/questions/54839618/v-on-click-add-handler-only-if-condition-has-been-met
'programing' 카테고리의 다른 글
node.js를 사용하여 콜백이 호출될 때까지 함수를 대기시키는 방법 (0) | 2022.09.08 |
---|---|
요구 방지필요한 스크립트 캐싱의 JS (0) | 2022.09.08 |
빈 테이블 'Primary' 키에 대해 '1' 항목이 중복됩니다. (0) | 2022.09.08 |
Vuex는 키를 사용하여 상태의 개체에 액세스합니다. (0) | 2022.09.08 |
효율적인 정수 비교 기능 (0) | 2022.09.08 |