Vue js 각 개별 요소의 클래스 전환
부에즈에는 토글 클래스의 예가 많지만, 요소의 범위를 좁히는 토글 클래스는 아직 찾지 못했다.다음과 같은 전역 변수를 정의하는 경우:
data: {
toggle: false
}
다음 탐색 모음과 같은 요소가 있으면 문제가 발생할 수 있음:
<ul class="menu">
<li class="has-dropdown" v-bind:class="{ 'is-open': toggle }" @click="toggle = !toggle">
Foo
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</li>
<li class="has-dropdown" v-bind:class="{ 'is-open': toggle }" @click="toggle = !toggle">
Bar
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</li>
</ul>
여기서 무슨 일이 일어나는지 봐?이 두 요소 중 하나를 클릭하면 클래스가 글로벌 변수를 변경하기 때문에 클래스가 동시에 전환됩니다.클릭되는 요소만 클래스를 어떻게 전환하시겠습니까?
너무나 단순한 것이 현대적인 프레임워크를 사용하여 너무나 많은 코드를 필요로 한다는 것이 내 마음을 어지럽히고, 그것이 자바스크립트 개발이 이렇게 복잡해지는 이유다.나는 그 문제를 해결하기 위해 평범한 자바스크립트 청취자를 이용했다.
<li class="has-dropdown" @click="toggle">
...
</li>
...
methods: {
toggle: function( event ) {
event.target.classList.toggle('is-open')
}
}
...
이것은 그의 대답에서 @SLAKS가 언급했던 것의 작은 예일 뿐이다.본질적으로 목록 요소들을 그들 자신의 구성 요소로 바꾸어 그들 자신의 상태를 가질 수 있게 한다.
Vue.component("clicktoggle", {
template:`<li :class="{ 'is-open': toggle }" @click="toggle = !toggle"><slot></slot></li>`,
data() {return {toggle: false}}
})
그리고 이것이 어떻게 사용되는가.
console.clear()
Vue.component("clicktoggle", {
template:`<li :class="{ 'is-open': toggle }" @click="toggle = !toggle"><slot></slot></li>`,
data() {return {toggle: false}}
})
new Vue({
el:"#app"
})
.has-dropdown {
cursor: pointer;
}
.has-dropdown:not(.is-open) ul {
display: none
}
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<ul class="menu">
<li class="has-dropdown" is="clicktoggle">
Foo
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</li>
<clicktoggle class="has-dropdown">
Bar
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</clicktoggle>
</ul>
</div>
Vue는 이와 같은 작은 구성 요소들을 없앤다는 것이 믿을 수 없을 정도로 간단하다.한 가지 빠른 개선은 전환하려는 클래스를 지정하기 위해 속성을 추가하는 것이다.
VueJS(및 대부분의 다른 현대 웹 프레임워크)의 기본 지침 원칙은 모든 것이 모델에서 나온다는 것이다.
당신은 결코 DOM 조작에 대해 말하지 않고, 대신에 당신이 원하는 효과를 설명하는 모델을 만든다.
네 경우엔, 두 개를 원한다는 뜻이야data
한 가지가 아닌 재산.
그러나 실제로 해야 할 일은 각 목록 항목을 자신의 하위 구성 요소(그 다음 고유한 모델을 얻게 됨)로 만드는 것이다.슬롯을 사용하여 각 슬롯에 서로 다른 내용을 지정하십시오.
내가 이것을 다루는 방법은 부울이 아니라 색인(숫자 또는 기타)을 사용하는 것이다.확인toggle === index
및 클릭 시 인덱스 또는 -1로 전환 설정
문자열 값을 토글로 사용하는 작업 버전
https://jsfiddle.net/dnqp2nc9/1/
new Vue({
el: '#app',
data: {
toggle: null
}
})
.has-dropdown li{
opacity: 0.2;
}
.is-open li{
opacity: 1;
}
<script src="https://unpkg.com/vue"></script>
<div id="app">
{{toggle}}
<ul class="menu">
<li class="has-dropdown" v-bind:class="{ 'is-open': toggle === 'foo' }" @click="toggle = toggle !== 'foo' ? 'foo' : null">
Foo [{{toggle === 'foo' ? 'open' : 'closed'}}]
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</li>
<li class="has-dropdown" v-bind:class="{ 'is-open': toggle === 'bar' }" @click="toggle = toggle !== 'bar' ? 'bar' : null">
Bar [{{toggle === 'bar' ? 'open' : 'closed'}}]
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</li>
</ul>
</div>
여러 개를 열거나 닫으려면 어레이 버전 https://jsfiddle.net/hLm82x1d/1/을 참조하십시오.
new Vue({
el: '#app',
data: {
toggle: []
},
methods: {
toggleItem: function (key) {
var i = this.toggle.indexOf(key)
if (i < 0) {
this.toggle.push(key)
} else {
this.toggle.splice(i, 1)
}
}
}
})
.has-dropdown li{
opacity: 0.2;
}
.is-open li{
opacity: 1;
}
<script src="https://unpkg.com/vue"></script>
<div id="app">
{{toggle}}
<ul class="menu">
<li class="has-dropdown" v-bind:class="{ 'is-open': toggle.indexOf('foo') >= 0 }" @click="toggleItem('foo')">
Foo [{{toggle === 'foo' ? 'open' : 'closed'}}]
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</li>
<li class="has-dropdown" v-bind:class="{ 'is-open': toggle.indexOf('bar') >= 0 }" @click="toggleItem('bar')">
Bar [{{toggle === 'bar' ? 'open' : 'closed'}}]
<ul class="dropdown">
<li>Dropdown Item 1</li>
<li>Dropdown Item 2</li>
</ul>
</li>
</ul>
</div>
이것은 나에게 효과가 있었던 것 같다. 아이디어는 데이터를 통해 토글하는 아동 구성요소로 드롭 다운을 하는 것이었다. 이것은 여전히 진행 중이지만, 나는 Js와 Vue를 배우는데 이것이 최선의 방법이 아닐 수도 있다.
프라이머리.부에를 하다
<template>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<nuxt-link class="navbar-brand" to="/">Navbar</nuxt-link>
<button
@click="isNavbarCollapsed = !isNavbarCollapsed"
ref="navbar-toggler"
:aria-expanded="[!isNavbarCollapsed ? 'true' : 'false']"
:class="{ collapsed: isNavbarCollapsed}"
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarNavDropdown"
aria-controls="navbarNavDropdown"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div
:class="{ show: !isNavbarCollapsed}"
class="collapse navbar-collapse"
id="navbarNavDropdown"
>
<NavbarNav :items="loadedPrimaryMenu" />
</div>
</div>
</nav>
</template>
<script>
import NavbarNav from '@/components/Navigation/ThePrimary/NavbarNav'
export default {
name: 'TheNavigationPrimary',
data() {
return {
isNavbarCollapsed: true
}
},
computed: {
loadedPrimaryMenu() {
return this.$store.getters.loadedPrimaryMenu
}
},
components: {
NavbarNav
}
}
</script>
<style scoped lang="scss">
</style>
나바나브뷰
<template>
<ul class="navbar-nav">
<li
v-for="item in items"
:key="item.id"
class="nav-item"
:class="{ dropdown: hasChildren(item.children) }"
>
<NavLink
v-if="!hasChildren(item.children)"
:attributes="item"
/>
<NavbarNavDropdownMenu
v-else
:item="item"
/>
</li>
</ul>
</template>
<script>
import NavbarNavDropdownMenu from "@/components/Navigation/ThePrimary/NavbarNavDropdownMenu";
import NavLink from '@/components/Navigation/NavLink';
export default {
name: "NavbarNav",
props: {
items: {
type: Array,
required: true,
},
},
data() {
return {
};
},
methods: {
hasChildren(item) {
return item.length > 0 ? true : false;
},
},
components: {
NavbarNavDropdownMenu,
NavLink
}
};
</script>
<style scoped lang="scss">
</style>
NavbarNavDropdownMenu.부에를 하다
<template>
<span v-if="item">
<nuxt-link
to="#"
@click.prevent.native="openDropdownMenu"
v-click-outside="closeDropdownMenu"
:title="item.title"
:class="[
item.cssClasses,
{ show: isDropdownMenuVisible }
]"
:id="`navbarDropdownMenuLink-${item.id}`"
:aria-expanded="[isDropdownMenuVisible ? true : false]"
class="nav-link dropdown-toggle"
aria-current="page"
role="button"
data-toggle="dropdown"
>
{{ item.label }}
</nuxt-link>
<ul
:class="{ show: isDropdownMenuVisible }"
:aria-labelledby="`navbarDropdownMenuLink-${item.id}`"
class="dropdown-menu"
>
<li v-for="item in item.children" :key="item.id">
<NavLink
:attributes="item"
class="dropdown-item"
/>
</li>
</ul>
</span>
</template>
<script>
import NavLink from '@/components/Navigation/NavLink';
export default {
name: "DropdownMenu",
props: {
item: {
type: Object,
required: true,
},
},
data() {
return {
isDropdownMenuVisible: false,
};
},
methods: {
openDropdownMenu() {
this.isDropdownMenuVisible = !this.isDropdownMenuVisible;
},
closeDropdownMenu() {
this.isDropdownMenuVisible = false;
}
},
components: {
NavLink
}
};
</script>
<style scoped lang="scss">
</style>
NavLink.부에를 하다
<template>
<component
v-bind="linkProps(attributes.path)"
:is="attributes"
:title="attributes.title"
:class="[ attributes.cssClasses ]"
class="nav-link active"
aria-current="page"
prefetch
>
{{ attributes.label }}
</component>
</template>
<script>
export default {
name: 'NavLink',
props: {
attributes: {
type: Object,
required: true
}
},
methods: {
linkProps (path) {
if (path.match(/^(http(s)?|ftp):\/\//) || path.target === '_blank') {
return {
is: 'a',
href: path,
target: '_blank',
rel: 'noopener'
}
}
return {
is: 'nuxt-link',
to: path
}
}
}
}
</script>
<style scoped lang="scss">
</style>
외부 클릭 시 드롭다운을 닫으려면
import Vue from 'vue'
Vue.directive('click-outside', {
bind: function (el, binding, vnode) {
el.clickOutsideEvent = function (event) {
if (!(el == event.target || el.contains(event.target))) {
vnode.context[binding.expression](event);
}
};
document.body.addEventListener('click', el.clickOutsideEvent)
},
unbind: function (el) {
document.body.removeEventListener('click', el.clickOutsideEvent)
},
});
참조URL: https://stackoverflow.com/questions/45697058/vue-js-toggle-class-of-each-individual-element
'IT이야기' 카테고리의 다른 글
C/C++에 어레이를 복사하는 기능이 있는가? (0) | 2022.05.10 |
---|---|
Java에서 Long을 바이트[]로 변환한 후 다시 변환하는 방법 (0) | 2022.05.10 |
꼬리 재발은 정확히 어떻게 작동하는가? (0) | 2022.05.10 |
JS에서 api 클래스를 작성하고 Vuex에 전화하여 상태를 변경하는 방법 (0) | 2022.05.10 |
HTTP 응답 본문을 문자열로 가져오는 방법 (0) | 2022.05.10 |