vue 数组件封装
组件代码:
<template>
<div class="content">
<div class="tree-item" v-for="(item, index) in data" :key="index">
<div
class="item"
:class="{
active: choice === item.id,
}"
:style="{ 'padding-left': padLeft + 'px' }"
>
<div class="icon-box" @click="expandChange(item)">
<div v-if="item.children">
<a-icon
type="right"
:class="'icon' + item.id"
v-if="item.expand === false"
/>
<a-icon
type="down"
:class="'icon' + item.id"
v-if="item.expand === true"
/>
</div>
</div>
<div class="title">
<slot name="name" :data="item">
{{ item.name }}
</slot>
</div>
</div>
// 递归调用自身
<tree
v-if="item.children && item.expand === true"
:data="item.children"
:pad-left="padLeft + 10"
:select="choice"
:search-value="selectValue"
@choiceChange="onChoiceChange"
@expandChild="expandChange"
>
<template slot="name" slot-scope="item">
<slot name="name" :data="item.data" />
</template>
</tree>
</div>
</div>
</template>
<script>
import Tree from './Tree.vue';
export default {
components: { Tree },
name: 'Tree',
props: ['data', 'padLeft', 'select', 'searchValue'],
data() {
return {
choice: this.select,
selectValue: this.searchValue,
};
},
watch: {
select: {
handler(newVal, oldVal) {
this.choice = Number(newVal);
this.$emit('choiceChange', this.choice);
},
},
searchValue: {
handler(newVal, oldVal) {
if (newVal !== '') {
this.selectValue = newVal;
}
},
},
},
methods: {
/**
* 选中状态,需要回传给父组件,改变父组件选中状态
*/
onChoice(item) {
this.choice = item.id;
this.$emit('choiceChange', this.choice);
},
/**
* 由子组件触发改变父组件的选中状态
*/
onChoiceChange(e) {
this.choice = e;
},
/**
* 展开子组件
*/
expandChange(item) {
this.$emit('expandChild', item);
},
},
created() {},
};
</script>
<style lang="less" scoped>
.content {
width: 100%;
.tree-item {
width: 100%;
margin-bottom: 5px;
.item {
width: 100%;
height: 40px;
line-height: 40px;
border-radius: 4px;
cursor: pointer;
display: flex;
padding: 0 5px;
z-index: 1;
.icon-box {
width: 10px;
height: 10x;
cursor: pointer;
margin-right: 5px;
color: #c5c5c5;
font-size: 12px;
margin-left: 3px;
}
}
.title {
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
.treenode {
width: 100%;
height: 100%;
}
}
.active {
background-color: rgba(59, 145, 255, 0.08);
}
}
}
</style>
应用:
// 搜索
<div class="search">
<a-input
ref="searchInput"
v-model="selectInput"
placeholder="搜索"
@change="select('department')"
>
<div slot="prefix">
<a-icon :component="icons[0]" class="search-icon" />
</div>
</a-input>
</div>
<tree
class="tree"
:data="userDepartment"
:pad-left="padLeft"
:select="treeChoice"
:search-value="selectInput"
@expandChild="expandChange"
@choiceChange="onChoiceChange"
v-if="auth('managementUserList')"
v-show="!subMenu('managementUserList')"
>
<template slot="name" slot-scope="item">
<router-link
class="link treenode"
:title="item.data.name"
:key="item.data.id"
tag="div"
:to="{
name: 'managementUserList',
params: { id: item.data.id },
}"
>
<div
v-if="
item.data.name.indexOf(selectInput) === -1 ||
selectInput === ''
"
class="link-name"
@click="treeNodeChoice(item.data)"
>
<span>{{ item.data.name }}</span>
</div>
<div
v-if="
item.data.name.indexOf(selectInput) !== -1 &&
selectInput !== ''
"
class="link-name"
@click="treeNodeChoice(item.data)"
>
<div>
{{
item.data.name.substr(
0,
item.data.name.indexOf(selectInput)
)
}}
</div>
<div style="color: #f50">{{ selectInput }}</div>
<div>
{{
item.data.name.substr(
item.data.name.indexOf(selectInput) +
selectInput.length
)
}}
</div>
</div>
// 操作
<a-dropdown :trigger="['click']">
<a-icon class="more-icon menu-icon" type="more" />
<a-menu slot="overlay">
<a-menu-item
v-operation:MANAGEMENT_USER_ADD_DEPT
@click="addDepart(item.data)"
>添加</a-menu-item
>
<a-menu-item
v-operation:MANAGEMENT_USER_UPDATE_DEPT
@click="addDepart(item.data, 'update')"
>编辑</a-menu-item
>
<a-menu-item
v-operation:MANAGEMENT_USER_DELETE_DEPT
@click="departRemove(item.data)"
>删除</a-menu-item
>
</a-menu>
</a-dropdown>
</router-link>
</template>
</tree>
效果: