Files
element-plus/packages/components/tree-v2/src/tree-node.vue
2021-12-04 11:20:06 +08:00

115 lines
2.7 KiB
Vue

<template>
<div
ref="node$"
class="el-tree-node"
:class="{
'is-expanded': expanded,
'is-current': current,
'is-focusable': !disabled,
'is-checked': !disabled && checked,
}"
role="treeitem"
tabindex="-1"
:aria-expanded="expanded"
:aria-disabled="disabled"
:aria-checked="checked"
:data-key="node?.key"
@click.stop="handleClick"
@contextmenu="handleContextMenu"
>
<div
class="el-tree-node__content"
:style="{ paddingLeft: `${(node.level - 1) * indent}px` }"
>
<el-icon
v-if="icon"
:class="[
{
'is-leaf': node?.isLeaf,
'is-hidden': hiddenExpandIcon,
expanded: !node?.isLeaf && expanded,
},
'el-tree-node__expand-icon',
]"
@click.stop="handleExpandIconClick"
>
<component :is="icon" />
</el-icon>
<el-checkbox
v-if="showCheckbox"
:model-value="checked"
:indeterminate="indeterminate"
:disabled="disabled"
@change="handleCheckChange"
@click.stop
/>
<el-node-content :node="node" />
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, inject } from 'vue'
import { CaretRight } from '@element-plus/icons-vue'
import ElIcon from '@element-plus/components/icon'
import ElCheckbox from '@element-plus/components/checkbox'
import ElNodeContent from './tree-node-content'
import {
ROOT_TREE_INJECTION_KEY,
NODE_CONTEXTMENU,
treeNodeEmits,
treeNodeProps,
} from './virtual-tree'
const DEFAULT_ICON = 'caret-right'
export default defineComponent({
name: 'ElTreeNode',
components: {
ElIcon,
CaretRight,
ElCheckbox,
ElNodeContent,
},
props: treeNodeProps,
emits: treeNodeEmits,
setup(props, { emit }) {
const tree = inject(ROOT_TREE_INJECTION_KEY)
const indent = computed(() => {
return tree?.props.indent ?? 16
})
const icon = computed(() => {
return tree?.props.icon ?? DEFAULT_ICON
})
const handleClick = () => {
emit('click', props.node)
}
const handleExpandIconClick = () => {
emit('toggle', props.node)
}
const handleCheckChange = (value: boolean) => {
emit('check', props.node, value)
}
const handleContextMenu = (event: Event) => {
if (tree?.instance?.vnode?.props?.['onNodeContextmenu']) {
event.stopPropagation()
event.preventDefault()
}
tree?.ctx.emit(NODE_CONTEXTMENU, event, props.node?.data, props.node)
}
return {
indent,
icon,
handleClick,
handleExpandIconClick,
handleCheckChange,
handleContextMenu,
}
},
})
</script>