【问题标题】:How to toggle a selected class in a global click event?如何在全局点击事件中切换选定的类?
【发布时间】:2017-05-06 13:13:33
【问题描述】:

我在vue中创建我的组件库,我定义了我的组件checkbox,代码是这样的:

<template>
    <div class="checkboxcont" :class="{'checkboxcont-selected': isSelected}" @click="clickevent">
        <span class="j-checkbox">
            <input type="checkbox" />
        </span>
        <slot></slot>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                isSelected: false
            }
        },
        methods: {
            clickevent(event) {
                if(this.isSelected) {
                    this.isSelected = false;
                } else {
                    this.isSelected = true;
                }
            }
        },
    }
</script>

现在,我希望当我点击复选框将数据“isSelected”设为false时,我可以给组件类“checkboxcont-selected-last”,当我点击其他checkbox组件时,类名 "checkboxcont-selected-last" 可以删除,我怎样才能听我的点击事件来完成它?我尝试使用原生 JavaScript 代码添加 dom 的类名,但是当我将组件的类名与 Vue.js 绑定时,它似乎什么都没有:

clickevent(event) {
    if(this.isSelected) {
        this.isSelected = false;
        this.$el.classList.add("checkboxcont-selected-last");
    } else {
        this.isSelected = true;
    }
}

请问我该怎么做才能解决这个问题?

这是我使用 less 的样式代码:

<style lang="less" scoped rel="stylesheet/less">
    @import '../../mixin/mixin.less';
    .checkboxcont {
        display: inline-block;
        &:hover {
            cursor: pointer;
            .j-checkbox {
                border-color: @jbluelight;
            }
        }
    }
    .j-checkbox {
        position: relative;
        top: 0;
        left: 0;
        width: 12px;
        height: 12px;
        display: inline-block;
        border: 1px solid @border;
        border-radius: 3px;
        line-height: 12px;
        vertical-align: -3px;
        margin: 0 5px;
        z-index: 20;
        transition: all .2s linear;
        input {
            opacity: 0;
            position: absolute;
            left: 0;
            top: 0;
            visibility: hidden;
            /*display: none;*/
        }
    }
    .checkboxcont-selected {
        .j-checkbox {
            background: @jbluelight;
            border-color: @jbluelight;
            &:after {
                content: '';
                width: 4px;
                height: 7px;
                border: 2px solid white;
                border-top: none;
                border-left: none;
                position: absolute;
                left: 3px;
                top: 0;
                z-index: 30;
                transform: rotate(45deg) scale(1);
            }
        }
    }
</style>
<style lang="less" rel="stylesheet/less">
    @import '../../mixin/mixin.less';
    .checkboxcont-selected-last .j-checkbox {
        border-color: @jbluelight;
    }
</style>

我最初的想法是我点击组件后使用this.$el添加类,因为我调度了点击事件,所以可以访问它,并且我只是无法访问其他组件:

if(this.isSelected) {
    this.isSelected = false;
    this.$el.classList.add("checkboxcont-selected-last")
} else {
    this.isSelected = true;
}

并且我在调度click事件时使用原生HTML DOM操作删除了类,因为我无法访问其他组件,所以clickevent的完整定义是:

clickevent(event) {
    let selectedLast = document.querySelector(".checkboxcont-selected-last");
    if(selectedLast) {
        selectedLast.classList.remove("checkboxcont-selected-last")
    }
    if(this.isSelected) {
        this.isSelected = false;
        this.$el.classList.add("checkboxcont-selected-last")
    } else {
        this.isSelected = true;
    }
}

看起来不错,但是当我使用v-bind绑定我的组件的类名时,我无法添加我的组件的类名,是不是错了?并且当我将组件的类名与Vue绑定时是否无法使用原生HTML DOM操作?

【问题讨论】:

  • 我想提一下,Vue 有很多组件库,真的足够了,所以考虑参与其中的一些而不是创建新的。
  • 你能详细说明一下吗?我试图了解您想要实现的目标,但我做不到。如果您能在这个案例中创建小提琴,这将有所帮助,这样会更容易为您提供帮助。
  • 您已经在使用 HTML 类的动态绑定,我在发布答案后注意到了这一点,那么为什么需要本机 JavaScript 代码来在 DOM 中添加类。
  • 是的,我现在可以动态绑定 HTML 类,但它在一个组件中很有用(我只能这样做),如何单击该组件并删除另一个组件的类,好吗?

标签: javascript vue.js


【解决方案1】:

动态添加或删除类的更好方法是使用v-bind:class。有多种方法可以添加基于 vue data 变量的动态类。

我看到你已经在使用它了:

<div class="checkboxcont" :class="{'checkboxcont-selected': isSelected}" @click="clickevent">

所以这里这个 div 只有一个类:checkboxcont 如果isSelected 为假,两个类:checkboxcont and checkboxcont-selected 如果isSelected 为真。

编辑:

鉴于您想在另一个组件上向 DOM 添加一个类,我可以想到两种方法:

  1. 使用 Web API:如果您知道要使用 Element.className 添加类的元素的 ID,则可以执行以下操作:

    var d = document.getElementById("yourElem") d.className += " otherclass"

  2. Vuex方式:可以有vue提供的集中状态,也可以使用vuex来管理状态,这些状态变量可以跨组件改变,可以用来动态添加/删除类。

    你可以看看我的这个answer,了解更多关于vuex的信息。

【讨论】:

  • 可能我的想法表达的不是很清楚,我可以通过绑定clickEvent来动态添加我的类,但是在一个组件中是有用的,当我点击一个时怎么办复选框(组件1),并删除另一个复选框(组件2)的类?
  • 我想让我的组件的边框在我取消点击它时点亮,但是当我点击其他复选框时,它的边框不应该是浅色的,所以我给它一个临时类,我使用less添加了我的样式代码,你可以看到它。
  • 你给出的第一种方式,我在问题的最后尝试使用它,但它似乎什么也没做,是我用错了this.$el i> 改变它的类名?第二个方法我想问我在使用Vuex时,我必须让用户编写Vue.use(vuex),我提到我想创建一个组件库,所以使用 Vuex 是不是一个好方法?
  • @Jorten 我不认为你可以使用 this.$el 访问其他组件的元素,除了你使用的语法似乎也是错误的。是的,Vuex 是 vue 社区在不同组件之间共享数据的标准方式,看看我的回答 here
  • 我明白你的意思。现在我有两个问题,第一个是我尝试在其他组件中更改类名,我会在我的问题中添加它,你可以看看,拜托。第二个是当我使用vuex的时候,我必须声明:Vue.use(vuex);而当人们使用我的组件时,他们会导入它:import checkbox from "ChanotUI"是使用vuex吗?自动地?或者他们应该自己再次声明"Vue.use(vuex)"
猜你喜欢
  • 2014-09-30
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 2020-07-09
  • 2019-04-25
  • 2013-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多