一. 选中取消(传参)
- 选中
- 取消选中
- 实现
<template>
<div class="qualitityIssues">
<div style="display: flex;">
<div class="course-area">
<div :class="checkoutIndex == index ? 'course-name' : 'course-name-active'"
v-for="(item, index) in courseList" :key="item.id" @click="handleCourse(index, item.id)">
<div :class="checkoutIndex == index ? 'course-flag' : 'course-flag-active'"></div>
<div :class="checkoutIndex == index ? 'course-title' : 'course-title-active'">{{ item.dictValue
}}</div>
</div>
</div>
<div class="course-content-area" v-loading="listLoading">
<div class="course-document" v-for="(item, index) in list" :key="index">
<div class="course-content">
<div class="tag-area">
<span class="course-tag" v-show="item.sourceClassifyName != ''"
v-for="( tag, index ) in item.sourceClassifyName.split(',').slice(0, 3)" :key="index">{{
tag
}}</span>
</div>
<div class="course-time">
{{ item.createTime }}
</div>
</div>
<div class="course-document-name" @click="handleDetail(item.id)">
{{ item.title }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getCourseTree} from "@/api/xxx"
import { getList } from "@/api/xxx"
export default {
data() {
return {
courseList: [],
checkoutIndex: null,
list: [],
query: {
tagA:''
},
pageForm: {
current: 1,
size: 10,
total: 0
},
listLoading: false,
count: 0
}
},
mounted() {
getCourseTree().then(res => {
this.courseList = res.data
})
this.fetchData()
},
methods: {
/**
* 选中标签项
* @param {Int} index
* @param {Object} item
*/
handleCourse(index, tagA) {
if (this.checkoutIndex == index) {
this.checkoutIndex = null
this.query.tagA = ''
} else {
this.checkoutIndex = index
this.query.tagA = tagA
}
this.fetchData()
},
/**
* 初始化质量课题列表数据
*/
fetchData() {
this.listLoading = true;
getList(this.pageForm.current, this.pageForm.size, this.query).then(res => {
if (res.success) {
// 仅显示前十条
this.list = res.data.slice(0, 10)
this.listLoading = false
}
})
},
/**
* 点击跳转到详情页
* @param {Int} id
*/
handleDetail(id) {
this.$router.push({
path: `/pageDetail/${id}`
})
},
}
}
</script>
<style scoped lang="less">
.qualitityIssues {
margin: 24px 0;
background-color: #fff;
padding: 24px;
border-radius: 10px;
.title {
display: flex;
justify-content: center;
align-items: flex-start;
gap: 10px;
color: #333;
text-shadow: 0px 4px 0px rgba(0, 0, 0, 0.05);
font-family: "Source Han Sans CN";
font-size: 20px;
font-style: normal;
font-weight: 700;
line-height: 24px;
margin-bottom: 24px;
}
.course-area {
border-radius: 10px 0px 0px 10px;
background: linear-gradient(166deg, #3C61E6 5.57%, #023EB4 95.34%);
padding: 16px;
gap: 12px;
display: flex;
flex-direction: column;
align-items: flex-start;
width: 219px;
min-height: 664px;
.course-name {
border-radius: 5px;
background: #FFF;
display: flex;
padding: 8px 16px;
align-items: center;
gap: 8px;
align-self: stretch;
cursor: pointer;
.course-flag {
border-radius: 4px;
background: linear-gradient(180deg, #046AF9 0%, rgba(4, 106, 249, 0.00) 100%);
width: 3px;
height: 16px;
}
.course-title {
color: #023FB5;
font-family: "Source Han Sans CN";
font-size: 16px;
font-style: normal;
font-weight: 700;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
max-width: 144px;
text-wrap: nowrap;
}
}
.course-name-active {
display: flex;
padding: 8px 16px;
align-items: center;
gap: 8px;
align-self: stretch;
cursor: pointer;
.course-flag-active {
border-radius: 4px;
background: #FFF;
width: 3px;
height: 16px;
}
.course-title-active {
color: #FFF;
font-family: "Source Han Sans CN";
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
max-width: 144px;
text-wrap: nowrap;
}
}
}
.course-content-area {
margin-left: 16px;
min-width: 740px;
.course-document {
border-bottom: 1px dotted #EEE;
.course-content {
display: flex;
justify-content: space-between;
.tag-area {
.course-tag {
border-radius: 20px;
border: 1px solid #F46924;
display: inline-block;
padding: 0px 12px;
color: #F46924;
font-family: "Source Han Sans CN";
font-size: 12px;
font-style: normal;
font-weight: 350;
line-height: 24px;
margin-right: 12px;
}
}
.course-time {
color: #CCC;
text-align: right;
font-family: "Source Han Sans CN";
font-size: 14px;
font-style: normal;
font-weight: 350;
line-height: 24px;
}
}
.course-document-name {
color: #666;
font-family: "Source Han Sans CN";
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px;
margin: 8px 0 12px 0;
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 740px;
}
.course-document-name:hover {
color: #023EB4;
cursor: pointer;
}
}
.course-document:not(:first-child) {
margin: 24px 0;
}
}
}
</style>
- 数据结构
courseList:[
{
id:"1",
dictValue:"质量创新"
},
{
id:"2",
dictValue:"六西格玛项目"
},
]
list:[
{
id:"1",
title:"",
sourceClassifyName:"标准,政策",
createTime:""
},
{
id:"2",
title:"",
sourceClassifyName:"标准,政策",
createTime:""
}
]
二. 选中取消(展示选中标签项)
-
选中
-
取消
-
实现
<template>
<div>
<div>
<!-- 展示选中项 -->
<div class="search-tag" v-for="item in checkedTags" :key="item.id">
<span>{{ item.dictValue }}</span>
</div>
<!-- 标签区域 -->
<div class="tags-area">
<div class="tags-content">
<div v-for="( item, index ) in allTagList " :key="index" class="tag-area">
<div>
<span class="tag-icon"></span>
<span class="tag-title">{{ item.dictValue }}</span>
</div>
<div class="tag-value">
<div v-for="( children, childrenIndex ) in item.children " :key="children.id" :class="children.flag ? 'tag-name-active' : 'tag-name'" @click="clickTag(index, childrenIndex, children)">
<span style="display: flex;align-items: center;">
{{ children.dictValue }}
</span>
</div>
</div>
</div>
</div>
</div>
</div
</div>
</template>
<script>
import { getTagTree } from "@/api/dictbiz";
export default {
data(){
return{
checkedTags: [], // 已选标签项
allTagList: [], // 所有标签项
}
},
methods:{
/**
* 初始化所有分类标签项
**/
fetchData(){
getTagTree().then(res => {
if (res.success) {
this.allTagList = res.data;
}
})
},
/**
* 选择标签项
* @param {Int} 父级index
* @param {Int} 子级index
* @param {Object} item 选中项
*/
clickTag(index, i, item) {
let list = this.allTagList;
let flag = !list[index].children[i].flag;
this.$set(this.allTagList[index].children[i], "flag", flag);
if (flag) {
this.checkedTags.push(item);
} else {
this.handleClose(item);
}
},
/**
* 删除标签
**
*/
handleClose(item) {
let index = this.checkedTags.findIndex((e) => e.id == item.id);
this.allTagList.forEach((e) => {
let itemIndex = e.children.findIndex((i) => i.id == item.id);
if (itemIndex != -1) {
e.children[itemIndex].flag = false;
this.checkedTags.splice(index, 1);
}
});
},
}
}
</script>
<style lang="less" scoped>
.tags-area {
padding: 14px 48px;
min-height: 272px;
background-color: #fff;
.tags-content {
display: flex;
justify-content: space-between;
padding: 8px 0;
.tag-area{
.tag-icon {
display: inline-block;
width: 4px;
height: 16px;
border-radius: 2px;
background: #023FB5;
margin-right: 8px;
}
.tag-title {
color: #023FB5;
font-family: "Source Han Sans CN";
font-size: 18px;
font-style: normal;
font-weight: 700;
line-height: 16px;
}
.tag-value {
display: flex;
flex-wrap: wrap;
.tag-name {
color: #023FB5;
font-family: "Source Han Sans CN";
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
border-radius: 5px;
padding: 4px 12px;
margin: 12px 12px 0 0;
border: 1px solid rgba(52, 93, 223, 0.30);
cursor: pointer;
}
.tag-name-active {
color: #FFF;
font-family: "Source Han Sans CN";
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
border-radius: 5px;
padding: 4px 12px;
margin: 12px 12px 0 0;
background: linear-gradient(166deg, #3C61E6 5.57%, #023EB4 95.34%);
cursor: pointer;
border: 1px solid transparent;
}
}
}
.tag-area:first-child {
min-width: 468px;
}
.tag-area:not(:last-child) {
margin-right: 28px;
}
}
}
</style>
- 数据结构
allTagList:[
{
id:"1",
dictValue:"分类一",
children:[
{
id:"1712717305748391111",
dictValue: "可靠性项目",
parentId:"1",
code:"kind_1"
sort:0
},
{
id:"1712717305748393985",
dictValue: "服务创新",
parentId:"1",
code:"kind_1"
sort:1
}
]
sort:0,
code:"kind_1"
},
{
id:"2",
dictValue:"分类二",
children:[
{
id:"1712717305748392222",
dictValue: "落实双碳",
parentId:"2",
code:"kind_2"
sort:0
},
]
sort:1,
code:"kind_2"
}
]