市北互联平台前端仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

437 lines
11 KiB

<!-- 输入框+选择 点击选择弹出多选树 -->
<template>
<div>
<div class="multiInput">
<div class="showPart"
tabindex="0"
@click="checked = true"
v-on:blur="checked = false"
:class="{blueBorder:checked}">
<p class="clues"
v-show="!selDataArray.length">{{placeholder}}</p>
<ul v-show="selDataArray.length"
class="checkedList">
<li class="checkedItem"
v-for="(item,index) in selDataArray"
:key="item.id+''+index">
<span>{{item.name}}</span>
<i class="el-icon-close"
@click="deleteHandle(index)"></i>
</li>
</ul>
</div>
<el-button type="button"
class="choose"
@click="handleSelect">选择</el-button>
</div>
<el-dialog :title="title"
lock-scroll
:visible="dialogVisible"
:modal="modal"
:width="'28%'"
:before-close="handleCancel"
:append-to-body="isNest"
:close-on-click-modal="false">
<div :style="{height:formHeight+'px',overflowY:'auto',overflowX:'hidden'}">
<c-tree ref="dialog_tree"
:url="url"
:params="params"
:isDialogTree="true"
:showCheckbox="showCheckbox"
:defaultExpandAll="defaultExpandAll"
:defaultExpandKeys="[0]"
:defaultNodeKey="defaultNodeKey"
:defaultCheckedKeys="checkedKeys"
:defaultOnlyLeaf="defaultOnlyLeaf"
:defaultExpandOnClickNode="defaultExpandOnClickNode"
:nodeType="nodeType"
@chechBoxClick="handleCheckBox"
@nodeClick="handleNodeClick"></c-tree>
</div>
<span slot="footer"
class="dialog-footer">
<el-button @click="handleOk">确定</el-button>
<el-button @click="handleClear">清空</el-button>
<!-- <el-button @click="handleCancel">取消</el-button> -->
</span>
</el-dialog>
</div>
</template>
<script>
import CDialog from './CDialog'
import CTree from './CTree'
import { mapGetters } from 'vuex'
export default {
components: { CDialog, CTree },
data () {
return {
dialogVisible: false, // 是否显示下拉框
selData: Object, // 选择的节点
selDataArray: [], // 多选树选择的节点数组
inputValue: this.inputModel,
substationId: this.handleId,
expandKeys: this.defaultExpandKeys, // 默认展开的节点克隆
checked: false, // 蓝色边框
checkedKeys: this.defaultCheckedKeys,
temArr: [], // 临时存放选中人员的数组
temKeys: [] // 临时存放key的数组
}
},
props: {
formKey: { // 用于接收form的key
type: String,
default: ''
},
formIndex: { // 用于接收form的index
type: Number,
default: 0
},
placeholder: { // input
type: String,
default: '请选择'
},
inputModel: { // input
type: String,
default: ''
},
handleId: {
type: String,
default: ''
},
type: { // button
type: String,
default: 'primary'
},
title: { // dialog
type: String,
default: '选择'
},
isNest: {
type: Boolean,
default: true
},
modal: {
type: Boolean,
default: true
},
url: { // tree
type: String,
required: true
},
params: { // tree
type: Object,
default () {
return {}
}
},
showCheckbox: { // tree
type: Boolean,
default: true
},
defaultCheckedKeys: { // tree
// 默认勾选节点
type: Array,
default () {
return []
}
},
defaultExpandKeys: {
// 默认展开的节点
type: Array,
default () {
return [0]
}
},
// 默认节点定为0 ,即选择树不回显
defaultNodeKey: { // tree
// 默认选中节点(节点id)
type: [Number, String]
},
defaultExpandAll: { // tree
// 默认展开全部节点
type: Boolean,
default: true
},
defaultOnlyLeaf: {
// 点击所有节点都能选中,为true时表示:只能选择叶节点
type: Boolean,
default: false
},
// 能够选择的节点类型,默认为空
nodeType: {
type: String,
default: ''
},
defaultExpandOnClickNode: {
// 默认点击节点时展开节点
type: Boolean,
default: false
},
// 判断是否自动刷新树
freshen: {
type: Boolean,
default: false
}
},
methods: {
// 选择按钮点击事件
handleSelect () {
this.dialogVisible = true
// 给临时存放数组赋值
let arr = this.selDataArray
this.temArr = this.temArr.concat(arr)
// 给临时存放key的数组赋值
let keys = this.checkedKeys
this.temKeys = this.temKeys.concat(keys)
// 渲染对话框中默认选择树的节点
this.$nextTick(() => {
this.loadData()
this.$refs['dialog_tree'].setCheckedKeys(this.checkedKeys)
})
},
// icon删除
deleteHandle (num) {
this.selDataArray.splice(num, 1)
this.checkedKeys.splice(num, 1)
this.$emit('handleDel', this.selDataArray, this.formKey, this.formIndex)
},
loadData (callback, currentKey, expandKeys) {
this.$nextTick(() => {
this.expandKeys = expandKeys
this.$refs['dialog_tree'].loadData(callback, currentKey)
})
},
handleClear () { // 清空
this.substationId = ''
this.inputValue = ''
this.selData = ''
this.selDataArray = []
this.checkedKeys = []
this.temArr = []
this.temKeys = []
this.$emit('handleClear', '', this.formKey, this.formIndex)
this.dialogVisible = false
},
// 关闭dialog
handleCancel () {
this.dialogVisible = false
this.temArr = []
this.temKeys = []
},
handleOk () {
this.dialogVisible = false
this.selDataArray = this.temArr
this.checkedKeys = this.temKeys
this.temArr = []
this.temKeys = []
this.$emit('handleSure', this.selDataArray, this.formKey, this.formIndex)
},
// 清空输入框
clearInput () {
this.selData = ''
this.inputValue = ''
},
// 复选框点击事件
handleCheckBox (data, checkedArr) {
// to do
// let filterText = this.$refs['dialog_tree'].filterText
// if (filterText) {
// if (data.children.length !== 0) {
// console.log('father', filterText)
// } else {
// console.log('children', filterText)
// }
// } else {
// console.log('blank')
// }
let checkedNoRepeat = [] // 无重复的选中数组
let keysNoRepeat = [] // 无重复的keys数组
for (let i = 0; i < checkedArr.length; i++) {
if (checkedArr[i].children.length === 0) {
let obj = { 'id': checkedArr[i].id, 'name': checkedArr[i].label }
checkedNoRepeat.push(obj)
keysNoRepeat.push(checkedArr[i].id)
}
}
this.temArr = checkedNoRepeat
this.temKeys = keysNoRepeat
// let checkedObj = { 'id': data.id, 'name': data.label }
// let id = data.id
// let index = ''
// let haven = false
// let length = this.temArr.length
// if (this.temArr.length === 0) {
// this.temArr.push(checkedObj)
// this.temKeys.push(Number(id))
// } else {
// for (let i = 0 i < length i++) {
// if (this.temArr[i].id === id) {
// haven = true
// index = i
// break
// }
// }
// if (haven) {
// this.temArr.splice(index, 1)
// this.temKeys.splice(index, 1)
// } else {
// this.temArr.push(checkedObj)
// this.temKeys.push(Number(id))
// }
// }
},
handleNodeClick (data, node) { // 点击树节点内容触发事件
// console.log(checkedArr)
// let checkedObj = { 'id': data.id, 'name': data.label }
// let id = data.id
// let index = ''
// let haven = false
// let length = this.temArr.length
// if (this.temArr.length === 0) {
// this.temArr.push(checkedObj)
// this.temKeys.push(Number(id))
// } else {
// for (let i = 0 i < length i++) {
// if (this.temArr[i].id === id) {
// haven = true
// index = i
// break
// }
// }
// if (haven) {
// this.temArr.splice(index, 1)
// this.temKeys.splice(index, 1)
// } else {
// this.temArr.push(checkedObj)
// this.temKeys.push(Number(id))
// }
// }
}
},
mounted () {
},
computed: {
formHeight () {
return this.clientHeight * 0.56
},
...mapGetters(['clientHeight'])
},
watch: {
inputValue () {
let idArr = []
let nameArr = []
if (this.substationId !== '') {
idArr = this.substationId.split(',')
}
if (this.inputValue !== null) {
nameArr = this.inputValue.split(',')
}
for (let i = 0; i < idArr.length; i++) {
this.selDataArray.push({ 'id': idArr[i], 'name': nameArr[i] })
}
this.checkedKeys = idArr
}
// dialogVisible () {
// if (!this.dialogVisible) {
// this.temArr = []
// this.temKeys = []
// }
// }
}
}
</script>
<style scoped>
.mLeft {
margin-left: 6px;
}
.blue {
color: #003585;
}
.multiInput {
width: 100%;
box-sizing: border-box;
display: flex;
}
.multiInput .showPart {
width: 197px;
min-height: 34px;
border: 1px solid #dcdfe6;
border-radius: 4px 0 0 4px;
outline: none;
}
.clues {
line-height: 34px;
padding-left: 15px;
color: #bfc2ca;
}
.multiInput .showPart .checkedList {
display: flex;
width: 100%;
padding: 5px 5px 0 5px;
flex-wrap: wrap;
box-sizing: border-box;
}
.multiInput .showPart .checkedList .checkedItem {
list-style: none;
height: 24px;
margin: 0 0 5px 5px;
padding: 0 8px;
background-color: #f0f1f4;
color: #8f9197;
font-size: 14px;
line-height: 24px;
border-radius: 4px;
display: flex;
align-items: center;
}
.multiInput .showPart .checkedList .checkedItem span {
font-size: 12px;
}
.el-icon-close {
border-radius: 50%;
background-color: #bfc2ca;
width: 13px;
height: 13px;
text-align: center;
margin-left: 5px;
cursor: pointer;
}
.el-icon-close:hover {
background-color: #8f9197;
}
.el-icon-close:before {
color: #fff;
font-size: 9px;
width: 13px;
height: 13px;
line-height: 13px;
display: block;
}
.multiInput .blueBorder {
border: 1px solid #5095fa;
}
.multiInput .choose {
border: none;
flex: 1;
border: 1px solid #dcdfe6;
border-left: none;
background: #f5f7fa;
color: #0085d0;
border-radius: 0 4px 4px 0;
outline: none;
}
.tree {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>