基于 Vue 的樹形選擇組件的示例代碼
更新時(shí)間:2017年08月18日 09:47:40 作者:ZhuFaner
本篇文章主要介紹了基于 Vue 的樹形選擇組件的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
本文介紹了基于 Vue 的樹形選擇組件。分享給大家,具體如下:
系統(tǒng)要求:Vue 2
基本特性
- 完美的多級(jí)聯(lián)動(dòng)效果
- 支持無限多的分級(jí)
- 有 全選、半選、不選 三種狀態(tài)
截圖展示

代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" rel="external nofollow" type="image/x-icon">
<title>Vue Tree Select Example</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
</head>
<body>
<!-- 遞歸引用的模板 -->
<template id="one-select" style="display: none;">
<ul>
<li v-for="(node, key, index) in tree">
<div v-if="key != 'selected'">
<div v-on:click="nodeClick(node, index)" v-bind:class="[node.selected == null ? 'tree-select-null' : (node.selected == 'half' ? 'tree-select-half' : 'tree-select-full'), 'tree-select', 'inline-block']"></div>
<div class="inline-block">{{ key }}</div>
<div v-if="key != ''">
<one-select v-bind:tree="node" v-bind:isroot="false"></one-select>
</div>
</div>
</li>
</ul>
</template>
<!-- 整體樹容器 -->
<div id="tree">
<one-select v-bind:isroot="true" v-bind:tree="tree"></one-select>
</div>
<textarea id="treeDataJSON" style="display: none;">
{
"客戶管理": {
"我的客戶": {
"新分配": {},
"跟進(jìn)中": {},
"簽單客戶": {},
"長(zhǎng)期客戶": {}
},
"長(zhǎng)期客戶權(quán)限": {
"設(shè)為長(zhǎng)期客戶": {},
"還原長(zhǎng)期客戶": {}
}
},
"采購列表": {
"添加異??颓?: {},
"添加采購單": {},
"采購?fù)素泦瘟斜?: {},
"供應(yīng)商管理": {},
"供應(yīng)商聯(lián)系人": {},
"品牌列表": {
"寶潔": {},
"樂視": {
"樂視網(wǎng)": {},
"樂視手機(jī)": {
"樂視手機(jī) 1": {},
"樂視手機(jī) 2": {},
"樂視手機(jī) 3": {},
"樂視手機(jī) 4": {},
"樂視手機(jī) 5": {
"體驗(yàn)超深層級(jí)": {
"繼續(xù)體驗(yàn)超深層級(jí)": {
"依然體驗(yàn)超深層級(jí)": {},
"依然體驗(yàn)超深層級(jí) 2": {}
}
}
}
},
"樂視電視": {}
},
"可口可樂": {},
"圣象": {}
}
}
}
</textarea>
<script>
// 初始數(shù)據(jù)
var treeDataJSON = document.getElementById("treeDataJSON").value;
var treeData = JSON.parse(treeDataJSON);
Vue.component('one-select', {
name: 'one-select',
template: '#one-select',
props: ['tree', 'isroot'],
created: function() {
var realTree = Object.assign({}, this.tree);
delete realTree.selected;
if (Object.keys(realTree).length === 0) { // 判斷最低級(jí),再刷新父級(jí)
this.refreshAllParentNodes(this.$parent);
}
},
methods: {
nodeClick: function(node, index) {
if (node.selected === 'full' || node.selected === 'half') {
Vue.set(node, 'selected', null);
} else {
Vue.set(node, 'selected', 'full');
}
this.refreshAllParentNodes(self.$parent);
this.refreshAllParentNodes(this);
this.refreshAllSonNodes(this.$children[index], node.selected);
},
refreshAllSonNodes: function(node, status) {
if (node instanceof Vue && node.$children.length) {
for (index in node.$children) {
Vue.set(node.$children[index].tree, 'selected', status);
// 遞歸計(jì)算子級(jí)
this.refreshAllSonNodes(node.$children[index], status);
}
}
},
refreshAllParentNodes: function(node) {
if (node instanceof Vue) {
var status = null;
var nullCount = 0;
var halfCount = 0;
var fullCount = 0;
for (index in node.$children) {
if (typeof node.$children[index].tree.selected === 'undefined') {
nullCount++;
} else if (node.$children[index].tree.selected === null) {
nullCount++;
} else if (node.$children[index].tree.selected === 'half') {
halfCount++;
} else if (node.$children[index].tree.selected === 'full') {
fullCount++;
}
}
if (fullCount === node.$children.length) {
status = 'full';
} else if (nullCount === node.$children.length) {
status = null;
} else {
status = 'half';
}
Vue.set(node.tree, 'selected', status);
// 遞歸計(jì)算父級(jí)
this.refreshAllParentNodes(node.$parent);
}
},
log: function(o) {
console.log(o);
}
}
});
vm = new Vue({
el: '#tree',
data: {
tree: treeData
},
methods: {
// 返回最終數(shù)據(jù)
getResult: function() {
return Object.assign({}, this.tree);
}
}
});
</script>
<style>
#tree {
width: 500px;
margin: 0 auto;
margin-top: 50px;
}
li {
list-style: none;
line-height: 25px;
}
.inline-block {
display: inline-block;
}
.tree-select {
width: 13px;
height: 13px;
line-height: 16px;
margin: 3px;
display: inline-block;
vertical-align: middle;
border: 0 none;
cursor: pointer;
outline: none;
background-color: transparent;
background-repeat: no-repeat;
background-attachment: scroll;
background-image: url('selects.png');
}
.tree-select-null {
background-position: 0 0;
}
.tree-select-full {
background-position: -14px 0;
}
.tree-select-half {
background-position: -14px -28px;
}
</style>
</body>
</html>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- vue遞歸實(shí)現(xiàn)樹形組件
- Vue組件庫ElementUI實(shí)現(xiàn)表格加載樹形數(shù)據(jù)教程
- Vue遞歸組件+Vuex開發(fā)樹形組件Tree--遞歸組件的簡(jiǎn)單實(shí)現(xiàn)
- vue用遞歸組件寫樹形控件的實(shí)例代碼
- 用 Vue.js 遞歸組件實(shí)現(xiàn)可折疊的樹形菜單(demo)
- Vue.js遞歸組件構(gòu)建樹形菜單
- vuejs使用遞歸組件實(shí)現(xiàn)樹形目錄的方法
- Vue組件模板形式實(shí)現(xiàn)對(duì)象數(shù)組數(shù)據(jù)循環(huán)為樹形結(jié)構(gòu)(實(shí)例代碼)
- Vue組件tree實(shí)現(xiàn)樹形菜單
- vue實(shí)現(xiàn)自定義樹形組件的示例代碼
相關(guān)文章
vue實(shí)現(xiàn)兩個(gè)組件之間數(shù)據(jù)共享和修改操作
這篇文章主要介紹了vue實(shí)現(xiàn)兩個(gè)組件之間數(shù)據(jù)共享和修改操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11
element input輸入框自動(dòng)獲取焦點(diǎn)的實(shí)現(xiàn)
本文主要介紹了element input輸入框自動(dòng)獲取焦點(diǎn)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
Vue使用pdf-lib實(shí)現(xiàn)為文件流添加水印并預(yù)覽
這篇文章主要為大家詳細(xì)介紹了Vue如何使用pdf-lib實(shí)現(xiàn)為文件流添加水印并預(yù)覽的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-03-03
VUE實(shí)現(xiàn)表單元素雙向綁定(總結(jié))
本篇文章主要介紹了VUE實(shí)現(xiàn)表單元素雙向綁定(總結(jié)) ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08

