vue-treeselect绑值、回显常见问题
最近vue-treeselect使用的比较多,分享一波
可以用在表单里,也可以用在可编辑的表格内
这里以表单里的举例
在main.js中引入
import ElTreeSelect from ‘el-tree-select'
import Treeselect from ‘@riophae/vue-treeselect'
import ‘@riophae/vue-treeselect/dist/vue-treeselect.css'
Vue.use(ElTreeSelect)
Vue.component(‘TreeSelect', Treeselect)
最主要的几点就是
1、绑值:value=“form.astdeptId”,主要绑的就是id或者code,通过id或code找到对应的label回显
2、options是数据源,正常调接口获取就行了
3、append-to-body="true"这个最好加上,可能会遇到下拉的弹窗打不开或者只有一点点高的情况
4、normalizer就是把我们自己的后端返的数据格式按树插件需要的格式转换
5、select点击事件里赋值
6、插槽slot=“option-label” 是下拉框的值
7、插槽slot=“value-label” 是输入框回显的值
<el-form-item label="上级部门:">
<TreeSelect
:value="form.astdeptId"
:options="zoneCodeOptions"
clearable
no-options-text="暂无可用选项"
:append-to-body="true"
:normalizer="tenantIdnormalizer"
open-direction="bottom"
placeholder="请选择父级节点"
@select="node => tenantIdHandleSelect(node)"
>
<div slot="option-label" slot-scope="{ node }" style="white-space: nowrap; font-size: 14px">
{{ node.raw.name ? node.raw.name : '' }}
</div>
<div slot="value-label" slot-scope="{ node }">{{ node.raw.name ? node.raw.name : '' }}</div>
</TreeSelect>
</el-form-item>
打印node,拿对应的id,label和children
tenantIdnormalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.astdeptId,
label: node.name,
children: node.children,
}
},
赋值给 this.form.astdeptId
tenantIdHandleSelect(node) {
this.form.astdeptId = node.astdeptId
this.form.name = node.name
},
vue3-treeselect绑定数据有bug问题
问题,Vue3-treeSelect,在第一次绑定值的时候没有问题,但是第二次开始无法绑定,知道各位有没有什么好的解决方法,我比较菜搞不太懂。
所以,我重写了个简单的,没那么多功能的就只有v-model,options,placeholder,normalizer4个参数,下面把代码贴出来,需要注意的是,placeholder,normalizer这俩是非必须项,如果不需要可以不写,
placeholder不写,默认是空,normalizer不写默认是
{
id: ‘id',
label: ‘label',
children: ‘children',
}
不过大佬们看看代码估计也就懂了
<template>
<div class="tree-container">
<el-select
ref="singleTree"
v-model="singleSelectTreeVal"
class="vab-tree-select"
clearable
:placeholder="placeholder"
popper-class="select-tree-popper"
value-key="id"
@clear="selectTreeClearHandle('single')"
>
<el-option :value="singleSelectTreeKey">
<el-tree
id="singleSelectTree"
ref="singleSelectTree"
:current-node-key="singleSelectTreeKey"
:data="selectTreeData"
:default-expanded-keys="selectTreeDefaultSelectedKeys"
:highlight-current="true"
:node-key="selectTreeDefaultProps.id"
:props="selectTreeDefaultProps"
@node-click="selectTreeNodeClick"
>
<template #defalut="{ node }" class="vab-custom-tree-node">
<span class="vab-tree-item">{{ node.label }}</span>
</template>
</el-tree>
</el-option>
</el-select>
</div>
</template>
<script>
import { onBeforeMount, onMounted, reactive, toRefs, watch } from 'vue'
export default {
name: 'VabSingleSelectTree',
props: {
//这里是绑定参数
modelValue: {
type: Number,
default: undefined,
},
//这里是数组
options: {
type: Array,
default: undefined,
},
//placeholder
placeholder: {
type: String,
default: '',
},
//这里是转换方法
normalizer: {
type: Object,
default: undefined,
},
},
emits: ['update:modelValue'],
// { emit }
setup(props, { emit }) {
//$emit('update:modelValue', $event.target.value)
const state = reactive({
singleSelectTree: null,
singleTree: null,
singleSelectTreeKey: props.modelValue,
singleSelectTreeVal: null,
selectTreeData: props.options,
selectTreeDefaultSelectedKeys: [],
selectTreeDefaultProps: props.normalizer,
})
onBeforeMount(() => {
defaultNormalizer()
})
//首次加载
onMounted(() => {
initialize()
})
watch(props, (newValue) => {
//这里props里的值不会自动赋值给state中常量,只有第一次过来的时候才会赋值之后需要手动赋值
state.singleSelectTreeKey = newValue.modelValue
state.selectTreeData = newValue.options
initialize()
})
//防止不写Normalizer报错
const defaultNormalizer = () => {
if (!state.selectTreeDefaultProps) {
state.selectTreeDefaultProps = {
id: 'id',
label: 'label',
children: 'children',
}
}
}
//初始化
const initialize = () => {
if (state.singleSelectTreeKey != null) {
state['singleSelectTree'].setCurrentKey(state.singleSelectTreeKey) // 设置默认选中
let node = state['singleSelectTree'].getNode(
state.singleSelectTreeKey
)
state.singleSelectTreeVal =
node.data[state.selectTreeDefaultProps['label']]
state.singleSelectTreeKey =
node.data[state.selectTreeDefaultProps['id']]
} else {
selectTreeClearHandle()
}
}
// 清除单选树选中
const selectTreeClearHandle = () => {
state.selectTreeDefaultSelectedKeys = []
clearSelected()
emit('update:modelValue', null)
state.singleSelectTreeVal = ''
state.singleSelectTreeKey = null
state['singleSelectTree'].setCurrentKey(null) // 设置默认选中
}
const clearSelected = () => {
const allNode = document.querySelectorAll(
'#singleSelectTree .el-tree-node'
)
allNode.forEach((element) => element.classList.remove('is-current'))
}
const selectTreeNodeClick = (data) => {
state.singleSelectTreeVal = data[state.selectTreeDefaultProps['label']]
state.singleSelectTreeKey = data[state.selectTreeDefaultProps['id']]
emit('update:modelValue', state.singleSelectTreeKey)
state['singleTree'].blur()
//data
// if (data.rank >= this.selectLevel) {
//
// }
}
return {
...toRefs(state),
selectTreeClearHandle,
selectTreeNodeClick,
defaultNormalizer,
initialize,
}
},
}
</script>
<style scoped></style>
.vab-hey-message {
@mixin vab-hey-message {
min-width: 246px;
padding: 15px;
background-color: $base-color-white;
border-color: $base-color-white;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
.el-message__content {
padding-right: $base-padding;
color: #34495e;
}
.el-icon-close {
color: #34495e;
&:hover {
opacity: 0.8;
}
}
}
有需要的各位随意取用吧
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。