Vue3+ElementPlus—高效存储和回显多选项的状态值

应用场景

监控摄像头,多通道,如通道1,通道2,通道3,通道4,通道5,通道6。

一个属性值,用来表示拥有哪几个通道

每个通道作为一个复选框,使用 位运算 来高效地处理多选框的状态

应用逻辑

使用位运算来高效地处理多选框的状态。在计算机科学中,2 的幂次方在二进制表示中各自占据不同的位: 通道1的值:十进制是1,二进制是 000001 通道2的值:十进制是2,二进制是 000010 通道3的值:十进制是4,二进制是 000100 通道4的值:十进制是8,二进制是 001000 通道5的值:十进制是16,二进制是 010000 通道6的值:十进制是32,二进制是 100000

这种设计的优势:

  • 可以通过简单的加法或按位或运算组合多个通道的值
  • 可以通过按位与运算快速判断某个通道是否被选中
  • 节省存储空间,一个整数就可以表示所有通道的选择状态
  • 位运算天然避免重复值的影响

例如,如果选中了通道1、3和5,那么总值就是 1 + 4 + 16 = 21。要检查通道3是否被选中,只需要检查 21 & 4 是否等于 4。

前置知识

reduce函数

是 JavaScript 数组的一个高阶函数方法,用于对数组中的每个元素执行一个回调函数,并将数组缩减为一个单一的值。

基本语法:

js 复制代码
array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)
//或
array.reduce((accumulator, currentValue, currentIndex, array) => {}, initialValue)

参数说明:

  • callback: 执行数组中每个元素的函数,包含以下参数:
    • accumulator:上一次调用回调函数返回的值,或者是提供的初始值
    • currentValue:当前正在处理的数组元素
    • currentIndex(可选):当前处理元素的索引
    • array(可选):调用 reduce 的数组
  • initialValue(可选):作为第一次调用 callback 函数时的第一个参数的值

示例演示:

js 复制代码
// 数组内每个元素相加得到的结果(可以遍历相加,此处是使用reduce函数和位或运算得到结果)
const videoChannelList = [1,4,16]
const value = videoChannelList.reduce((accumulator, currentValue) => accumulator | currentValue, 0);

这里的工作原理是:

  1. 初始值为 0
  2. 对于数组中的每个值,执行按位或运算(|)
  3. 逐步累积结果,最终得到一个合并值

例如:如果选中了通道1(1)、通道3(4)和通道5(16):

  • 第一次:0 | 1 = 1
  • 第二次:1 | 4 = 5
  • 第三次:5 | 16 = 21
  • 最终结果:21

这种方式利用了位运算的特性,每个通道值都是2的幂次方,在二进制中只有一个位为1,通过按位或运算可以安全地合并这些值。

Math.pow()函数

是 JavaScript 中用于计算幂运算的内置函数。

基本语法:

js 复制代码
Math.pow(base, exponent)

参数说明:

  • base:底数
  • exponent:指数

返回值:

返回 base 的 exponent 次幂,即 base^exponent。

例如:

js 复制代码
Math.pow(2, 3)  // 返回 8 (2的3次方)
Math.pow(4, 0.5) // 返回 2 (4的平方根)
Math.pow(10, -1) // 返回 0.1 (10的负一次方)

const bitValue = 1 << i; : 使用位移运算符计算2的i次方

功能:

  • 1 << i 表示将数字1的二进制向左移动i位
  • 等价于计算 Math.pow(2, i) 或 2^i
  • 用于生成二进制中只有第i位为1的数值

示例演示:

html 复制代码
<el-checkbox v-for="item in 6" :label="Math.pow(2, item - 1)" :key="item">
  通道{{item}}
</el-checkbox>

具体生成的值为:

  • 当 item=1 时,Math.pow(2, 0) = 1
  • 当 item=2 时,Math.pow(2, 1) = 2
  • 当 item=3 时,Math.pow(2, 2) = 4
  • 当 item=4 时,Math.pow(2, 3) = 8
  • 当 item=5 时,Math.pow(2, 4) = 16
  • 当 item=6 时,Math.pow(2, 5) = 32

可以通过按位或运算 (|) 安全地合并 可以通过按位与运算 (&) 检查某个位是否被设置 这种方式常用于权限系统或状态标记,因为它能高效地组合和检查多个标志位。

应用实操

xxx.vue

html 复制代码
<template>
...
    <el-form-item label="视频通道" prop="videoChannel">
        <el-checkbox-group v-model="videoChannelList">
            <!--
                这里会生成 6 个复选框,每个复选框的 label 值分别是:
                当 item=1 时,label=Math.pow(2, 0) = 1
                当 item=2 时,label=Math.pow(2, 1) = 2
                当 item=3 时,label=Math.pow(2, 2) = 4
                当 item=4 时,label=Math.pow(2, 3) = 8
                当 item=5 时,label=Math.pow(2, 4) = 16
                当 item=6 时,label=Math.pow(2, 5) = 32
            -->
            <el-checkbox v-for="item in 6" :label="Math.pow(2, item - 1)" :key="item" @change="handleCheckChange('video')">
                通道{{item}}
        </el-checkbox>
        </el-checkbox-group>
    </el-form-item>
	<el-button @click="selectValueFun">取值({{result}})</el-button>
    <el-button @click="echoFun">回显</el-button>
</template>

<script setup>
import { ref } from "vue";
// 被勾选的一个或多个复选框返回数组,如勾选通道1、通道3和通道5,返回的数组是[1,4,16]
const videoChannelList = ref([])
const channelValue = 21
const result = ref(0)
// 回显哪些复选框被选中
const echoFun = () => {
  //视频通道打钩
  for (let i = 0; i < 6; i++) {
    /*
    表示将数字1的二进制向左移动i位
      -等价于计算 Math.pow(2, i) 或 2^i(2的i次幂)
      -用于生成二进制中只有第i位为1的数值
    */
    const bitValue = 1 << i;
    if ((channelValue & bitValue) !== 0) {
      videoChannelList.value.push(bitValue);
    }
  }
}
// 选中一个或多个复选框后的值
const selectValueFun = () => {
  // channel初始值为 0,并与当前值val(遍历数组中的每个值),执行按位或运算(|),获取最终的值(相当于每个元素值相加后的结果,但仅限于元素值为2^i时)
  const value = videoChannelList.value.reduce((channel, val) => channel | val, 0);
  result.value = value;
}
</script>
相关推荐
月弦笙音14 分钟前
【XSS】后端服务已经加了放xss攻击,前端还需要加么?
前端·javascript·xss
code_Bo17 分钟前
基于vueflow实现动态添加标记的装置图
前端·javascript·vue.js
传奇开心果编程1 小时前
【传奇开心果系列】Flet框架实现的图形化界面的PDF转word转换器办公小工具自定义模板
前端·python·学习·ui·前端框架·pdf·word
CodeTransfer2 小时前
css中animation与js的绑定原来还能这样玩。。。
前端·javascript
20262 小时前
14.7 企业级脚手架-制品仓库发布使用
前端·vue.js
言之。3 小时前
Web技术构建桌面应用-Tauri框架和Electron框架
前端·javascript·electron
萌萌哒草头将军3 小时前
Node.js v24.7.0 新功能预览 🚀🚀🚀
前端·javascript·node.js
用户841794814563 小时前
vue table 甘特图 vxe-gantt 实现多个表格的任务互相拖拽数据
vue.js
艾小码3 小时前
90%前端忽略的3大内存黑洞,这样根治性能飙升300%!
前端·javascript·性能优化