Skip to content

Commit

Permalink
新增:树形多选选择器
Browse files Browse the repository at this point in the history
  • Loading branch information
jamebal committed Jan 20, 2021
1 parent 0bf40d0 commit 30e84b5
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 21 deletions.
156 changes: 156 additions & 0 deletions src/components/select/MultipleTree.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<template>
<el-select
ref="treeSelect"
size="mini"
:value="valueTitles"
:clearable="clearable"
multiple
collapse-tags
:placeholder="placeholder"
@clear="clearHandle"
@remove-tag="removeTag"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-tree
class="multiple-tree"
ref="selectTree"
node-key="id"
:data="options"
:props="props"
icon-class="-"
:check-on-click-node="true"
:expand-on-click-node="false"
:check-strictly="true"
:highlight-current="false"
:default-expand-all="true"
:default-checked-keys="value"
show-checkbox
@check="selectNode"
>
</el-tree>
</el-select>
</template>

<script>
export default {
name: "MultipleTreeSelect",
props:{
/* 配置项 */
props:{
type: Object,
default:()=>{
return {
value:'id', // ID字段名
label: 'name', // 显示名称
children: 'children' // 子级字段名
}
}
},
/* 选项列表数据(树形结构的对象数组) */
options:{
type: Array,
default: ()=>{ return [] }
},
/* 初始值 */
value:{
type: Array,
default: ()=>{ return [] }
},
/* 可清空选项 */
clearable:{
type:Boolean,
default:()=>{ return true }
},
/* 自动收起 */
accordion:{
type:Boolean,
default:()=>{ return false }
},
placeholder:{
type:String,
default:()=>{return "请选择"}
}
},
data() {
return {
valueIds: this.value, // 初始值
valueTitles: [],
data: [],
}
},
mounted(){
this.initHandle()
},
methods: {
// 初始化值
initHandle(){
if(this.valueIds){
this.$nextTick(() => {
this.$refs.selectTree.setCheckedKeys(this.valueIds)
if(this.valueIds.length > 0){
this.valueTitles = this.$refs.selectTree.getCheckedNodes().map(node => node.name)
} else {
this.valueTitles = []
}
})
}
this.initScroll()
},
// 初始化滚动条
initScroll(){
this.$nextTick(()=>{
let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0]
let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar')
scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'
scrollBar.forEach(ele => ele.style.width = 0)
})
},
selectNode(props, data){
this.valueIds = data.checkedKeys
this.valueTitles = data.checkedNodes.map(node => node.name)
this.$emit('input', this.valueIds)
},
// 移除选中项
removeTag(name) {
this.valueTitles = this.valueTitles.filter(valueTitle => valueTitle !== name)
let checkKeys = this.$refs.selectTree.getCheckedKeys();
let removeKey = this.$refs.selectTree.getCheckedNodes().filter(node => node.name === name)[0].id
checkKeys = checkKeys.filter(key => key !== removeKey)
this.valueIds = checkKeys
this.$refs.selectTree.setCheckedKeys(checkKeys)
this.$emit('input', this.valueIds)
},
// 清除选中
clearHandle(){
this.valueTitles = []
this.valueIds = []
this.$refs.selectTree.setCheckedKeys([])
this.$emit('input', this.valueIds)
}
},
watch: {
value(value){
this.valueIds = value
this.initHandle()
}
},
};
</script>

<style scoped>
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
height: auto;
max-height: 274px;
padding: 0;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item.selected{
font-weight: normal;
}
</style>
6 changes: 5 additions & 1 deletion src/components/table/TableList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
:data="tableData"
:max-height="tableMaxHeight"
row-key="id"
border
:border="border"
size="medium"
fit
highlight-current-row
Expand Down Expand Up @@ -96,6 +96,10 @@ export default {
return [];
}
},
border: {
type: Boolean,
default: true
},
loading: {
type: Boolean,
default: false
Expand Down
67 changes: 50 additions & 17 deletions src/views/setting/articles/articleManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<div class="box-card-header">
<div class="clearfix card-header-back">
<span>{{ alonePage ? '管理独立页面':'管理文章' }}</span>
<el-button class="card-button" size="mini" type="primary" @click="newArticle">新建</el-button>
<el-button class="card-button" size="mini" type="primary" @click="newArticle">写文章</el-button>
</div>
<div class="card-header-right" v-show="this.multipleSelection.length > 0">
<el-button size="small" type="danger" @click="handleDelete()">删除</el-button>
Expand All @@ -42,19 +42,34 @@
<div class="table-top-right">
<el-button v-if="isFilter" type="text" size="mini" @click="cancelFilter">取消筛选</el-button>
<el-input v-model="query.keyword" size="mini" placeholder="请输入关键字" @keyup.enter.native="getArticleList"></el-input>
<el-cascader
v-if="!alonePage"
v-model="categoryIdsList"
class="mark-setting-input"
placeholder="不选择"
size="mini"
:collapse-tags="false"
:options="categories"
:show-all-levels="false"
:props="{ multiple: true, checkStrictly: true, value: 'id', label: 'name' }"
clearable
@change="selectCategory"
></el-cascader>
<!-- <el-cascader-->
<!-- v-if="!alonePage"-->
<!-- v-model="categoryIdsList"-->
<!-- class="mark-setting-input"-->
<!-- placeholder="不选择"-->
<!-- size="mini"-->
<!-- :collapse-tags="false"-->
<!-- :options="categories"-->
<!-- :show-all-levels="false"-->
<!-- :props="{ multiple: true, checkStrictly: true, value: 'id', label: 'name' }"-->
<!-- clearable-->
<!-- @change="selectCategory"-->
<!-- ></el-cascader>-->
<!-- <tree-select-->
<!-- ref="selectTree"-->
<!-- placeholder="请选择上级菜单"-->
<!-- :props="{value: 'id', label: 'name'}"-->
<!-- :options="dataList"-->
<!-- v-model="form.parentId"-->
<!-- clearable-->
<!-- />-->
<multiple-tree-select
ref="selectTree"
placeholder="请选择分类"
:options="categories"
v-model="categoryIdsList"
>
</multiple-tree-select>
<el-button type="primary" size="mini" @click="getArticleList">筛选</el-button>
</div>
</div>
Expand Down Expand Up @@ -124,14 +139,25 @@
</div>
<el-pagination
style="text-align: center"
background
:hide-on-single-page="true"
:current-page.sync="pagination.pageIndex"
:page-sizes="pagination.pageSizes"
:page-size="pagination.pageSize"
:total="pagination.total"
@current-change="currentChange"
layout="prev, pager, next">
layout="total, prev, pager, next">
</el-pagination>

<!-- <el-pagination-->
<!-- hide-on-single-page-->
<!-- background-->
<!-- layout="total, prev, pager, next"-->
<!-- :current-page.sync="pagination.pageIndex"-->
<!-- :page-size="pagination.pageSize"-->
<!-- :total="pagination.pageTotal"-->
<!-- @current-change="currentChange"-->
<!-- ></el-pagination>-->
</el-card>
</div>
</template>
Expand All @@ -142,9 +168,11 @@ import MarkdownEditor from '@/views/markdown/index'
import markdownApi from "@/api/markdown-api";
import categoryApi from "@/api/category";
import api from "@/api/file-api";
import MultipleTreeSelect from "@/components/select/MultipleTree";
export default {
name: 'articleManager',
components: {
MultipleTreeSelect,
MarkdownEditor
},
props: {
Expand Down Expand Up @@ -295,12 +323,14 @@ export default {
if(this.$route.query.categoryIds){
this.query.categoryIds = this.$route.query.categoryIds
}
console.log('this.categoryIdsList', this.categoryIdsList)
if(this.categoryIdsList.length > 0){
this.categoryIdsList.forEach(categoryIdList => {
this.query.categoryIds += categoryIdList[categoryIdList.length - 1] + ','
this.categoryIdsList.forEach(categoryId => {
this.query.categoryIds += categoryId + ','
})
this.query.categoryIds = this.query.categoryIds.substring(0, this.query.categoryIds.length - 1)
}
console.log('this.query.categoryIds', this.query.categoryIds)
this.isFilter = this.query.keyword.length > 0 || this.query.categoryIds.length > 0;
if(this.isFilter){
this.$router.push({query: {keyword: this.query.keyword, categoryIds: this.query.categoryIds}})
Expand Down Expand Up @@ -447,4 +477,7 @@ export default {
cursor: move;
}
}
/deep/.el-pagination{
padding: 15px 5px 0;
}
</style>
2 changes: 1 addition & 1 deletion src/views/setting/sys/menuManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export default {
}
},
{prop: 'createTime', label: '创建时间'},
{label: '操作', minWidth: 130, active: [
{label: '操作', minWidth: this.$pc ? 0 : 130, active: [
{name: '修改', icon: 'el-icon-edit', handle: (row) => this.handleEdit(row.id)},
{name: '删除', icon: 'el-icon-delete', color: '#ff4d4f', handle: (row) => this.handleDelete([row.id])},
],
Expand Down
4 changes: 2 additions & 2 deletions src/views/setting/sys/roleManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ export default {
{prop: 'name',label: '角色名称', minWidth: 110, sortable: 'custom'},
{prop: 'code',label: '角色标识', minWidth: 110, sortable: 'custom'},
{prop: 'remarks',label: '备注', minWidth: 110, sortable: 'custom'},
{prop: 'createTime',label: '创建时间',sortable: 'custom'},
{label: '操作', minWidth: 160, active: [
{prop: 'createTime',label: '创建时间', minWidth: 110, sortable: 'custom'},
{label: '操作', minWidth: this.$pc ? 0 : 160, active: [
{name: '修改', icon: 'el-icon-edit', handle: (row) => this.handleEdit(row.id)},
{name: '分配权限', icon: 'el-icon-finished', handle: (row) => this.authorization(row.id)},
],
Expand Down

0 comments on commit 30e84b5

Please sign in to comment.