初学vue.js,恰好公司有个页面需要做一个简单的CheckBox组成的节点树,于是摸索着写了一个。
业务逻辑为:选中父节点,子节点全部选中;取消选中父节点,子节点全部取消;选中字节点,父节点选中。
附例子链接:写完的html页面,下载后可以直接在浏览器上观看。
样式如下:
准备工作:引入vue.js
Html代码如下:div container 为显示节点树的div
1 <div id="container"> 2 <ul class="Ones"> 3 <One v-for="One in Ones" :One.sync="One"></One> 4 </ul> 5 </div>
vue的三个模板代码如下(一级节点、二级节点、三级节点)css都是临时写的 没有做整理 有些class样式代码中也没有写。
1 <script type="x/template" id="One">//一级节点模板 2 <li class="One"> 3 <div class="tree_div"> 4 <input :id="One.Code" type="checkbox" v-model="oneSelect" style="margin-top:0px !important; margin-bottom:4px !important;"> 5 <label style="font-size:16px !important;color:red;" :for="One.Code">{{ One.FuncName }}</label> 6 </div> 7 8 <ul class="Twos"> 9 <Two v-for="Two in One.Twos" :Two.sync="Two"></Two> 10 </ul> 11 </li> 12 </script> 13 14 15 <script type="x/template" id="Two">//二级节点模板 16 <li class="Two"> 17 <div class="tree_div"> 18 <input :id="Two.Code" type="checkbox" v-model="twoSelect" style="margin-top:0px !important; margin-bottom:4px !important;"> 19 <label style="font-size:16px !important;color:blue;" :for="Two.Code">{{ Two.FuncName }}</label> 20 </div> 21 <ul class="Threes"> 22 <Three v-for="Three in Two.Threes" :Three.sync="Three"></Three> 23 </ul> 24 </li> 25 </script> 26 27 28 <script type="x/template" id="Three">//三级节点模板 29 <li class="Three"> 30 <div class="tree_div"> 31 <input :id="Three.Code" type="checkbox" v-model="threeSelect" style="margin-top:0px !important; margin-bottom:4px !important;"> 32 <label style="font-size:16px !important;color:green;" :for="Three.Code">{{ Three.FuncName }}</label> 33 </div> 34 <div class="Fours" style="margin-left:20px;max-400px;margin-top:4px;"> 35 <span style="margin-right:10px;" v-for="Four in Three.Fours"> 36 <input :id="Four.Code" type="checkbox" v-model="Four.Selected" style="margin-top:0px !important; margin-bottom:4px !important;"> 37 <label style="font-size:16px !important;color:darkslateblue;" :for="Four.Code">{{ Four.FuncName }}</label> 38 </span> 39 40 </div> 41 </li> 42 </script>
vue的组件代码如下:(代码写的比较low,希望各位大大指正)
1 //一级节点 组件 2 Vue.component('One', { 3 props: ['One'], 4 template: '#One', 5 computed: { 6 oneSelect: { 7 get: function () {//点击子节点时触发(子节点选中,父节点也选中) 8 var Selected; 9 if (this.One.Twos && this.One.Twos.length > 0) { 10 Selected = this.One.Twos.some(function (Two) { 11 if (Two.Threes && Two.Threes.length > 0) { 12 Two.Selected = Two.Threes.some(function (Three) { 13 if (Three.Fours && Three.Fours.length > 0) { 14 Three.Selected = Three.Fours.some(function (Four) { 15 return Four.Selected; 16 }); 17 } 18 return Three.Selected; 19 }); 20 } 21 return Two.Selected; 22 }); 23 } else { 24 Selected = this.One.Selected; 25 } 26 return Selected; 27 28 }, 29 set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) 30 if (this.One.Twos && this.One.Twos.length > 0) { 31 this.One.Twos.forEach(function (Two) { 32 Two.Selected = value; 33 if (Two.Threes && Two.Threes.length > 0) { 34 Two.Threes.forEach(function (Three) { 35 Three.Selected = value; 36 if (Three.Fours && Three.Fours.length > 0) { 37 Three.Fours.forEach(function (Four) { 38 Four.Selected = value; 39 }) 40 } 41 }) 42 } 43 }); 44 } 45 this.One.Selected = value; 46 } 47 } 48 } 49 }) 50 51 //二级节点 组件 52 Vue.component('Two', { 53 props: ['Two'], 54 template: '#Two', 55 computed: { 56 twoSelect: { 57 get: function () {//点击子节点时触发(子节点选中,父节点也选中) 58 var Selected; 59 if (this.Two.Threes && this.Two.Threes.length > 0) { 60 Selected = this.Two.Threes.some(function (Three) { 61 if (Three.Fours && Three.Fours.length > 0) { 62 Three.Selected = Three.Fours.some(function (Four) { 63 return Four.Selected; 64 }); 65 } 66 return Three.Selected; 67 }); 68 } else { 69 Selected = this.Two.Selected; 70 } 71 return Selected; 72 }, 73 set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) 74 75 if (this.Two.Threes && this.Two.Threes.length > 0) { 76 this.Two.Threes.forEach(function (Three) { 77 Three.Selected = value; 78 if (Three.Fours && Three.Fours.length > 0) { 79 Three.Fours.forEach(function (Four) { 80 Four.Selected = value; 81 }) 82 } 83 }); 84 } 85 this.Two.Selected = value; 86 } 87 } 88 } 89 }) 90 91 //三级节点 组件 92 Vue.component('Three', { 93 props: ['Three'], 94 template: '#Three', 95 computed: { 96 threeSelect: { 97 get: function () {//点击子节点时触发(子节点选中,父节点也选中) 98 var Selected; 99 if (this.Three.Fours && this.Three.Fours.length > 0) { 100 Selected = this.Three.Fours.some(function (Four) { 101 return Four.Selected; 102 }); 103 } else { 104 Selected = this.Three.Selected; 105 } 106 return Selected; 107 }, 108 set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) 109 if (this.Three.Fours && this.Three.Fours.length > 0) { 110 this.Three.Fours.forEach(function (Four) { 111 Four.Selected = value; 112 }); 113 } 114 this.Three.Selected = value; 115 } 116 } 117 } 118 })
最后的就是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 }] } });
整体页面代码如下:
1 <html> 2 3 <head> 4 <title></title> 5 </head> 6 7 <body> 8 9 <div id="container"> 10 <ul class="Ones"> 11 <One v-for="One in Ones" :One.sync="One"></One> 12 </ul> 13 </div> 14 15 <script src="vue.min.js"></script> 16 17 18 <script type="x/template" id="One">//一级节点模板 19 <li class="One"> 20 <div class="tree_div"> 21 <input :id="One.Code" type="checkbox" v-model="oneSelect" style="margin-top:0px !important; margin-bottom:4px !important;"> 22 <label style="font-size:16px !important;color:red;" :for="One.Code">{{ One.FuncName }}</label> 23 </div> 24 25 <ul class="Twos"> 26 <Two v-for="Two in One.Twos" :Two.sync="Two"></Two> 27 </ul> 28 </li> 29 </script> 30 31 32 <script type="x/template" id="Two">//二级节点模板 33 <li class="Two"> 34 <div class="tree_div"> 35 <input :id="Two.Code" type="checkbox" v-model="twoSelect" style="margin-top:0px !important; margin-bottom:4px !important;"> 36 <label style="font-size:16px !important;color:blue;" :for="Two.Code">{{ Two.FuncName }}</label> 37 </div> 38 <ul class="Threes"> 39 <Three v-for="Three in Two.Threes" :Three.sync="Three"></Three> 40 </ul> 41 </li> 42 </script> 43 44 45 <script type="x/template" id="Three">//三级节点模板 46 <li class="Three"> 47 <div class="tree_div"> 48 <input :id="Three.Code" type="checkbox" v-model="threeSelect" style="margin-top:0px !important; margin-bottom:4px !important;"> 49 <label style="font-size:16px !important;color:green;" :for="Three.Code">{{ Three.FuncName }}</label> 50 </div> 51 <div class="Fours" style="margin-left:20px;max-400px;margin-top:4px;"> 52 <span style="margin-right:10px;" v-for="Four in Three.Fours"> 53 <input :id="Four.Code" type="checkbox" v-model="Four.Selected" style="margin-top:0px !important; margin-bottom:4px !important;"> 54 <label style="font-size:16px !important;color:darkslateblue;" :for="Four.Code">{{ Four.FuncName }}</label> 55 </span> 56 57 </div> 58 </li> 59 </script> 60 <script type="text/javascript"> 61 //一级节点 组件 62 Vue.component('One', { 63 props: ['One'], 64 template: '#One', 65 computed: { 66 oneSelect: { 67 get: function () {//点击子节点时触发(子节点选中,父节点也选中) 68 var Selected; 69 if (this.One.Twos && this.One.Twos.length > 0) { 70 Selected = this.One.Twos.some(function (Two) { 71 if (Two.Threes && Two.Threes.length > 0) { 72 Two.Selected = Two.Threes.some(function (Three) { 73 if (Three.Fours && Three.Fours.length > 0) { 74 Three.Selected = Three.Fours.some(function (Four) { 75 return Four.Selected; 76 }); 77 } 78 return Three.Selected; 79 }); 80 } 81 return Two.Selected; 82 }); 83 } else { 84 Selected = this.One.Selected; 85 } 86 return Selected; 87 88 }, 89 set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) 90 if (this.One.Twos && this.One.Twos.length > 0) { 91 this.One.Twos.forEach(function (Two) { 92 Two.Selected = value; 93 if (Two.Threes && Two.Threes.length > 0) { 94 Two.Threes.forEach(function (Three) { 95 Three.Selected = value; 96 if (Three.Fours && Three.Fours.length > 0) { 97 Three.Fours.forEach(function (Four) { 98 Four.Selected = value; 99 }) 100 } 101 }) 102 } 103 }); 104 } 105 this.One.Selected = value; 106 } 107 } 108 } 109 }) 110 111 //二级节点 组件 112 Vue.component('Two', { 113 props: ['Two'], 114 template: '#Two', 115 computed: { 116 twoSelect: { 117 get: function () {//点击子节点时触发(子节点选中,父节点也选中) 118 var Selected; 119 if (this.Two.Threes && this.Two.Threes.length > 0) { 120 Selected = this.Two.Threes.some(function (Three) { 121 if (Three.Fours && Three.Fours.length > 0) { 122 Three.Selected = Three.Fours.some(function (Four) { 123 return Four.Selected; 124 }); 125 } 126 return Three.Selected; 127 }); 128 } else { 129 Selected = this.Two.Selected; 130 } 131 return Selected; 132 }, 133 set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) 134 135 if (this.Two.Threes && this.Two.Threes.length > 0) { 136 this.Two.Threes.forEach(function (Three) { 137 Three.Selected = value; 138 if (Three.Fours && Three.Fours.length > 0) { 139 Three.Fours.forEach(function (Four) { 140 Four.Selected = value; 141 }) 142 } 143 }); 144 } 145 this.Two.Selected = value; 146 } 147 } 148 } 149 }) 150 151 //三级节点 组件 152 Vue.component('Three', { 153 props: ['Three'], 154 template: '#Three', 155 computed: { 156 threeSelect: { 157 get: function () {//点击子节点时触发(子节点选中,父节点也选中) 158 var Selected; 159 if (this.Three.Fours && this.Three.Fours.length > 0) { 160 Selected = this.Three.Fours.some(function (Four) { 161 return Four.Selected; 162 }); 163 } else { 164 Selected = this.Three.Selected; 165 } 166 return Selected; 167 }, 168 set: function (value) {//点击节点本身时触发(选中、取消 所有子节点) 169 if (this.Three.Fours && this.Three.Fours.length > 0) { 170 this.Three.Fours.forEach(function (Four) { 171 Four.Selected = value; 172 }); 173 } 174 this.Three.Selected = value; 175 } 176 } 177 } 178 }) 179 var app = new Vue({ 180 el: '#container', 181 data: { 182 Ones: [{ 183 184 Code: 1, 185 FuncName: '一级节点1', 186 Twos: [ 187 { 188 Code: 2, 189 Selected: false, 190 FuncName: '二级节点1', 191 Threes: [ 192 { 193 Code: 3, 194 Selected: true, 195 FuncName: 'joe的商品2' 196 }, 197 { 198 Code: 4, 199 Selected: false, 200 FuncName: '三级节点1', 201 Fours: [{ 202 Code: 5, 203 Selected: true, 204 FuncName: '四级节点1' 205 }, { 206 Code: 6, 207 Selected: true, 208 FuncName: '四级节点2' 209 }] 210 } 211 ] 212 }, 213 { 214 Code: 7, 215 Selected: false, 216 FuncName: '二级节点2' 217 } 218 ], 219 Selected: false 220 }] 221 } 222 }); 223 224 </script> 225 </body> 226 </html>
代码写的比较粗糙,望各位大大指正。^_^