这里例子中的文字内容不是写死的,而是在数组中,用循环取出后渲染到页面上,每个元素还需要添加点击事件,点击时希望当前点击这个元素改变样式,我当时新建了一个类,以方便动态添加,但因为用了循环,动态添加时总是有问题,小花原来纠结了很久,现在记录下怎么解决的
(用其他的写法也能实现,比如动态绑定style,但是在使用该方法时出了问题,所以值得记录下)
先写好vue初始化代码,在data准备中有一个数组:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
</body>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
arr: ['喜羊羊', '美羊羊', '懒羊羊', '慢羊羊']
}
})
</script>
</html>l
我们要做的就是,将数组中的数据取出做成4个按钮,当点击某个时,某个按钮改变样式:
首先循环取出数据:
<div id="app">
<button v-for="(item,index) in arr">{{item}}</button>
</div>
给他们绑定点击事件: (注意,methods放在和data同级位置)
<button v-for="(item,index) in arr" v-on:click="btnClick(index)">{{item}}</button>
methods: {
btnClick(index) {
console.log(index)
}
}
此时,点击按钮,会打印序号,说明点击事件绑定成功
接下来重点来了,我们新建一个类:
<style>
.choose {
background-color: pink;
color: #fff;
border: 1px solid red;
}
</style>
我们应该给这些按钮动态绑定这个类: (并且用isActive变量来确定是否添加该类)
v-bind:class="{choose:isActive}"
但是,这样直接将这句话添加到循环上,那么每个元素是否添加这个类就都由isActive这一个变量来确定了,那么一旦isActive是true,那么所有的元素就都改变样式了。
因此,我们应该用另一个数组来存储每个元素是否添加这个类:(在data中添加数组)
isActive: [false, false, false, false]
然后动态绑定数组序号对应的值:
<button v-for="(item,index) in arr" v-on:click="btnClick(index)"
v-bind:class="{choose:isActive[index]}">{{item}}</button>
然后,在点击事件绑定的方法中: (点击时修改对应序号的布尔值)
btnClick(index) {
// console.log(index)
this.isActive[index] = true;
}
发现,点击时,并不能达到效果:这是因为这样通过索引号的方式更改数组内容是非响应式的,我们应该通过Vue.set方法: Vue.set(要修改的对象,序号,修改后的值)
btnClick(index) {
// console.log(index)
Vue.set(this.isActive, index, true)
}
此时,看效果:
如果要实现导航效果,点击某个,只有当前的变色,其他不变
只需要在修改当前样式前,先用循环将数组中所有布尔值都先改成false
btnClick(index) {
// console.log(index)
for (let i in this.isActive) {
Vue.set(this.isActive, i, false)
}
Vue.set(this.isActive, index, true)
}
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.choose {
background-color: pink;
color: #fff;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<button v-for="(item,index) in arr" v-on:click="btnClick(index)"
v-bind:class="{choose:isActive[index]}">{{item}}</button>
</div>
</body>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
arr: ['喜羊羊', '美羊羊', '懒羊羊', '慢羊羊'],
isActive: [false, false, false, false]
},
methods: {
btnClick(index) {
// console.log(index)
for (let i in this.isActive) {
Vue.set(this.isActive, i, false)
}
Vue.set(this.isActive, index, true)
}
}
})
</script>
</html>