123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- <template>
- <div class="cip-tree">
- <div class="cip-tree__filter">
- <el-input placeholder="请输入关键字过滤" size="small" v-model="filterText"></el-input>
- </div>
- <div class="cip-tree__header" v-if="showButton">
- <el-button v-if="isTreeAppend" type="text" icon="el-icon-circle-plus-outline" @click="appendTree">新增</el-button>
- <el-button type="text" icon="el-icon-refresh-right" @click="reload">刷新</el-button>
- <el-button type="text" icon="el-icon-bottom" @click="expandAll">展开</el-button>
- <el-button type="text" icon="el-icon-top" @click="narrowAll">折叠</el-button>
- </div>
- <el-scrollbar class="cip-tree__scrollbar">
- <el-tree class="filter-tree"
- ref="tree"
- :node-key="nodeKey"
- :default-expand-all="defaultExpandAll && !accordion"
- :current-node-key="currentNodeKey"
- :props="defaultProps"
- :expandOnClickNode="expandOnClickNode"
- :filter-node-method="filterNode"
- :data="options"
- :accordion="accordion"
- :lazy="!!lazyLoad"
- :load="lazyLoad"
- :show-checkbox="showCheckbox"
- :highlight-current="highlightCurrent"
- :render-content="renderContent"
- @node-click="nodeClick"/>
- </el-scrollbar>
- </div>
- </template>
- <script>
- import { watch, ref } from 'vue'
- import { ElTree, ElInput, ElScrollbar, ElButton } from 'element-plus'
- import { useTree } from './use-tree'
- import './index.less'
- export default {
- name: 'CipTree',
- components: { ElTree, ElInput, ElScrollbar, ElButton },
- props: {
- config: {},
- options: {},
- showButton: {
- type: Boolean,
- default: true
- }
- },
- emits: ['node-click', 'node-append', 'node-edit', 'node-remove', 'tree-reload', 'expand-all', 'narrow-all', 'handle-remote'],
- setup (props, content) {
- const { emit } = content
- const filterText = ref('')
- const tree = ref(null)
- const { config, defaultProps, level, buttonLevel, buttonList, ...useTreeOption } = useTree(props, content, tree, filterText)
- // 头部按钮
- const expandAll = () => {
- // eslint-disable-next-line
- for (const i in tree.value.store.nodesMap) {
- tree.value.store.nodesMap[i].expanded = true
- }
- }
- const narrowAll = () => {
- // eslint-disable-next-line
- for (const i in tree.value.store.nodesMap) {
- tree.value.store.nodesMap[i].expanded = false
- }
- }
- watch(filterText, val => {
- if (config.value.remoteFilter) {
- emit('handle-remote', val)
- } else {
- tree.value.filter(val)
- }
- })
- // 节点增删改函数
- const nodeAppend = (e, data, node) => {
- e.stopPropagation()
- emit('node-append', data)
- }
- const nodeEdit = (e, data, node) => {
- e.stopPropagation()
- emit('node-edit', data)
- }
- const nodeRemove = (e, data, node) => {
- e.stopPropagation()
- emit('node-remove', data)
- }
- const renderButton = (h, { node, data, store }) => {
- const buttonAttr = { size: 'mini', type: 'text' }
- const appendButton = h(ElButton,
- { ...buttonAttr, onClick: e => nodeAppend(e, data, node) }, { default: () => h('i', { class: 'el-icon-plus' }) })
- const editButton = h(ElButton,
- { ...buttonAttr, onClick: e => nodeEdit(e, data, node) }, { default: () => h('i', { class: 'el-icon-edit' }) })
- const removeButton = h(ElButton,
- { ...buttonAttr, onClick: e => nodeRemove(e, data, node) }, { default: () => h('i', { class: 'el-icon-delete' }) })
- const buttonDefault = [
- { type: 'append', component: appendButton },
- { type: 'edit', component: editButton },
- { type: 'remove', component: removeButton }]
- if (node.level > buttonLevel.value) {
- buttonDefault.splice(buttonDefault.findIndex(i => i.type === 'append'), 1)
- }
- return buttonList.value.map((item) => {
- // eslint-disable-next-line
- for (const btn of buttonDefault) {
- if (item === btn.type) {
- return btn.component
- }
- }
- })
- }
- // 自定义树节点
- const renderContent = (h, { node, data, store }) => {
- const showButton = renderButton(h, { node, data, store })
- // 外部传节点
- const renderNode = config.value.renderNode
- const operationNode = renderNode ? <span class="view-node">{renderNode?.(data)}</span> : <span class='operation'>{showButton}</span>
- const renderItem = config.value.renderItem
- const renderItemNode = renderItem ? <span class="custom-tree-node__text">{renderItem({ node, data, store })}</span> : <span class="custom-tree-node__text" title={data[defaultProps.value.label]}>
- {data[defaultProps.value.label]}
- </span>
- return <span class='custom-tree-node'>
- {renderItemNode}
- {operationNode}
- </span>
- }
- const getCheckedKeys = (leafOnly = false) => {
- return tree.value.getCheckedKeys(leafOnly)
- }
- const setCheckedKeys = (keys, leafOnly = false) => {
- return tree.value.setCheckedKeys(keys, leafOnly)
- }
- const setCurrentKey = (key) => {
- tree.value.setCurrentKey(key)
- }
- return {
- tree,
- defaultProps,
- filterText,
- renderContent,
- expandAll,
- narrowAll,
- getCheckedKeys,
- setCheckedKeys,
- setCurrentKey,
- ...useTreeOption
- }
- }
- }
- </script>
|