UNPKG

magiccube-vue3

Version:

vue3-js版组件库

222 lines (217 loc) 7.27 kB
import '../../style/permission-tree.less' import { ref, computed, provide, inject, watchEffect, watch } from 'vue' import * as utils from '../../utils/common' /** * 更新祖级的treeData,可以使用provide和inject */ const TreeRender = { name: 'TreeRender', props: { data: Array, currentText: [String, Number], keyName: { type: String, default: 'permissionId' } }, setup(props, { emit, slots }) { /** * +- 处理 */ const forefatherRefresh = inject('forefatherRefresh', () => { }) const handleExtend = (item) => { item.isExtend = !item.isExtend forefatherRefresh() } const extendNode = (item) => ( <div class="mc-permission-tree__panel--node--content--symbol" onClick={() => handleExtend(item)}> {item.isExtend ? '-' : '+'} </div> ) /** * √ 处理 */ const forefatherCheckboxClick = inject('forefatherCheckboxClick', () => { }) const handleCheck = (item) => { forefatherCheckboxClick(item) } const checkboxNode = (item) => { return ( <McCheckbox v-model={item.isChecked} onChange={() => handleCheck(item)}></McCheckbox> ) } /** * text 处理 */ const forefatherTextClick = inject('forefatherTextClick', () => { }) const handleTextClick = (item) => { forefatherTextClick(item) } const textNode = (item) => ( <span class={{ 'mc-permission-tree__panel--node--content--text': true, 'mc-permission-tree__panel--node--content--text-clickable': true, 'mc-permission-tree__panel--node--content--text-active': item[props.keyName] === props.currentText, }} onClick={() => handleTextClick(item)}> {item.permissionName} <span style="margin-left: 8px">id:{item.permissionId}</span> </span> ) /** * 编辑按钮 处理 */ const forefatherEdit = inject('forefatherEdit', () => { }) const handleEdit = (item) => { forefatherEdit(item) } const editButtonNode = (item) => ( <span class="mc-permission-tree__panel--node--content--edit" onClick={() => handleEdit(item)}>编辑</span> ) /** * 复制按钮 处理 */ const copyBottuonNode = (item) => ( <span class="mc-permission-tree__panel--node--content--copy" v-copy={item.permissionKey}>复制</span> ) /** * 递归 处理 */ const newPanel = (item) => ( <TreeRender data={item.children} currentText={props.currentText} /> ) /** * liNode 处理 */ const liNode = (item, idx) => ( <li key={idx} class="mc-permission-tree__panel--node"> <div class={{ 'mc-permission-tree__panel--node--content': true, 'mc-permission-tree__panel--node--placeholder': !item.children?.length }}> {item.children?.length ? extendNode(item) : ''} {checkboxNode(item)} {textNode(item)} {editButtonNode(item)} {copyBottuonNode(item)} </div> { item.children?.length && item.isExtend ? newPanel(item) : '' } </li> ) return () => ( <ul class="mc-permission-tree__panel"> {props.data.map(liNode)} </ul> ) } } const PermissionTree = { name: 'McPermissionTree', props: { data: { type: Array, default: () => [] }, /** * 表示选中的条目的key值(id)的集合 */ modelValue: { type: Array, default: () => [] }, keyName: { type: String, default: 'permissionId' }, currentTextValue: [Number, String], initData: Boolean }, emits: ['trigger', 'update:modelValue', 'edit', 'update:currentTextValue'], setup(props, { emit, slots }) { /** * 初始treeData * 每次刚打开弹窗,用最初的props.data */ const treeData = ref([]) watchEffect(() => { if (props.initData) { treeData.value = utils.deepCopy(props.data) } }) const model = computed({ get() { return props.modelValue }, set(val) { emit('update:modelValue', val) } }) const resetTreeData = (data, selected) => { return data.map(item => { const obj = { ...item, isChecked: selected.includes(item[props.keyName]), children: resetTreeData(item.children, selected), } if (obj.buttons) obj.buttons = resetTreeData(item.buttons, selected) return obj }) } watch(() => props.modelValue, (n, o) => { treeData.value = resetTreeData(treeData.value, model.value) }) /** * 点击+-时,item的isExtend改变,更新祖级的treeData.value */ const refresh = () => { treeData.value = utils.deepCopy(treeData.value) } provide('forefatherRefresh', refresh) /** * 点击checkbox后,item的isChecked改变,需要修改model.value的值(随后会根据watch改变treeData) */ const checkboxClick = (item) => { const _k = item[props.keyName] const ary = [...model.value] ary.includes(_k) ? ary.splice(ary.indexOf(_k), 1) : ary.push(_k) model.value = [...ary] } provide('forefatherCheckboxClick', checkboxClick) /** * 点击文本后,会抛出点击事件; */ const currentText = computed({ get() { return props.currentTextValue || '' }, set(val) { emit('update:currentTextValue', val) } }) const textClick = (item) => { currentText.value = item[props.keyName] emit('trigger', item) } provide('forefatherTextClick', textClick) /** * 点击编辑后,会抛出编辑事件; */ const handleEdit = (item) => { emit('edit', item) } provide('forefatherEdit', handleEdit) return () => ( <div class="mc-permission-tree"> <TreeRender data={treeData.value} currentText={currentText.value} /> </div> ) } } PermissionTree.install = Vue => { Vue.component(PermissionTree.name, PermissionTree) } const McPermissionTree = PermissionTree export { McPermissionTree, McPermissionTree as default }