文件目录组件
<pre><code class="language-markdown">treeContainer/index
<template>
<div style="border:1px solid #ccc;padding:0 20px;" v-if="show">
树形
<hr />
<treeItem :arr="data" />
</div>
</template>
<script>
import treeItem from "./tree-item";
export default {
name: "",
props: {
show: {
type: Boolean,
default: false,
},
},
components: { treeItem },
watch: {
show: {
handler(val, oldVal) {
console.log(oldVal);
if (!val) {
this.data = this.takeup(this.data);
}
},
deep: true, //true 深度监听
},
},
data() {
return {
data: [
{
label: "一级 1",
flag: false,
children: [
{
label: "二级 1-1",
flag: false,
children: [
{
label: "三级 1-1-1",
},
],
},
],
},
{
label: "一级 2",
flag: false,
children: [
{
label: "二级 2-1",
flag: false,
children: [
{
label: "三级 2-1-1",
},
],
},
{
label: "二级 2-2",
flag: false,
children: [
{
label: "三级 2-2-1",
},
],
},
],
},
{
label: "一级 3",
flag: false,
children: [
{
label: "二级 3-1",
flag: false,
children: [
{
label: "三级 3-1-1",
},
],
},
{
label: "二级 3-2",
flag: false,
children: [
{
label: "三级 3-2-1",
},
],
},
],
},
],
defaultProps: {
children: "children",
label: "label",
},
};
},
computed: {},
created() {},
mounted() {},
beforeDestroy() {},
methods: {
takeup(arr) {
return arr.map((item) => {
item.flag = false;
if (item.children) this.takeup(item.children);
return item;
});
},
},
};
</script>
<style>
</style></code></pre>
<pre><code class="language-markdown">
treeContainer/tree-item.vue
<template>
<div style="width:400px;">
<div v-for="(item,index) in arr" :key="index" class="tree-div">
<i @click="tagClick(item)" class="pointer" :class="[item.children ? (item.flag ? 'el-icon-folder-opened': 'el-icon-folder') : 'el-icon-tickets']"></i><span style="margin-left:12px">{{item.label}}</span>
<template>
<treeItem v-if="item.children && item.flag" :arr="item.children" class="subItem"/>
</template>
</div>
</div>
</template>
<script>
export default {
name: "treeItem",
props:{
arr:{
type:Array,
default:()=>{
return []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
beforeDestroy() {},
methods: {
tagClick(item){
this.$set(item,'flag',!item.flag)
}
},
};
</script>
<style>
.tree-div{
line-height: 30px;
}
span{
cursor: pointer;
}
.pointer{
cursor: pointer;
}
span + .subItem{
padding-left: 15px;
}
</style></code></pre>
<pre><code class="language-markdown">
treeContainer/vueClickOutSize.js
const clickOutside = {
// 初始化指令
bind(el, binding, vnode) {
console.log(vnode)
function clickHandler(e) {
// 这里判断点击的元素是否是本身,是本身,则返回
if (el.contains(e.target)) {
return false;
}
console.log(binding)
// 判断指令中是否绑定了函数
if (binding.expression) {
// 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
binding.value(e);
}
}
// 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
el.__vueClickOutside__ = clickHandler;
document.addEventListener("click", clickHandler);
},
unbind(el, binding) {
console.log(binding)
// 解除事件监听
document.removeEventListener("click", el.__vueClickOutside__);
delete el.__vueClickOutside__; // 删除属性
}
};
export default clickOutside</code></pre>
<pre><code class="language-markdown">
views/b.vue
<template>
<div style="width:500px" v-clickOutside="hideTree">
<div style="height:30px;border:1px solid #ccc;" @click="toggerShow">
{{select}}
</div>
<treeContainer :show="show"/>
</div>
</template>
<script>
import treeContainer from './treeContainer'
import clickOutside from "./treeContainer/vueClickOutSize";
export default {
name:'',
components: {treeContainer},
data(){
return {
select:null,
show:false
}
},
directives: { clickOutside },
computed: {},
watch:{},
created(){},
mounted(){},
beforeDestroy() {},
methods: {
hideTree(){
this.show=false
},
toggerShow(){
// this.show=!this.show;
this.show=true;
}
}
}
</script>
<style>
</style></code></pre>