道招

Vue和React hooks实现Select批量选择、选中条数、全选、反选实现对比

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

Vue和React hooks实现Select批量选择、选中条数、全选、反选实现对比

批量选择、全选、反选这些功能使用频率还是很高的,下面直接看看Vue和React分别怎么实现吧。

Vue

在使用Vue的时候是很容易实现的,我们以下列数据格式为例:

const dataList = [{
    id: 1,
    label: '第一个',
}, {
    id: 2,
    label: '第二个',
}, {
    id: 3,
    label: '第三个',
}]

批量选择 在Vue中我们一般喜欢格外增加一个属性来标记是否已被选择,可以在每条数据item被勾选时,比如第一条的话就是Vue.set(dataList[0], 'checked', !!dataList[0].checked); 选中条数

const count = dataList.filter(item => item.checked).length;

全选

dataList.forEach(item => Vue.set(item, 'checked', true));

反选

dataList.forEach(item => Vue.set(item, 'checked', false));

React实现一

在React中怎么实现呢? 如果只是简单按照同样的方式的话,你就会失望了。

因为React不是跟Vue采用观察者模式来处理数据更新后的视图变更逻辑的,它更多是需要进行全量更新数据的。

对应数组而言,是引用类型数据,尽管里面某个元素发生了变更,但是对于整体数组的引用地址并未变更,React也就无法进行视图更新。

我们以使用useReducer为例

import React, { useReducer, useMemo } from 'react';

const [state, dispatch] = useReducer({
    dataList: [],
}, (state, reducer) => {
    switch(reducer.type) {
     case 'update':
         return {
            ...state,
            ...reducer.payload
         }
     case default:
         return state;
    } 

})

批量选择 在React中我们也可以选择格外增加一个属性来标记是否已被选择,可以在每条数据item被勾选时,比如第一条的话就是:

state.dataList[0].checked = !!state.dataList[0].checked;
dispatch({
    type: 'update',
    payload: {
        dataList: state.dataList.slice()
    }
})

对的,我们需要额外增加state.dataList.slice()这一步,这样我们就使用了新的数组引用了。 同理,下面的这些都需要额外增加这一步,或者要实现类似的功能。 选中条数

const count = useMemo(() => {
    state.dataList.filter(item => item.checked).length
}, [state.dataList]);

全选

dispatch({
    type: 'update',
    payload: {
        dataList: state.dataList.map(item => ({
            ...item,
            checked: true,
        }))
    }
})

反选

dispatch({
    type: 'update',
    payload: {
        dataList: state.dataList.map(item => ({
            ...item,
            checked: false,
        }))
    }
})

React实现二

网上也有不少网友借助一个存储对象来实现上述批量选择、选中条数、全选、反选的功能的,也简单看下具体实现。

import React, { useReducer, useMemo } from 'react';

const [state, dispatch] = useReducer({
    dataList: [],
    checkedMap: {}, // 新增 用来存储选中数据关系
}, (state, reducer) => {
    switch(reducer.type) {
     case 'update':
         return {
            ...state,
            ...reducer.payload
         }
     case default:
         return state;
    } 

})

批量选择 在每条数据item被勾选时通过变更checkedMap记录存储关系,比如第一条的话,如果选中就是{0: true},否则就是未选中,具体实现如下:

dispatch({
    type: 'update',
    payload: {
        checkedMap: {
            ...state.checkedMap,
            0: !!state.checkedMap[0]
        }
    }
})

我们不需要变更dataList里面的数据,只用变更checkedMap

选中条数

const count = useMemo(() => {
 Object.keys(state.checkedMap).filter(item => state.checkedMap[item]).length
}, [state.checkedMap]);

全选

dispatch({
    type: 'update',
    payload: {
        checkedMap: state.dataList.reduce((acc, curr) => ({
            ...acc,
            [curr.id]: true,
        }), {})
    }
})

反选

dispatch({
    type: 'update',
    payload: {
        checkedMap: state.dataList.reduce((acc, curr) => ({
            ...acc,
            [curr.id]: false,
        }), {})
    }
})

效果如下 file

更新时间:
上一篇:网址改用七牛云存储图片下一篇:道招网回归国内主机并完成备案

相关文章

Vue在chrome44偶现点击子元素事件无法冒泡

公司的一个项目大致是这样的:一个左侧列表,点击左侧列表的文章标题,右侧展开该文章对应的内容的。 现在的问题出现在极少部分客户有时左侧的标题,无法打开对应的右侧的内容,给人的改进就是‘卡’、点不动、点 阅读更多…

2021年的一点工作总结(一)迁移React技术栈

2021年全年的工作总结起来很简单,算是做苦力的一年吧。。。 2021年春节后就开始邮件项目从Vue迁移到React的工作以及富文本编辑器由wangEditor替换成CKEditor。 其实自己 阅读更多…

对React Hooks的Capture value特性的理解

之前我的项目里面很多功能都是用的事件驱动,所以下面的实例也会更多地使用监听事件的回调函数。 我们先看下测试代码 const {useEffect ,useState, useRef, us 阅读更多…

vue-cli设置css不生效

我们有的项目使用的是老的vue-cli脚手架生成的,今天想写点东西,发现.vue文件里面 style 里面写的样式都不生效了,很自然就想到是不是loader的问题。 在这种项目的webpack.ba 阅读更多…

从vuecli3学习webpack记录(一)vue-cli-serve机制

最近看了看vuecli3,把自己的学习记录下来。 首先看入口 npm run dev 即是 vue-cli-service serve ,之所以能运行 vue-cli-service 命令,就是 阅读更多…

转译:使用react hooks优化回调函数在组件间的传递,useState,useReducer?

我们先看一下使用 useState hooks写的todoList组件,里面我们需要层层传递回调函数。 import React, { useState } from "react& 阅读更多…

关注道招网公众帐号
友情链接
消息推送
道招网关注互联网,分享IT资讯,前沿科技、编程技术,是否允许文章更新后推送通知消息。
允许
不用了