gpt4 book ai didi

javascript - 如果元素单击 vue 组件,我如何添加类事件?

转载 作者:太空宇宙 更新时间:2023-11-04 07:30:17 25 4
gpt4 key购买 nike

我的 vue 组件是这样的:

Vue.component('list-category', {
template: "#lc",
props: ['data', 'category', 'search'],
data() {
return {
open: false,
categoryId: this.category
}
},
mounted() {
let isDataOpen = (d) => d.id === this.categoryId || d.children && d.children.some(isDataOpen);
this.open = isDataOpen(this.data);
},
computed: {
icon() {
return {
'fa-plus': !this.open,
'fa-minus': this.open,
}
},
isFolder() {
return this.data.children && this.data.children.length
},
isShow() {
return this.open ? 'show' : 'hide'
}
},
methods: {
toggle() {
this.open = !this.open
},
filterByCategory(id) {
this.categoryId = id
}
}
})

new Vue({
el: '#app',
data() {
return {
categories: [{
id: 1,
name: 'England',
children: [{
id: 3,
name: 'Chelsea',
children: [{
id: 7,
name: 'Hazard'
},
{
id: 8,
name: 'Morata'
}
]
},
{
id: 4,
name: 'Manchester United',
children: [{
id: 9,
name: 'Pogba'
},
{
id: 10,
name: 'Lukaku'
}
]
}
]
},
{
id: 2,
name: 'Spain',
children: [{
id: 5,
name: 'Real Madrid',
children: [{
id: 11,
name: 'Ronaldo'
},
{
id: 12,
name: 'Bale'
}
]
},
{
id: 6,
name: 'Barcelona',
children: [{
id: 13,
name: 'Messi'
},
{
id: 14,
name: 'Suarez'
}
]
},
]
}
],
category: 7
}
}
})
.active {
background: yellow;
}

.pd-search-filter > .panel-body ul.filter-category {
padding-left: 0;
list-style: none;
margin: 0 -15px 0;
}

.pd-search-filter > .panel-body ul.filter-category > li a {
display: block;
padding: 10px 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.pd-search-filter > .panel-body ul.filter-category > li a:last-child {
padding-left: 45px;
}

.pd-search-filter > .panel-body ul.filter-category > li a:focus, .pd-search-filter > .panel-body ul.filter-category > li a:hover {
background-color: #eeeeee;
text-decoration: none;
}

.pd-search-filter > .panel-body ul.filter-category > li a + ul {
padding-left: 0;
list-style: none;
}

.pd-search-filter > .panel-body ul.filter-category > li a + ul > li > a {
padding-left: 30px;
}

.show {
display: block !important;
}

.hide {
display: none !important;
}
<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<div id="app">
<div class="panel panel-default pd-search-filter">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-circle-o"></i> By Category</h3>
</div>
<div class="panel-body">
<ul class="filter-category" v-for="list in categories">
<list-category :data="list" :category="category"></list-category>
</ul>
</div>
</div>
</div>

<template id="lc">
<li>
<!--parent-->
<a v-if="isFolder" href="javascript:" @click="toggle">
<span class="fa fa-fw" :class="icon"></span> {{data.name}}
</a>
<!--if not folding, we do not need an binding event-->
<a v-else href="javascript:" :title="data.name" :class="{active: data.id === categoryId}" @click="filterByCategory(data.id)"><span class="fa fa-fw fa-circle-o"></span> {{data.name}}</a>
<!--children-->
<ul v-if="isFolder" :class="isShow">
<list-category v-for="(data, index) in data.children" :key="index" :data="data" :search="search" :category="categoryId"></list-category>
</ul>
</li>
</template>

看来您需要查看演示和完整代码

是这样的:http://jsfiddle.net/vxLhbo5m/861/

从演示中看到类别危险活跃。如果我点击 morata 类别,它是不活动的。而我已经编写了代码

我该如何解决这个问题?

============================================= ============================

最佳答案

您必须将类别计算器移动到观察者(而不是 mount())并发出/监听从子级到父级的一些事件以更新类别和折叠 未选择的子树。

Updated JSFiddle here .

变化:

  • 模板:

    • 家长:

      • 来自:

        <div id="app">
        ...
        <list-category :data="list" :category="category"></list-category>
      • 添加对 category 事件的监听并更新父级的 category 属性:

        <div id="app">
        ...
        <list-category :data="list" :category="category" @category="category = $event"></list-category>
    • child :

      • 来自:

        <template id="lc">
        ...
        <list-category v-for="(data, index) in data.children" :key="index" :data="data" :search="search" :category="categoryId"></list-category>
      • 监听 category 事件并将其发送给父级:

        <template id="lc">
        ...
        <list-category v-for="(data, index) in data.children" :key="index" :data="data" :search="search" :category="categoryId" @category="$emit('category', $event)"></list-category>
  • JavaScript(全部在 child 中):

    • 更改 filterByCategory 以发出事件而不是改变属性:

      • 来自:

        filterByCategory(id) {
        this.categoryId = id
        }
      • 收件人:

        filterByCategory(id) {
        this.$emit('category', id);
        }
    • 删除 mounted 钩子(Hook)并添加 watcher:

      • 移除挂载:

        mounted() {
        let isDataOpen = (d) => d.id === this.categoryId || d.children && d.children.some(isDataOpen);
        this.open = isDataOpen(this.data);
        },
      • category 在父级中发生变化时添加 watcher 以获取:

        watch: {
        category: {
        handler() {
        this.categoryId = this.category
        let isDataOpen = (d) => d.id === this.categoryId || d.children && d.children.some(isDataOpen);
        this.open = isDataOpen(this.data);
        },
        immediate: true
        }
        }

演示:

Vue.component('list-category', {
template: "#lc",
props: ['data', 'category', 'search'],
data() {
return {
open: false,
categoryId: this.category
}
},
computed: {
icon() {
return {
'fa-plus': !this.open,
'fa-minus': this.open,
}
},
isFolder() {
return this.data.children && this.data.children.length
},
isShow() {
return this.open ? 'show' : 'hide'
}
},
methods: {
toggle() {
this.open = !this.open
},
filterByCategory(id) {
this.$emit('category', id);
}
},
watch: {
category: {
handler() {
this.categoryId = this.category
let isDataOpen = (d) => d.id === this.categoryId || d.children && d.children.some(isDataOpen);
this.open = isDataOpen(this.data);
},
immediate: true
}
}
})

new Vue({
el: '#app',
data() {
return {
categories: [{
id: 1,
name: 'England',
children: [{
id: 3,
name: 'Chelsea',
children: [{
id: 7,
name: 'Hazard'
},
{
id: 8,
name: 'Morata'
}
]
},
{
id: 4,
name: 'Manchester United',
children: [{
id: 9,
name: 'Pogba'
},
{
id: 10,
name: 'Lukaku'
}
]
}
]
},
{
id: 2,
name: 'Spain',
children: [{
id: 5,
name: 'Real Madrid',
children: [{
id: 11,
name: 'Ronaldo'
},
{
id: 12,
name: 'Bale'
}
]
},
{
id: 6,
name: 'Barcelona',
children: [{
id: 13,
name: 'Messi'
},
{
id: 14,
name: 'Suarez'
}
]
},
]
}
],
category: 7
}
}
})
.active {
background: yellow;
}

.pd-search-filter > .panel-body ul.filter-category {
padding-left: 0;
list-style: none;
margin: 0 -15px 0;
}

.pd-search-filter > .panel-body ul.filter-category > li a {
display: block;
padding: 10px 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.pd-search-filter > .panel-body ul.filter-category > li a:last-child {
padding-left: 45px;
}

.pd-search-filter > .panel-body ul.filter-category > li a:focus, .pd-search-filter > .panel-body ul.filter-category > li a:hover {
background-color: #eeeeee;
text-decoration: none;
}

.pd-search-filter > .panel-body ul.filter-category > li a + ul {
padding-left: 0;
list-style: none;
}

.pd-search-filter > .panel-body ul.filter-category > li a + ul > li > a {
padding-left: 30px;
}

.show {
display: block !important;
}

.hide {
display: none !important;
}
<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<div id="app">
<div class="panel panel-default pd-search-filter">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-circle-o"></i> By Category</h3>
</div>
<div class="panel-body">
<ul class="filter-category" v-for="list in categories">
<list-category :data="list" :category="category" @category="category = $event"></list-category>
</ul>
</div>
</div>
</div>

<template id="lc">
<li>
<!--parent-->
<a v-if="isFolder" href="javascript:" @click="toggle">
<span class="fa fa-fw" :class="icon"></span> {{data.name}}
</a>
<!--if not folding, we do not need an binding event-->
<a v-else href="javascript:" :title="data.name" :class="{active: data.id === categoryId}" @click="filterByCategory(data.id)"><span class="fa fa-fw fa-circle-o"></span> {{data.name}}</a>
<!--children-->
<ul v-if="isFolder" :class="isShow">
<list-category v-for="(data, index) in data.children" :key="index" :data="data" :search="search" :category="categoryId" @category="$emit('category', $event)"></list-category>
</ul>
</li>
</template>

关于javascript - 如果元素单击 vue 组件,我如何添加类事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49473224/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com