init
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
x<01><><EFBFBD>r<EFBFBD>0<10>{<7B>)vt<76>3<13>㸗<18>%<25><>Й><3E>kW3B0<42><30>8<EFBFBD><38><EFBFBD>]<5D>0<EFBFBD>I<EFBFBD>NO<12><><EFBFBD>o<EFBFBD><6F>v<EFBFBD><76><EFBFBD><EFBFBD>z<EFBFBD><7A><EFBFBD><EFBFBD>ª<EFBFBD>@Ks<4B>9<>GxjjKP<4B>^<5E><><EFBFBD>Y<>#<23>o<EFBFBD><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Tm<54>]<5D>m<EFBFBD>4<19>y4rHm3/<2F>*_<><0C><><1F>&<1D>m]<5D>8<EFBFBD>(<28>Q<EFBFBD><51>e<EFBFBD>L<EFBFBD><4C><EFBFBD>F<EFBFBD><46><EFBFBD><EFBFBD><EFBFBD><0C><><EFBFBD><02><><EFBFBD>MY?<3F><><EFBFBD>:<3A>E<EFBFBD>4~yGV<47>ÖAIj<1D><12>ս<EFBFBD>_<EFBFBD><5F>֍_?<3F>V\<1D><><EFBFBD>|7<>wQT<51><54>8<><38>]<5D><17><>3<EFBFBD>xϊ~>
|
||||
r<1E>2<EFBFBD><32><EFBFBD>+<2B>|q{7<>2<15><>71p`<60><><EFBFBD>ʧ<EFBFBD><CAA7>JX5Z<12><0C><><EFBFBD><08><><EFBFBD>eB˗V<CB97>S<EFBFBD>><3E>nF<6E>*y@6<><36><EFBFBD>̾K<CCBE>l&<26>c<>τ<EFBFBD>~<19>9<>p<EFBFBD>E5<45>p2j<32><6A>B<EFBFBD><42>-T<>.@<40><>
|
||||
<EFBFBD>p#Fd<46><64><EFBFBD><EFBFBD>w&<06>7<EFBFBD><0F><>l<EFBFBD>?7<><37><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,205 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "TreeNode",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LayIcon } from "@layui/icons-vue";
|
||||
import LayCheckbox from "../checkbox/index.vue";
|
||||
import { computed, Ref, useSlots } from "vue";
|
||||
import { Tree } from "./tree";
|
||||
import { Nullable } from "../../types";
|
||||
import LayTransition from "../transition/index.vue";
|
||||
import { StringOrNumber, CustomKey, CustomString } from "./tree.type";
|
||||
|
||||
export interface TreeData {
|
||||
id: CustomKey;
|
||||
title: CustomString;
|
||||
children: TreeData[];
|
||||
parentKey: Nullable<StringOrNumber>;
|
||||
isRoot: boolean;
|
||||
isChecked: boolean;
|
||||
isDisabled: boolean;
|
||||
isLeaf: boolean;
|
||||
hasNextSibling: boolean;
|
||||
parentNode: Nullable<TreeData>;
|
||||
}
|
||||
|
||||
export interface TreeNodeProps {
|
||||
tree: Tree;
|
||||
nodeList: TreeData[];
|
||||
showCheckbox: boolean;
|
||||
showLine: boolean;
|
||||
selectedKey: any;
|
||||
checkStrictly: boolean | string;
|
||||
collapseTransition: boolean;
|
||||
onlyIconControl: boolean;
|
||||
}
|
||||
|
||||
interface TreeNodeEmits {
|
||||
(e: "node-click", node: TreeData): void;
|
||||
}
|
||||
|
||||
const slots = useSlots();
|
||||
const props = defineProps<TreeNodeProps>();
|
||||
const emit = defineEmits<TreeNodeEmits>();
|
||||
|
||||
function renderLineShort(node: TreeData) {
|
||||
return (
|
||||
!node.hasNextSibling &&
|
||||
node.parentNode &&
|
||||
// 外层最后一个
|
||||
(!node.parentNode.hasNextSibling ||
|
||||
//上一层父级有延伸线
|
||||
(node.parentNode.hasNextSibling && !node.parentNode.children))
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 展开收起 icon样式
|
||||
* @param node
|
||||
*/
|
||||
const nodeIconType = (node: TreeData): string => {
|
||||
if (!props.showLine) {
|
||||
if (node.children.length > 0) {
|
||||
return "layui-tree-iconArrow ";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
if (node.children.length !== 0) {
|
||||
return !node.isLeaf ? "layui-icon-addition" : "layui-icon-subtraction";
|
||||
}
|
||||
return "layui-icon-file";
|
||||
};
|
||||
|
||||
function recursiveNodeClick(node: TreeData) {
|
||||
emit("node-click", node);
|
||||
}
|
||||
|
||||
function handleChange(checked: boolean, node: TreeData) {
|
||||
props.tree.setCheckedKeys(checked, props.checkStrictly, node);
|
||||
}
|
||||
|
||||
function handleIconClick(node: TreeData) {
|
||||
node.isLeaf = !node.isLeaf;
|
||||
}
|
||||
|
||||
function handleTitleClick(node: TreeData) {
|
||||
if (!props.onlyIconControl) {
|
||||
handleIconClick(node);
|
||||
}
|
||||
if (!node.isDisabled) {
|
||||
emit("node-click", node);
|
||||
}
|
||||
}
|
||||
|
||||
function handleRowClick(node: TreeData) {
|
||||
if (!props.showLine) {
|
||||
handleTitleClick(node);
|
||||
}
|
||||
}
|
||||
|
||||
//判断是否半选
|
||||
const isChildAllSelected = computed(() => {
|
||||
function _isChildAllSelected(node: TreeData): boolean {
|
||||
if (!props.showCheckbox) {
|
||||
return false;
|
||||
}
|
||||
let childSelectNum = 0;
|
||||
let res = false; // true为半选 false为全选
|
||||
for (const item of node.children) {
|
||||
if (item.isChecked) childSelectNum++;
|
||||
}
|
||||
if (childSelectNum > 0) node.isChecked = true; //此处的处理与 checkedKeys 有关联
|
||||
if (childSelectNum == node.children.length) {
|
||||
//继续递归向下判断
|
||||
for (const item of node.children) {
|
||||
res = _isChildAllSelected(item);
|
||||
if (res) break;
|
||||
}
|
||||
} else {
|
||||
res = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
return (node: TreeData): boolean => {
|
||||
if (props.checkStrictly) {
|
||||
return false;
|
||||
} else {
|
||||
let res = _isChildAllSelected(node);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-for="(node, nodeIndex) in nodeList"
|
||||
:key="nodeIndex"
|
||||
:class="{
|
||||
'layui-tree-set': true,
|
||||
'layui-tree-setLineShort': renderLineShort(node),
|
||||
'layui-tree-setHide': node.isRoot,
|
||||
}"
|
||||
>
|
||||
<div class="layui-tree-entry" @click="handleRowClick(node)">
|
||||
<div class="layui-tree-main">
|
||||
<span
|
||||
:class="[
|
||||
showLine && node.children.length > 0 ? 'layui-tree-icon' : '',
|
||||
{ 'layui-tree-iconClick': true },
|
||||
]"
|
||||
>
|
||||
<lay-icon
|
||||
:type="nodeIconType(node)"
|
||||
@click.stop="handleIconClick(node)"
|
||||
/>
|
||||
</span>
|
||||
<lay-checkbox
|
||||
value=""
|
||||
skin="primary"
|
||||
:modelValue="node.isChecked"
|
||||
:disabled="node.isDisabled"
|
||||
:isIndeterminate="isChildAllSelected(node)"
|
||||
@change="(checked) => handleChange(checked, node)"
|
||||
v-if="showCheckbox"
|
||||
/>
|
||||
<span
|
||||
:class="{
|
||||
'layui-tree-txt': true,
|
||||
'layui-disabled': node.isDisabled,
|
||||
'layui-this': selectedKey === node.id,
|
||||
}"
|
||||
@click.stop="handleTitleClick(node)"
|
||||
>
|
||||
<slot name="title" :data="node">{{ node.title }}</slot>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<lay-transition :enable="collapseTransition">
|
||||
<div
|
||||
v-if="node.isLeaf"
|
||||
class="layui-tree-pack layui-tree-showLine"
|
||||
style="display: block"
|
||||
>
|
||||
<tree-node
|
||||
:tree="tree"
|
||||
:node-list="node.children"
|
||||
:show-checkbox="showCheckbox"
|
||||
:show-line="showLine"
|
||||
:selected-key="selectedKey"
|
||||
:collapse-transition="collapseTransition"
|
||||
:checkStrictly="checkStrictly"
|
||||
:only-icon-control="onlyIconControl"
|
||||
@node-click="recursiveNodeClick"
|
||||
>
|
||||
<template v-if="$slots.title" v-slot:title="slotProp: { data: any }">
|
||||
<slot name="title" :data="slotProp.data"></slot>
|
||||
</template>
|
||||
</tree-node>
|
||||
</div>
|
||||
</lay-transition>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
import container from "markdown-it-container";
|
||||
import type Token from "markdown-it/lib/token";
|
||||
|
||||
type ContainerArgs = [
|
||||
typeof container,
|
||||
string,
|
||||
{ render(tokens: Token[], idx: number): string }
|
||||
];
|
||||
|
||||
export default function createContainer(klass: string): ContainerArgs {
|
||||
return [
|
||||
container,
|
||||
klass,
|
||||
{
|
||||
render(tokens, idx) {
|
||||
const token = tokens[idx];
|
||||
const info = token.info.trim().slice(klass.length).trim();
|
||||
if (token.nesting === 1) {
|
||||
return `<lay-quote style="margin-left:0px;margin-right:0px;margin-top:20px;margin-bottom:40px;">${info}`;
|
||||
} else {
|
||||
return "</lay-quote>\n";
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user