vue简单的CheckBox节点树

时间:2021-01-05 20:36:51

初学vue.js,恰好公司有个页面需要做一个简单的CheckBox组成的节点树,于是摸索着写了一个。

业务逻辑为:选中父节点,子节点全部选中;取消选中父节点,子节点全部取消;选中字节点,父节点选中

附例子链接写完的html页面,下载后可以直接在浏览器上观看

样式如下:

vue简单的CheckBox节点树vue简单的CheckBox节点树vue简单的CheckBox节点树

准备工作:引入vue.js

Html代码如下:div container 为显示节点树的div

 <div id="container">
<ul class="Ones">
<One v-for="One in Ones" :One.sync="One"></One>
</ul>
</div>

vue的三个模板代码如下(一级节点、二级节点、三级节点)css都是临时写的 没有做整理 有些class样式代码中也没有写。

 <script type="x/template" id="One">//一级节点模板
<li class="One">
<div class="tree_div">
<input :id="One.Code" type="checkbox" v-model="oneSelect" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:red;" :for="One.Code">{{ One.FuncName }}</label>
</div> <ul class="Twos">
<Two v-for="Two in One.Twos" :Two.sync="Two"></Two>
</ul>
</li>
</script> <script type="x/template" id="Two">//二级节点模板
<li class="Two">
<div class="tree_div">
<input :id="Two.Code" type="checkbox" v-model="twoSelect" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:blue;" :for="Two.Code">{{ Two.FuncName }}</label>
</div>
<ul class="Threes">
<Three v-for="Three in Two.Threes" :Three.sync="Three"></Three>
</ul>
</li>
</script> <script type="x/template" id="Three">//三级节点模板
<li class="Three">
<div class="tree_div">
<input :id="Three.Code" type="checkbox" v-model="threeSelect" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:green;" :for="Three.Code">{{ Three.FuncName }}</label>
</div>
<div class="Fours" style="margin-left:20px;max-width:400px;margin-top:4px;">
<span style="margin-right:10px;" v-for="Four in Three.Fours">
<input :id="Four.Code" type="checkbox" v-model="Four.Selected" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:darkslateblue;" :for="Four.Code">{{ Four.FuncName }}</label>
</span> </div>
</li>
</script>

vue的组件代码如下:(代码写的比较low,希望各位大大指正)

     //一级节点 组件
Vue.component('One', {
props: ['One'],
template: '#One',
computed: {
oneSelect: {
get: function () {//点击子节点时触发(子节点选中,父节点也选中)
var Selected;
if (this.One.Twos && this.One.Twos.length > 0) {
Selected = this.One.Twos.some(function (Two) {
if (Two.Threes && Two.Threes.length > 0) {
Two.Selected = Two.Threes.some(function (Three) {
if (Three.Fours && Three.Fours.length > 0) {
Three.Selected = Three.Fours.some(function (Four) {
return Four.Selected;
});
}
return Three.Selected;
});
}
return Two.Selected;
});
} else {
Selected = this.One.Selected;
}
return Selected; },
set: function (value) {//点击节点本身时触发(选中、取消 所有子节点)
if (this.One.Twos && this.One.Twos.length > 0) {
this.One.Twos.forEach(function (Two) {
Two.Selected = value;
if (Two.Threes && Two.Threes.length > 0) {
Two.Threes.forEach(function (Three) {
Three.Selected = value;
if (Three.Fours && Three.Fours.length > 0) {
Three.Fours.forEach(function (Four) {
Four.Selected = value;
})
}
})
}
});
}
this.One.Selected = value;
}
}
}
}) //二级节点 组件
Vue.component('Two', {
props: ['Two'],
template: '#Two',
computed: {
twoSelect: {
get: function () {//点击子节点时触发(子节点选中,父节点也选中)
var Selected;
if (this.Two.Threes && this.Two.Threes.length > 0) {
Selected = this.Two.Threes.some(function (Three) {
if (Three.Fours && Three.Fours.length > 0) {
Three.Selected = Three.Fours.some(function (Four) {
return Four.Selected;
});
}
return Three.Selected;
});
} else {
Selected = this.Two.Selected;
}
return Selected;
},
set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) if (this.Two.Threes && this.Two.Threes.length > 0) {
this.Two.Threes.forEach(function (Three) {
Three.Selected = value;
if (Three.Fours && Three.Fours.length > 0) {
Three.Fours.forEach(function (Four) {
Four.Selected = value;
})
}
});
}
this.Two.Selected = value;
}
}
}
}) //三级节点 组件
Vue.component('Three', {
props: ['Three'],
template: '#Three',
computed: {
threeSelect: {
get: function () {//点击子节点时触发(子节点选中,父节点也选中)
var Selected;
if (this.Three.Fours && this.Three.Fours.length > 0) {
Selected = this.Three.Fours.some(function (Four) {
return Four.Selected;
});
} else {
Selected = this.Three.Selected;
}
return Selected;
},
set: function (value) {//点击节点本身时触发(选中、取消 所有子节点)
if (this.Three.Fours && this.Three.Fours.length > 0) {
this.Three.Fours.forEach(function (Four) {
Four.Selected = value;
});
}
this.Three.Selected = value;
}
}
}
})

最后的就是vue的数据绑定代码了:

    var app = new Vue({
el: '#container',
data: {
Ones: [{ Code: 1,
FuncName: '一级节点1',
Twos: [
{
Code: 2,
Selected: false,
FuncName: '二级节点1',
Threes: [
{
Code: 3,
Selected: true,
FuncName: 'joe的商品2'
},
{
Code: 4,
Selected: false,
FuncName: '三级节点1',
Fours: [{
Code: 5,
Selected: true,
FuncName: '四级节点1'
}, {
Code: 6,
Selected: true,
FuncName: '四级节点2'
}]
}
]
},
{
Code: 7,
Selected: false,
FuncName: '二级节点2'
}
],
Selected: false
}]
}
});

整体页面代码如下

 <html>

 <head>
<title></title>
</head> <body> <div id="container">
<ul class="Ones">
<One v-for="One in Ones" :One.sync="One"></One>
</ul>
</div> <script src="vue.min.js"></script> <script type="x/template" id="One">//一级节点模板
<li class="One">
<div class="tree_div">
<input :id="One.Code" type="checkbox" v-model="oneSelect" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:red;" :for="One.Code">{{ One.FuncName }}</label>
</div> <ul class="Twos">
<Two v-for="Two in One.Twos" :Two.sync="Two"></Two>
</ul>
</li>
</script> <script type="x/template" id="Two">//二级节点模板
<li class="Two">
<div class="tree_div">
<input :id="Two.Code" type="checkbox" v-model="twoSelect" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:blue;" :for="Two.Code">{{ Two.FuncName }}</label>
</div>
<ul class="Threes">
<Three v-for="Three in Two.Threes" :Three.sync="Three"></Three>
</ul>
</li>
</script> <script type="x/template" id="Three">//三级节点模板
<li class="Three">
<div class="tree_div">
<input :id="Three.Code" type="checkbox" v-model="threeSelect" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:green;" :for="Three.Code">{{ Three.FuncName }}</label>
</div>
<div class="Fours" style="margin-left:20px;max-width:400px;margin-top:4px;">
<span style="margin-right:10px;" v-for="Four in Three.Fours">
<input :id="Four.Code" type="checkbox" v-model="Four.Selected" style="margin-top:0px !important; margin-bottom:4px !important;">
<label style="font-size:16px !important;color:darkslateblue;" :for="Four.Code">{{ Four.FuncName }}</label>
</span> </div>
</li>
</script>
<script type="text/javascript">
//一级节点 组件
Vue.component('One', {
props: ['One'],
template: '#One',
computed: {
oneSelect: {
get: function () {//点击子节点时触发(子节点选中,父节点也选中)
var Selected;
if (this.One.Twos && this.One.Twos.length > 0) {
Selected = this.One.Twos.some(function (Two) {
if (Two.Threes && Two.Threes.length > 0) {
Two.Selected = Two.Threes.some(function (Three) {
if (Three.Fours && Three.Fours.length > 0) {
Three.Selected = Three.Fours.some(function (Four) {
return Four.Selected;
});
}
return Three.Selected;
});
}
return Two.Selected;
});
} else {
Selected = this.One.Selected;
}
return Selected; },
set: function (value) {//点击节点本身时触发(选中、取消 所有子节点)
if (this.One.Twos && this.One.Twos.length > 0) {
this.One.Twos.forEach(function (Two) {
Two.Selected = value;
if (Two.Threes && Two.Threes.length > 0) {
Two.Threes.forEach(function (Three) {
Three.Selected = value;
if (Three.Fours && Three.Fours.length > 0) {
Three.Fours.forEach(function (Four) {
Four.Selected = value;
})
}
})
}
});
}
this.One.Selected = value;
}
}
}
}) //二级节点 组件
Vue.component('Two', {
props: ['Two'],
template: '#Two',
computed: {
twoSelect: {
get: function () {//点击子节点时触发(子节点选中,父节点也选中)
var Selected;
if (this.Two.Threes && this.Two.Threes.length > 0) {
Selected = this.Two.Threes.some(function (Three) {
if (Three.Fours && Three.Fours.length > 0) {
Three.Selected = Three.Fours.some(function (Four) {
return Four.Selected;
});
}
return Three.Selected;
});
} else {
Selected = this.Two.Selected;
}
return Selected;
},
set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) if (this.Two.Threes && this.Two.Threes.length > 0) {
this.Two.Threes.forEach(function (Three) {
Three.Selected = value;
if (Three.Fours && Three.Fours.length > 0) {
Three.Fours.forEach(function (Four) {
Four.Selected = value;
})
}
});
}
this.Two.Selected = value;
}
}
}
}) //三级节点 组件
Vue.component('Three', {
props: ['Three'],
template: '#Three',
computed: {
threeSelect: {
get: function () {//点击子节点时触发(子节点选中,父节点也选中)
var Selected;
if (this.Three.Fours && this.Three.Fours.length > 0) {
Selected = this.Three.Fours.some(function (Four) {
return Four.Selected;
});
} else {
Selected = this.Three.Selected;
}
return Selected;
},
set: function (value) {//点击节点本身时触发(选中、取消 所有子节点)
if (this.Three.Fours && this.Three.Fours.length > 0) {
this.Three.Fours.forEach(function (Four) {
Four.Selected = value;
});
}
this.Three.Selected = value;
}
}
}
})
var app = new Vue({
el: '#container',
data: {
Ones: [{ Code: 1,
FuncName: '一级节点1',
Twos: [
{
Code: 2,
Selected: false,
FuncName: '二级节点1',
Threes: [
{
Code: 3,
Selected: true,
FuncName: 'joe的商品2'
},
{
Code: 4,
Selected: false,
FuncName: '三级节点1',
Fours: [{
Code: 5,
Selected: true,
FuncName: '四级节点1'
}, {
Code: 6,
Selected: true,
FuncName: '四级节点2'
}]
}
]
},
{
Code: 7,
Selected: false,
FuncName: '二级节点2'
}
],
Selected: false
}]
}
}); </script>
</body>
</html>

代码写的比较粗糙,望各位大大指正。^_^