html结构:
:class的用法很多种:
:class="[class1,flag?class2:'']"// 数组
:class="{'class1':flag}"// 对象
:class="addClass()"// 函数形式
<ul>
<li class="p_item" v-for="(item,i) in items" :key="i">
<a class="p_title" @click="n=i" :class="{'selected':n==i}">
<i class="iconfont" :class="item.icon"></i>{{item.name}}
<b :class="n==i?'down':'up'">^</b>
</a>
<ul class="c_item" v-show="n==i">
<li v-for="(sub,j) in item.child" :key="j">
<a>{{sub.name}}</a>
</li>
</ul>
</li>
</ul>
js数据:
new Vue({
el:"#my",
data:{
n:1, //用于菜单的动态效果实现操作,这里也可以在数据加上flag去判断,但是这样不能保证后端数据是否能给到,所以优先采用这种
items:[
{
name:'肥羊',
icon:'icon-nnc',
child:[
{name:'标题肥羊'},
{name:'肥羊'},
{name:'肥羊一'}
]
},
...
]
},
methods:{
getList(){
axios({
method:'get',
url:'/menus'
}).then(res=>{
this.items = res?.data?.result;// ?.可选链
}).catch(error=>{
console.log(error)
})
}
},
mounted(){
this.getList()// 或者数据也可以通过这里获取,而不是写死的数据
}
})
css:
.selected {
color: #1890ff;
border-bottom: 1px solid #1890ff;
}
.down {
transform: rotate(180deg);
}
.up {
transform: rotate(0deg);
}
....
此外还有一种方式:
不过这种需要处理一下每条数据是否有flag字段。
<ul>
<li class="p_item" v-for="(item,i) in items" :key="i">
<a class="p_title" @click="flagChange(item)" :class="{'selected':item.flag}">
<i class="iconfont" :class="item.icon"></i>{{item.name}}
<b v-show="!item.flag">^</b>
<b v-show="item.flag">下</b>
</a>
<ul class="c_item" v-show="item.flag">
<li v-for="(sub,j) in item.subItems" :key="j">
<a>{{sub.name}}</a>
</li>
</ul>
</li>
</ul>
items:[
{
name:'标题一',
icon:'icon-yonghu',
flag:true,
subItems:[
{name:'标题一'},
{name:'标题一'},
{name:'标题一'}
]
},
....
]
methods:{
flagChange(item){
//item.flag = !item.flag;
this.items.forEach(function(v){
v.flag = false;
});
item.flag = true;
}
},
每条数据是否有flag字段,这种方法在列表选中状态时特别有用。
使用引入模式时,可以用template模块或者v-cloak清除一闪而过的模版语言{{}}
<link rel="stylesheet" type="text/css" href="css/index.css">
<script src='js/vue.js'></script>
<script src='js/index.js'></script>
<!--左侧所有好友-->
<div class="col-xs-6 col-sm-6" >
<div class="panel panel-success">
<!--标题-->
<div class="panel-heading">
<template><h3 class="panel-title">所有好友({{items.length}})/选中好友({{selectItems.length}})</h3></template>
</div>
<!--内容-->
<div class="panel-body panel-height">
<ul>
<li v-for="item in items" :key="item.id" @click="addItemfn(item)" :class="item.flag?'active':''">
<span class="glyphicon glyphicon-fire photo"></span>
<span v-cloak>{{item.name}}({{item.iphone}})</span>
</li>
</ul>
</div>
</div>
</div>
<!--右侧选择联系人-->
<div class="col-xs-6 col-sm-6" >
<div class="panel panel-success">
<!--标题-->
<div class="panel-heading">
<h3 class="panel-title" v-cloak>已选择联系人({{selectItems.length}})</h3>
</div>
<!--内容-->
<div class="panel-body panel-height">
<ul >
<li v-for="(item,i) in selectItems" :key="item.id" @mouseover="isShow=i" @mouseout="isShow='hide'">
<template><span class="glyphicon glyphicon-fire photo"></span>{{item.name}}({{item.iphone}})</template>
<span class="glyphicon glyphicon-trash del" v-show="isShow===i" @click="delItem(item,i)"></span>
</li>
</ul>
</div>
</div>
</div>
// index.js
window.onload = function(){
new Vue({
el:'#app',
data:{
isShow:'hide',
items:[],
selectItems:[]
},
mounted(){
for (let i = 0; i < 20; i++) {
this.items = [...this.items,{name:'肥羊'+i+2,id:i,iphone:'1856374879'+i,flag:false}]
}
},
methods:{
addItemfn:function(item){
item.flag = true// 选中状态
if(this.selectItems.length>0){
// 方法1 数组去重
// for (let i = 0; i < this.selectItems.length; i++) {
// const el = this.selectItems[i];
// if(item.id===el.id) return;
// }
// 方法二
let filterArr = this.selectItems.filter(v=>v.id===item.id)
if(filterArr.length>0) return
// // 方法三
// let mapArr = this.selectItems.map(v=>v.name)
// if(mapArr.includes(item.name)) return
}
this.selectItems.push(item)
// 方法四
// this.selectItems = [...new Set(this.selectItems)]
},
delItem(v,i){
this.selectItems.splice(i,1)// 删除第i个
this.items.forEach(item => {
if(item.id===v.id){
item.flag = false;//删除选中好友时,所有好友的列表也需要状态对应
}
});
}
}
})
}
部分css:
...
.active{
color: #f60;
}
[v-cloak]{
display: none;/* 去掉一闪而过的模版{{}}*/
}