为了账号安全,请及时绑定邮箱和手机立即绑定

Vue Js 范围复选框选择带 shift

Vue Js 范围复选框选择带 shift

湖上湖 2023-03-24 14:08:55
我有这个 html:<divclass="data__file"v-for="(data, index) in paginatedData":key="index"> <label class="data__info" :for="data.idfile" @click="onClickWithShift($event, index)">   <img     :src="data.link"     alt=""     :class= "{ 'data__image' : 1 ,'data__image-active' : (data.checked === 1) }"    />    <input     v-if="isManager === true"     type="checkbox"     class="data__access"     :value="data.idaccess"     :checked="(data.checked === 1) ? 1 : null"     v-model="checkedFilesPermission"          />              <input     v-if="isManager === false"     type="checkbox"     class="data__access"     :value="data.idfile"     :checked="(data.checked === 1) ? 1 : null"     v-model="checkedFilesDownload"           />    </label></div>此代码生成复选框输入列表,然后我需要当用户单击带有 shift 的标签时(因为输入是显示:无),单击输入之间的所有复选框都将选中或取消选中,就像它在此处使用 jquery 所做的那样我如何进行 shift- select像 GMail 这样的多个复选框?但我不知道我怎么能得到它。非常感谢用户 Spiky Chathu,我按照他说的做了,并且它没有工作v-model,但是当我尝试使用 v-model 时,它不起作用。
查看完整描述

2 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

我想出了一个解决你的问题的方法。我添加了一个模拟对象来重新创建相同的场景,希望您有一个对象数组。


已编辑:已修改解决方案以满足多个取消选择的场景


new Vue({

  el: '#app',

  data: {

    paginatedData: [

      {"link":"https://img.icons8.com/list","idfile":296,"idaccess":2},

      {"link":"https://img.icons8.com/list","idfile":6,"idaccess":99},

      {"link":"https://img.icons8.com/list","idfile":26,"idaccess":29},

      {"link":"https://img.icons8.com/list","idfile":960,"idaccess":2919},

      {"link":"https://img.icons8.com/list","idfile":16,"idaccess":9339},

      {"link":"https://img.icons8.com/list","idfile":2,"idaccess":9},

    ],

    lastCheckedIdx: -1,

    checkedFilesPermission : []

  },

  methods: {

    onClickWithShift(event, idx, idFile) {

  

      var action = (this.checkedFilesPermission.indexOf(idFile) === -1) ? 'select' : 'deselect';

      

      if (event.shiftKey && this.lastCheckedIdx !== -1) {

      

        var start = this.lastCheckedIdx;

        var end = idx-1;

        // can select top to bottom or bottom to top

        // always start with lesser value

        if (start > end) {

          start = idx+1;

          end = this.lastCheckedIdx;

        }

        

        for (var c = start; c <= end; c++) {

          var currentIdFile = this.paginatedData[c]['idfile'];

          this.markSelectDeselect(c, action, currentIdFile);

        }

      }

      

      this.markSelectDeselect(idx, action, idFile);

      this.lastCheckedIdx = idx;

      

      if (this.checkedFilesPermission.length === 0) {

        //reset last checked if nothing selected

        this.lastCheckedIdx = -1;

      }

    },


    markSelectDeselect(idx, action, idFile) {

      

      var currentPos = this.checkedFilesPermission.indexOf(idFile);

      

      if (action === 'select' && currentPos === -1) {

        this.checkedFilesPermission.push(idFile);

      } else if (action === 'deselect' && currentPos !== -1){

        this.checkedFilesPermission.splice(currentPos, 1);

      }

    }

  }

})

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

<div id="app">

  <div

      class="data__file"

      v-for="(data, index) in paginatedData"

      :key="index"

  >

      <input

          :id="data.idfile"

          type="checkbox"

          class="data__access"

          :value="data.idfile"

          v-model="checkedFilesPermission"

      />

       <label class="data__info" :for="data.idfile" @click="onClickWithShift($event, index, data.idfile)">

          <img

              :src="data.link"

              alt=""

              :class= "{ 'data__image' : 1 ,'data__image-active' : (checkedFilesPermission.indexOf(data.idfile) !== -1) }"

          />

      </label>

  </div>

</div>

您需要单击图像图标才能看到结果,因为您已经提到输入是隐藏的。我在这里保持它可见,以便您可以看到它实际上正在发生变化


查看完整回答
反对 回复 2023-03-24
?
大话西游666

TA贡献1817条经验 获得超14个赞

这是我刚刚尝试过的似乎可以完成工作的东西


<template>

  <div>

    <div v-for="(item, index) in items" :key="index">

      <label>

        <input type="checkbox" v-model="item.checked" @click="checked($event, index)">

        {{item.file}}

      </label>

    </div>

    <pre>{{items}}</pre>


  </div>

</template>


<script>


export default {

  data() {

    return {

      lastCheckedIndex: null,

      lastChange: null,

      items: [

        { file: "foo1", idx: 10 },

        { file: "foo2", idx: 20 },

        { file: "foo3", idx: 40 },

        { file: "foo4", idx: 30 },

        { file: "foo5", idx: 10 },

        { file: "foo6", idx: 90 },

        { file: "foo8", idx: 50 },

      ]

    }

  },

  methods: {

    checked(event, index) {

      // wheter or not to the multiple selection

      if (event.shiftKey && (null != this.lastCheckedIndex) && (this.lastCheckedIndex != index)) {


        const dir = index > this.lastCheckedIndex ? 1 : -1; // going up or down ?

        const check = this.lastChange;                      // are we checking all or unchecking all ?


        for (let i = this.lastCheckedIndex; i != index; i += dir) {

          this.items[i].checked = check;

        }

      }


      // save action

      this.lastCheckedIndex = index; 

      this.lastChange = !this.items[index].checked; // onclick is triggered before the default change hence the !

    }

  },

};


</script>



查看完整回答
反对 回复 2023-03-24
  • 2 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信