简体   繁体   English

如何在全局点击事件中切换选定的类?

[英]How to toggle a selected class in a global click event?

I'm creating my component library in vue, and I defined my component checkbox , the code is like this:我在 vue 中创建我的组件库,并定义了我的组件复选框,代码是这样的:

<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>

Now, I hope that when I click the checkbox to set the data "isSelected" false, I can give the component class "checkboxcont-selected-last" , and when I click other checkbox component, the classname "checkboxcont-selected-last" can be removed, how can I listen my click event to finish it?现在,我希望当我点击复选框将数据“isSelected”设置为false时,我可以给组件类“checkboxcont-selected-last” ,当我点击其他复选框组件时,类名“checkboxcont-selected-last”可以删除,我怎样才能听我的点击事件来完成它? I try to use native JavaScript code to add the classname of the dom, but it seemed to have nothing when I binded the classname of my component with Vue.js:我尝试使用原生 JavaScript 代码添加 dom 的类名,但是当我将组件的类名与 Vue.js 绑定时,它似乎什么都没有:

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

What should I do to solve this problem, please?请问我应该怎么做才能解决这个问题?

Here is my style code using 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>

My initial thought is that I add the class by using this.$el after I clicked the component, it can be accessed because I dispatched the click event, and I just can't access the other component:我最初的想法是我点击组件后使用this.$el添加类,因为我调度了click事件,所以可以访问它,而我只是无法访问其他组件:

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

And I remove the class by using native HTML DOM operation when I dispatch the click event because I can not access the other component, so the complete definition of clickevent is that:而且我在调度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;
    }
}

It looks good, but I can not add classname of my component when I use v-bind to bind my component's classname, is it wrong?看起来不错,但是当我使用v-bind绑定我的组件的类名时,我无法添加我的组件的类名,是不是错了? And Is it unable to use native HTML DOM operation when I bind my component's classname with Vue?当我将组件的类名与 Vue 绑定时,是否无法使用原生 HTML DOM 操作?

A better way to dynamically add or remove class can be using v-bind:class .动态添加或删除类的更好方法是使用v-bind:class There are different ways you can add a dynamic class based on a vue data variable.有多种方法可以基于vue 数据变量添加动态类。

I see you are already using it:我看到你已经在使用它了:

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

So here this div will have only one class : checkboxcont if isSelected is false, and two classes : checkboxcont and checkboxcont-selected if isSelected is true.所以这里这个 div 将只有一个类:如果isSelected为 false,则为checkboxcont ,如果isSelected为 true,则有两个类: checkboxcont and checkboxcont-selected

Edited:编辑:

Given that you want to add a class to DOM on another component, I can think of two ways:鉴于您想在另一个组件上向 DOM 添加一个类,我可以想到两种方法:

  1. Using Web API: You can do following if you know the id of the element you want to add class using Element.className :使用 Web API:如果您知道要使用Element.className添加类的元素的 id,则可以执行以下操作:

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

  1. Vuex way: You can have a centralised state provided by vue or use vuex to manage state, these state variables can be changed across components, and can be used to add/remove class dynamically. Vuex方式:你可以有一个vue提供的集中状态或者使用vuex来管理状态,这些状态变量可以跨组件改变,可以用来动态添加/删除类。

You can have a look at my this answer to understand more about vuex.您可以查看我的这个答案以了解有关 vuex 的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM