Vue点击一组按钮中的某一个按钮并动态更改样式

首先v-for循环渲染出一组button,并添加相应的样式

html

<div id="app">
    <div class="div_class_buttonGroup">
        <div v-for="item in btns" class="div_class_defaultBtn"> {{item.name}}</div>
        </div>
    </div>
</div>

javascript

var vm = new Vue({
    el:'#app',
    data(){
        return{
            currentBtn:'按钮1',
            btns:{
                btn_1:{
                    name:'按钮1',
                    value:'one'
                },
                btn_2:{
                	name:'按钮2',
                	value:'two'
            	},
            	btn_3:{
                	name:'按钮3',
                    value:'three'
            	}
            }
        }
    }
})

css

*{
    margin: 0 0;
    padding: 0 0;
}
.div_class_buttonGroup{
    display: flex;
}
.div_class_defaultBtn{
    display: flex;
    width: 100px;
    height: 50px;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    margin:0 1rem;
}
.div_class_defaultBtn:first-child{
    margin-left: 0rem;
}
.div_class_defaultBtn:last-child{
    margin-right: 0rem;
}
.active{
    background-color: aquamarine;
    color: #fff;
}

设置按钮1为默认按钮,并添加active 样式,则按钮1渲染的样式则为

<div class="div_class_defaultBtn active">按钮1</div>

相关代码

<div v-for="item in btns" class="div_class_defaultBtn" :class={active:currentBtn === item.name} > {{item.name}}</div>

或者

<div v-for="item in btns" class="div_class_defaultBtn" :class={active:getCurrentBtn(item.name)} > {{item.name}}</div>

以上代码中的getCurrentBtn方法可以是methods中的方法,也可以是computed中的计算属性

添加v-on:click方法修改currentBtn的值

()=>1,绑定active样式,使{active:item.name === currentBtn}

这样做是最方便的,当点击修改currentBtn的值,currentBtn的值修改之后,那么active的样式就会加载到item.name = currentBtn

<div v-for="item in btns" class="div_class_defaultBtn" :class={active:currentBtn === item.name} @click="currentBtn = item.name"> {{item.name}}</div>
()=>2,绑定active样式,使{active:getCurrentBtn(item.name)}

其中getCurrentBtn为一个方法,传入的item.name === this.currentBtn 为true时,则返回true,表示当前选中的按钮加载active样式

<div v-for="item in btns" class="div_class_defaultBtn" :class={active:getCurrentBtn(item.name)} @click="currentBtn = item.name"> {{item.name}}</div>
methods:{
    getCurrentBtn(data){
        return this.currentBtn === data
    }
}

其实这两种方法其实是一样的,只是在加载样式的时候换了一种写法而已,第一种是直接在绑定属性里通过计算item.name === currentBtn是否为true,为true则加载active样式,第二种写法是方法,在方法里判断之后再返回

()=>3,通过computed计算属性,判断是否相等
<div v-for="item in btns" class="div_class_defaultBtn" :class={active:getCurrentBtn(item.name)} @click="currentBtn = item.name"> {{item.name}}</div>
computed:{
    getCurrentBtn(){
        return function(data){
            return this.currentBtn === data
        }
    }
}

计算属性要传递参数,在当前函数中,必须要加一层闭包,在闭包中接受参数

Vue的计算属性不带参数的写法如下

在html中

<!--1111-->
{{test}}

在computed对象中

computed:{
    test(){
        return `1111` 
    }
}

可想Vue在处理该属性的时候,会以{{test()}}这样计算出结果,而我们需要传入参数,vue{{test()(params)}}这种形式渲染,所以我们需要一个函数闭包,在{{test}}中返回一个function,再通过这个function(params)将参数传递进计算属性中

所以我们在传递参数的时候在闭包中接受参数,闭包中的this要视情况而定

而我们在不使用箭头函数的写法的时候,this指向的是当前的vue实例,所以可以使用 return this.currentBtn === data,当前this.currentBtn 就是在data中定义的currentBtn

computed:{
    getCurrentBtn(){
        return data => this.currentBtn === data
    }
}

如果闭包使用箭头函数,箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this就继承了定义函数的对象。所以在箭头函数中的this则是定义函数时绑定的,则为当前vue的实例。

如果getCurrentBtn为箭头函数呢?

computed:{
    getCurrentBtn:self => data => self.currentBtn === data
}

我们可以知道,这个self 肯定是指向vue实例的,原因在于当我们在调用getCurrentBtn(self)(data)时,此时已经将vue实例传入至self中,以解决外层为箭头函数,闭包为箭头函数,闭包中的this为window