UNPKG

magiccube-vue3

Version:

vue3-js版组件库

211 lines (181 loc) 5.58 kB
import { ref, computed, provide, inject } from 'vue' import * as utils from '../../utils/common' const getSelectedData = (list = [], selected, key) => { const arr = [] function mapList(_list = []) { _list.map(item => { if (selected.includes(item[key])) { arr.push({ name: item.name, [key]: item[key] }) } mapList(item.children || []) }) } mapList(list) return arr } const initTreeData = (data, selected = []) => { const _data = [...data] function formatterTreeData(list = []) { const arr = [] list.map(item => { const obj = { ...item, children: formatterTreeData(item.children || []), isChecked: selected.includes(item.key) } obj.isExtend = obj.isExtend || obj.children.some(n => n.isChecked || n.isExtend) arr.push(obj) }) return arr } return formatterTreeData(_data) } const TreeNode = { name: 'McTreeNode', props: { data: Array, parentData: { type: Object, default: () => { } }, multi: Boolean, keyName: { type: String, default: 'value' } }, setup(props, { emit }) { const parentRefresh = inject('parentRefresh', () => {}) const parentSingleSelect = inject('parentSingleSelect', () => {}) const parentMultiSelect = inject('parentMultiSelect', () => {}) const handleExtend = (e, item) => { e.stopPropagation() item.isExtend = !item.isExtend parentRefresh() } const handleClick = (item) => { if (props.multi) return parentSingleSelect(item) } const handleCheck = (item) => { parentMultiSelect(item) } const extendNode = (item) => ( <span class={{ 'arrow-wrap': true, 'active': item.isExtend }} onClick={(event) => handleExtend(event, item)}> <i class="arrow"></i> </span> ) const singleNode = (item) => ( <span class={{ 'name': true, 'enable-click': true, 'checked': item.isChecked }} onClick={() => handleClick(item)}>{item.name}</span> ) const multiNode = (item) => ( <> <McCheckbox v-model={item.isChecked} onChange={() => handleCheck(item)} /> <span class="name" style="margin-left:5px;">{item.name}</span> </> ) const itemNode = (item) => ( <TreeNode data={item.children} multi={props.multi} parent-data={item} key-name={props.keyName} /> ) const liNode = (item, idx) => ( <li key={idx}> <div class="wrap"> { item.children && item.children.length ? extendNode(item) : '' } { props.multi ? multiNode(item) : singleNode(item) } </div> { item.isExtend && item.children && item.children.length ? itemNode(item) : '' } </li> ) return () => ( <ul class="mc-tree"> { props.data.map(liNode) } </ul> ) } } const Tree = { name: 'McTree', props: { modelValue: Array, data: Array, multi: Boolean, keyName: { type: String, default: 'value' }, }, setup(props, { emit }) { const treeData = ref([]) const model = computed({ get() { return props.modelValue || [] }, set(value) { emit('update:modelValue', value) emit('change', getSelectedData(props.data, value, props.keyName)) } }) treeData.value = initTreeData(props.data, model.value) const handleSingleSelected = (item) => { model.value = [item[props.keyName]] setTree() } const handleMultiSelected = (item) => { const value = item[props.keyName] const arr = model.value const exist = arr.includes(value) if (exist) { arr.splice(arr.indexOf(value), 1) } else { arr.push(value) } model.value = arr setTree() } const setTree = () => { treeData.value = initTreeData(treeData.value, model.value) } const refresh = () => { treeData.value = utils.deepCopy(treeData.value) } provide('parentRefresh', refresh) provide('parentSingleSelect', handleSingleSelected) provide('parentMultiSelect', handleMultiSelected) return () => ( <div class="mc-tree"> <TreeNode data={treeData.value} multi={props.multi} keyName={props.keyName} /> </div> ) } } Tree.install = (app) => { app.component(Tree.name, Tree) } const McTree = Tree export { McTree, McTree as default }