当前位置:Gxlcms > JavaScript > Vue自定义指令实现checkbox全选功能的方法

Vue自定义指令实现checkbox全选功能的方法

时间:2021-07-01 10:21:17 帮助过:6人阅读

最近做的一个项目需要用到Vue实现全选功能,参考了一下网上的做法,发现用属性计算的复用性不高,于是选用自定义指令,但网上的做法大多是会对原始数据有一定的格式要求,而且没有返回结果,于是做了改进。

上代码:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <input type="checkbox" v-model="allCheck" v-check-all="allCheck" check-data="list" result="customerResult" key="demo"> 全选
  10. <ul>
  11. <li v-for="item in list">
  12. <input type="checkbox" v-model="item.checked">
  13. {{item.demo}}
  14. </li>
  15. </ul>
  16. <div >
  17. customerResult: {{customerResult}}
  18. </div>
  19. </div>
  20. <script src="vue.js"></script>
  21. <script>
  22. var vm = new Vue({
  23. el: "#app",
  24. data:function(){
  25. return {
  26. list:[{demo:1},
  27. {demo:2},
  28. {demo:3}],
  29. allCheck:'',
  30. customerResult:'',
  31. }
  32. },
  33. directives: {
  34. 'check-all': {
  35. twoWay: true,
  36. params: ['checkData','result','key'],
  37. bind() {
  38. /*为原始数据的每一个对象添加一个checked属性*/
  39. this.vm[this.params.checkData].forEach((item)=>{
  40. Vue.set(item,'checked',false)
  41. });
  42. /*提取被选中的项*/
  43. this.setValue=function(){
  44. let result=[]
  45. this.vm[this.params.checkData].forEach((item) => {
  46. if(item.checked){
  47. result.push(item[this.params.key])
  48. }
  49. });
  50. this.vm[this.params.result]=result
  51. }
  52. /*如果所有的列表的checked属性都为true,则选中全选框,否则不选中全选框 */
  53. this.vm.$watch(this.params.checkData, (data) => {
  54. if(data.every((item) => item.checked)) {
  55. this.set(true);
  56. } else {
  57. this.set(false);
  58. }
  59. this.setValue()
  60. }, {deep: true});
  61. },
  62. // checkAll发生更改时
  63. update(checkAll) {
  64. /*如果全选框被选中,则将列表的所有checked属性转为true,否则转为false */
  65. if(checkAll) {
  66. this.vm[this.params.checkData].forEach((item) => {
  67. item.checked = true;
  68. });
  69. } else {
  70. this.vm[this.params.checkData].forEach((item) => {
  71. item.checked = false;
  72. });
  73. }
  74. this.setValue()
  75. },
  76. },
  77. }
  78. })
  79. </script>
  80. </body>
  81. </html>

通常我们都要获取原始数据中的某个键值,可在“key”中填进想要获取的键值,“result”就是被选中的项了。
有时,我们需要返回一个完整的对象修改一下代码,当不输入key时,返回一个完整的对象数组

  1. this.setValue=()=>{
  2. let result=[]
  3. this.vm[this.params.checkData].forEach((item) => {
  4. //删除checked属性
  5. let temp={};
  6. (()=>delete Object.assign(temp,item).checked)();
  7. item.checked?result.push(item[this.params.key]||temp):"";
  8. });
  9. this.vm[this.params.result]=result
  10. }

但时,这时,返回来的数组中对象中并没有与与原数据是相同的引用地址,当需要使用array.$remove()函数时就会失败,新增一个relative参数,用户自定义判断返回的数据是否与原始数据关联

  1. this.setValue = () => {
  2. let result = []
  3. this.vm[this.params.checkData].forEach((item) => {
  4. if(this.params.relative) {
  5. item.checked ? result.push(item) : "";
  6. }else{
  7. //删除checked属性
  8. let temp = {};
  9. (() => delete Object.assign(temp, item).checked)();
  10. item.checked ? result.push(item[this.params.key] || temp) : "";
  11. }
  12. });
  13. this.vm[this.params.result] = result
  14. }

当数据长度大于2个时,需要判断2N次,相当消耗性能,优化一下:

  1. 'check-all', {
  2. twoWay: true,
  3. params: ['checkData', 'result', 'key','relative'],
  4. /*checkData:列表数据,
  5. result:返回的结果,
  6. key:列表数据中需要返回的字段,
  7. relative:是否返回与列表数据相同引用地址的选中结果*/
  8. bind() {
  9. /*提取被选中的项*/
  10. this.setValue = () => {
  11. let result = []
  12. if (this.params.relative) {
  13. this.vm[this.params.checkData].forEach((item) => {
  14. item.checked ? result.push(item) : "";
  15. });
  16. } else {
  17. this.vm[this.params.checkData].forEach((item) => {
  18. //删除checked属性
  19. let temp = {};
  20. (() => delete Object.assign(temp, item).checked)();
  21. item.checked ? result.push(item[this.params.key] || temp) : "";
  22. });
  23. }
  24. this.vm[this.params.result] = result
  25. };
  26. /*为原始数据的每一个对象添加一个checked属性*/
  27. this.addChecked = () => {
  28. this.vm[this.params.checkData].forEach((item) => {
  29. Vue.set(item, 'checked', false)
  30. });
  31. };
  32. /*如果所有的列表的checked属性都为true,则选中全选框,否则不选中全选框 */
  33. this.vm.$watch(this.params.checkData, (data) => {
  34. if(!data.length) return;
  35. data.every((item) => item.checked) ? this.set(true) : this.set(false);
  36. this.setValue()
  37. }, {deep: true});
  38. //当列表发生变化时重新绑定
  39. this.vm.$watch(this.params.checkData, (data) => {
  40. if(!data.length) return
  41. this.addChecked();
  42. });
  43. },
  44. // checkAll发生更改时
  45. update(checkAll) {
  46. /*如果全选框被选中,则将列表的所有checked属性转为true,否则转为false */
  47. checkAll ? this.vm[this.params.checkData].forEach((item) => {
  48. item.checked = true
  49. }) : this.vm[this.params.checkData].forEach((item) => {
  50. item.checked = false
  51. });
  52. this.setValue()
  53. },
  54. }

这时只需要判断N+1次。

以上这篇Vue自定义指令实现checkbox全选功能的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

人气教程排行