Ant design vue table 单击行选中 勾选checkbox教程


Posted in Javascript onOctober 24, 2020

最近了解Ant design 设计table 单击行选中checkedbox功能,相比于element的 @row-click 再触发toggleRowSelection,ant design的api就没那么清晰了,言归正传

期望:Ant design table 单击行选中 勾选checkedbox

实现:

Ant design vue table 单击行选中 勾选checkbox教程

单选:

onClickRow(record) {
 return {
 on: {
  click: () => {
  let keys = [];
  keys.push(record.id); 
  this.selectedRowKeys = keys;
  }
 }
 }
}

多选:

onClickRowMulti(record) { 
return { 
 on: { 
 click: () => { 
  let rowKeys=this.selectedRowKeys
  if(rowKeys.length>0 && rowKeys.includes(record.id)){
  rowKeys.splice(rowKeys.indexOf(record.id),1)
  }else{
  rowKeys.push(record.id)
  }
  this.selectedRowKeys = rowKeys; 
 } 
 } 
 } 
}

补充知识:使用Ant Design的Table和Checkbox模拟Tree

一、小功能大需求

先看下设计图:

Ant design vue table 单击行选中 勾选checkbox教程

需求如下:

1、一级选中(取消选中),该一级下的二级全部选中(取消选中)

2、二级全选,对应的一级选中,二级未全选中,对应的一级不选中

3、支持搜索,只搜索二级数据,并且只展示搜索到的数据以及对应的一级title,如:搜索“店员”,此时一级只展示咖啡厅....其他一级隐藏,二级只展示店员,其他二级隐藏

4、搜索出来的数据,一级不可选中,即不允许全选,搜索框清空时,回归初始化状态

5、搜索后,自动展开所有二级,默认情况下收起所有二级

看到图的时候,第一反应就是使用Tree就能搞定,但是翻阅了文档后,发现Tree并不能全部完成,所以就只能使用其他组件进行拼装,最后发现使用Table和Checkbox可以完美实现。

二、逐步完成需求

如果不想看这些,可直接到最后,有完整代码。。。。。。

1、页面构建

这个就不用多说,只是一个简单的Table嵌套Checkbox,具体可去查看文档,直接贴代码,因为是布局,所有可以忽略代码中的事件。

注意一点:因为搜索时,会改变数据,所以需要将初始化的数据进行保存。

import React, { useState, useRef, useEffect } from "react";
import { Table, Input, Checkbox } from "antd";
const { Search } = Input;

export default () => {
 const initialData: any = useRef([]); //使用useRef创建initialData
 const [data, setData] = useState([
 {
 key: 1,
 title: "普通餐厅(中餐/日料/西餐厅)",
 checkboxData: [
 { key: 12, title: "普通服务员" },
 { key: 13, title: "收银" },
 { key: 14, title: "迎宾/接待" },
 ],
 },
 {
 key: 2,
 title: "零售/快消/服装",
 checkboxData: [
 { key: 17, title: "基础店员" },
 { key: 19, title: "收银员" },
 { key: 20, title: "理货员" },
 ],
 },
 ]);
 useEffect(() => {
 initialData.current = [...data]; //设置初始化值
 }, []);
 const [checkedJob, setCheckedJob] = useState([]); //设置子级中选择的类
 const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]); //设置选择的行
 const expandedRowRender = (record: any) => {
 return (
 <div style={{ paddingLeft: 50, boxSizing: "border-box" }}>
 <p>请选择岗位,或勾选类别全选岗位</p>
 <div>
  <Checkbox.Group value={checkedJob}>
  {record.checkboxData.map((item: any) => {
  return (
  <Checkbox
   value={item.key}
   key={item.key}
   onChange={checkChange}
  >
   {item.title}
  </Checkbox>
  );
  })}
  </Checkbox.Group>
 </div>
 </div>
 );
 };
 const rowSelection = {
 selectedRowKeys,
 };
 return (
 <div
 style={{
 background: "#fff",
 padding: 24,
 boxSizing: "border-box",
 width: 982,
 }}
 >
 <Search
 placeholder="请输入岗位名称"
 onSearch={(value) => {
  console.log(loop(value));
 }}
 />
 <Table
 showHeader={false}
 columns={columns}
 expandable={{
  expandedRowRender,
 }}
 dataSource={data}
 pagination={false}
 rowSelection={rowSelection}
 />
 </div>
 );
};
const columns = [{ title: "title", dataIndex: "title", key: "title" }];

2、一级选中(取消全选)

当一级选中(取消全选)时,需要更新对应二级选项的状态。在antd文档中,使用rowSelection的onSelect,可以设置选择/取消选择某行的回调。

onSelect:(record,selected)=> record:操作当前行的数据,selected:true:全选,false:取消全选

注意:当全选时,不能直接添加当前一级下的所有二级,需要过滤掉当前已经选中的二级

具体逻辑如下代码:

//首选在rowSelection配置中添加onSelectconst rowSelection = {
 selectedRowKeys,
 onSelect
 };

//一级全选或者取消的逻辑
const onSelect = (record: any, selected: any) => {
 //因为存在搜索,所以需要使用我们的初始化数据,找到当前record.key在初始化数据中对应的数据
 let initialParent = initialData.current.find(
  (d: any) => d.key === record.key
 );//初始化数据中对应的二级数据
 let selectParentData = initialParent.checkboxData
  ? initialParent.checkboxData.map((d: any) => d.key)
  : [];
 if (selected) { //全选
  //向selectRowKeys添加选中的值
  setSelectedRowKeys([...selectedRowKeys, record.key]);
  //更新child数组,将selectParentData中的数据全部过滤添加
  setCheckedJob(Array.from(new Set([...checkedJob, ...selectParentData])));
 } else { //取消全选
  //从父级数组中移除key值
  setSelectedRowKeys(
  [...selectedRowKeys].filter((d: any) => d !== record.key)
  );
  //更新child数组,将selectParentData中的数据全部过滤掉
  let newArr: any = [];
  [...checkedJob].forEach((v) => {
  if (selectParentData.indexOf(v) === -1) {
   newArr.push(v);
  }
  });
  setCheckedJob(newArr);
 }
 };

3、二级选中或取消选中逻辑

二级选中或者取消比较简单,只要注意在选中时,如何去考虑是否所有二级全部选中即可。具体代码如下。

//判断b数组中的数据是否全部在a数组中 const isContained = (a: any, b: any) => {
 if (!(a instanceof Array) || !(b instanceof Array)) return false;
 if (a.length < b.length) return false;
 var aStr = a.toString();
 for (var i = 0, len = b.length; i < len; i++) {
  if (aStr.indexOf(b[i]) == -1) return false;
 }
 return true;
 };
//设置checkbox的onChange事件
 const checkChange = (e: any) => {
 let praentRowsKey: any;
 //找到选中的二级对应的父级key
 initialData.current.forEach((v: any) => {
  if (v.checkboxData.find((d: any) => d.key === e.target.value)) {
  praentRowsKey = v.key;
  }
 });
 if (e.target.checked) {
  //选中时 设置当前的check数组
  let newCheckedJob = [...checkedJob, e.target.value];
  setCheckedJob(newCheckedJob);
  //判断当前二级的内容是否全部被选中,如果全部选中,则需要设置selectedRowKeys
  //praentRowsKey下的所有子元素
  let childArr = initialData.current
  .find((d: any) => d.key === praentRowsKey)
  ?.checkboxData?.map((i: any) => i.key);
  // 为当前选择之后的新数组
  if (isContained(newCheckedJob, childArr)) {
  //全部包含,设置父级
  setSelectedRowKeys([...selectedRowKeys, praentRowsKey]);
  }
 } else {
  //取消选中 设置当前的child数组
  setCheckedJob(
  [...checkedJob].filter((d: number) => d !== e.target.value)
  );
  //判断当前父级中是否存在praentRowsKey,存在则去除
  if (!!~selectedRowKeys.indexOf(praentRowsKey)) {
  setSelectedRowKeys(
   [...selectedRowKeys].filter((d: any) => d !== praentRowsKey)
  );
  }
 }
 };

4、搜索过滤

前3步骤完成后,目前来说,正常的一级二级联动已经完成,现在进行第4步,搜索过滤。

简单的说,搜索的时候,只要改变我们的data,就可以重新渲染Table,这样就可以达成搜索过滤的效果。具体代码如下

//Search组件搜索时,触发更改data<Search
 placeholder="请输入岗位名称"
 onSearch={(value) => {
  setData(loop(value));
 }}
/>
 //搜索岗位时,进行过滤
 const loop = (searchValue: any) => {
 let loopData = initialData.current?.map((item: any) => {
//判断一级是否包含该搜索内容
  let parentKey = !!~item.title.indexOf(searchValue);
  let childrenData: any = [];
  if (item.checkboxData) {
  //如果存在二级,则进行二级的循环,过滤出搜索到的value
  childrenData = item.checkboxData.filter(
   (d: any) => !!~d.title.indexOf(searchValue)
  );
  }  //如果一级有,二级没有,则展示一级下所有的二级
  //如果一级没有,二级有,则只展示存在的二级以及对应的一级
 //如果一级有,二级有,则展示存在的二级以及对应的一级  //如果一级没有,二级也没有,则不展示
  if(parentKey&&!childrenData.length){
  return {



title:item.title,



key:item.key,



checkboxData:item.checkboxData


}
 }else if((!parentKey || parentKey)&&childrenData.length){


return{



title:item.title,



key:item.key,



checkboxData:childrenData


}

}else{

}
 });

//搜索的值不为空时,返回搜索过滤后都数据(因为map出来的数据中有undefined,所以需要再次进行过滤),为空时返回初始化数据
 return searchValue ? loopData.filter((d: any) => d) : initialData.current;
 };

5、搜索后,禁止一级全选和取消全选

动态控制table的选择功能,需要使用rowSelection的getCheckboxProps。具体代码如下。

const [selectAllDisabled, setSelectAllDisabled] = useState<boolean>(false); //声明一个变量,控制是否允许选择,默认为false

//在rowSelection中添加getCheckboxProps
const rowSelection = {
 selectedRowKeys,
 onSelect,
 getCheckboxProps: (record: any) => ({ 
  disabled: selectAllDisabled,//true:禁止,false:允许
 }),
 };
//在搜索的时候设置
 const loop = (searchValue: any) => {
 ...
 setSelectAllDisabled(searchValue ? true : false);  //当搜索内容为空时,因为回到的是初始值,所以需要它允许选择,搜索内容不为空时,禁止选择
 ...
 };

6、设置自动展开

前5步完成后,如果不需要设置自动展开,则该功能就可以到此结束。

设置自动展开,需要用到expandable中的onExpand以及expandedRowKeys

expandedRowKeys:展开的行,控制属性

onExpand:点击展开图标时触发,(expanded,record)=> expanded:true:展开,false:收起。record:操作的当前行的数据

具体代码如下:

const [expandedRowKeys, setExpandedRowKeys] = useState<any>([]); //声明变量设置展开的行,默认全都收起

//table的 expandable添加 onExpand,expandedRowKeys
<Table
 expandable={{
 expandedRowRender,
 onExpand,
 expandedRowKeys,
 }}
/>

//搜索时改变状态
const loop = (searchValue: any) => {
 ...
 //有数据时自动展开所有搜索到的,无数据的时候默认全部收起
 setExpandedRowKeys(
  searchValue ? initialData.current.map((d: any) => d.key) : []
 );
 ...
 };

//控制表格的展开收起
 const onExpand = (expanded: any, record: any) => {
 if (expanded) {
  setExpandedRowKeys([...expandedRowKeys, record.key]); //展开时,将需要展开的key添加到数组中
 } else {
  setExpandedRowKeys(
  [...expandedRowKeys].filter((d: any) => d !== record.key)//收起时,将该key移除数组
  );
 }
 };

三、优化

一级选择框有三种状态,全选,二级选中某些个,未选中,三种状态对应不同的样式,如下图所示。

Ant design vue table 单击行选中 勾选checkbox教程

这种优化,就需要设置rowSelection的renderCell(注意,rendercell在antd的4.1+版本才能生效),配合Checkbox进行更改。具体代码如下。

1、设置renderCell

将我们在第二步和第五步设置的onSelect以及getCheckboxProps隐藏,再配置renderCell

const rowSelection = {
 selectedRowKeys,
 // onSelect,
 // getCheckboxProps: (record: any) => ({
 // disabled: selectAllDisabled,
 // }),
 renderCell: (checked: any, record: any) => {
  //当前record.key对应大初始化数据的一级所有数据
  let parentArr = initialData?.current?.find(
  (d: any) => d.key === record.key
  );
  //从所有已经选择过的数据中过滤出在parentArr中的数据
  let checkArr = parentArr?.checkboxData?.filter(
  (item: any) => checkedJob.indexOf(item.key) > -1
  );
  return (
  <Checkbox
   indeterminate={
   parentArr?.checkboxData &&
   !!checkArr?.length &&
   checkArr.length < parentArr.checkboxData.length
    ? true
    : false
   } //比较 当过滤后选中数据的长度 < 初始化数据的长度时,设置 indeterminate 状态为true,否则为false
   onClick={(e) => onClick(e, record)}
   checked={checked}
   disabled={selectAllDisabled}
  ></Checkbox>
  );
 },
 };

2、设置onClick事件

onClick事件其实就是原来的onSelect,具体代码如下

const onClick = (e: any, record: any) => {
 //存在搜索时,需要进行处理selectParentData
 let initialParent = initialData.current.find(
  (d: any) => d.key === record.key
 );
 let selectParentData = initialParent.checkboxData
  ? initialParent.checkboxData.map((d: any) => d.key)
  : [];
 if (e.target.checked) {
  //向选中数组中添加key值
  setSelectedRowKeys([...selectedRowKeys, record.key]);
  //更新child数组,将selectParentData中的数据全部过滤添加
  setCheckedJob(Array.from(new Set([...checkedJob, ...selectParentData])));
 } else {
  //从父级数组中移除key值
  setSelectedRowKeys(
  [...selectedRowKeys].filter((d: any) => d !== record.key)
  );
  //更新child数组,将selectParentData中的数据全部过滤掉
  let newArr: any = [];
  [...checkedJob].forEach((v) => {
  if (selectParentData.indexOf(v) === -1) {
   newArr.push(v);
  }
  });
  setCheckedJob(newArr);
 }
 };

四、完整代码

Table+Checkbox模拟Tree完整代码

import React, { useState, useRef, useEffect } from "react";
import { Table, Input, Checkbox } from "antd";
const { Search } = Input;

export default () => {
 const initialData: any = useRef([]);
 const [data, setData] = useState([
 {
  key: 1,
  title: "普通餐厅(中餐/日料/西餐厅)",
  checkboxData: [
  { key: 12, title: "普通服务员" },
  { key: 13, title: "收银" },
  { key: 14, title: "迎宾/接待" },
  ],
 },
 {
  key: 2,
  title: "零售/快消/服装",
  checkboxData: [
  { key: 17, title: "基础店员" },
  { key: 19, title: "收银员" },
  { key: 20, title: "理货员" },
  ],
 },
 ]);
 useEffect(() => {
 initialData.current = [...data]; //设置初始化值
 }, []);

 const [checkedJob, setCheckedJob] = useState([12]); //设置选择的二级
 const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]); //设置选择的行
 const [expandedRowKeys, setExpandedRowKeys] = useState<any>([]); //设置展开的行
 const [selectAllDisabled, setSelectAllDisabled] = useState<boolean>(false); //选择的时候,禁止全选
 //搜索岗位时,进行过滤
 const loop = (searchValue: any) => {
 let loopData = initialData.current?.map((item: any) => {
  let parentKey = !!~item.title.indexOf(searchValue);
  let childrenData: any = [];
  if (item.checkboxData) {
  //如果存在二级,则进行二级的循环,过滤出搜索到的value
  childrenData = item.checkboxData.filter(
   (d: any) => !!~d.title.indexOf(searchValue)
  );
  }
  //1.如果一级有,二级没有,则展示一级下所有的二级
  //2.如果一级没有,二级有,则只展示存在的二级以及对应的一级
  //3.如果一级有,二级有,则展示则存在的二级以及对应的一级
  //4.如果一级没有,二级也没有,则不展示
  if (parentKey && !childrenData.length) {
  return {
   title: item.title,
   key: item.key,
   checkboxData: item.checkboxData,
  };
  } else if ((!parentKey || parentKey) && childrenData.length) {
  return {
   title: item.title,
   key: item.key,
   checkboxData: childrenData,
  };
  } else {
  }
 });
 setSelectAllDisabled(searchValue ? true : false);
 //有数据时自动展开所有搜索到的,无数据的时候默认全部收起
 setExpandedRowKeys(
  searchValue ? initialData.current.map((d: any) => d.key) : []
 );
 return searchValue ? loopData.filter((d: any) => d) : initialData.current;
 };

 const isContained = (a: any, b: any) => {
 if (!(a instanceof Array) || !(b instanceof Array)) return false;
 if (a.length < b.length) return false;
 var aStr = a.toString();
 for (var i = 0, len = b.length; i < len; i++) {
  if (aStr.indexOf(b[i]) == -1) return false;
 }
 return true;
 };
 const checkChange = (e: any) => {
 let praentRowsKey: any;
 //找到点击child到一级key
 initialData.current.forEach((v: any) => {
  if (v.checkboxData.find((d: any) => d.key === e.target.value)) {
  praentRowsKey = v.key;
  }
 });
 if (e.target.checked) {
  //选中时 设置当前的child数组
  let newCheckedJob = [...checkedJob, e.target.value];
  setCheckedJob(newCheckedJob);
  //判断当前child的内容是否全部被选中,如果全部选中,则需要设置selectedRowKeys
  //praentRowsKey下的所有子元素
  let childArr = initialData.current
  .find((d: any) => d.key === praentRowsKey)
  ?.checkboxData?.map((i: any) => i.key);
  // 为当前选择之后的新数组
  if (isContained(newCheckedJob, childArr)) {
  //全部包含,设置父级
  setSelectedRowKeys([...selectedRowKeys, praentRowsKey]);
  }
 } else {
  //取消选中 设置当前的child数组
  setCheckedJob(
  [...checkedJob].filter((d: number) => d !== e.target.value)
  );
  //判断当前父级中是否存在praentRowsKey,存在则去除
  if (!!~selectedRowKeys.indexOf(praentRowsKey)) {
  setSelectedRowKeys(
   [...selectedRowKeys].filter((d: any) => d !== praentRowsKey)
  );
  }
 }
 };

 //父节点变化时,进行的操作
 // const onSelect = (record: any, selected: any) => {
 //  //存在搜索时,需要进行处理selectParentData
 //  let initialParent = initialData.current.find(
 //  (d: any) => d.key === record.key
 //  );
 //  let selectParentData = initialParent.checkboxData
 //  ? initialParent.checkboxData.map((d: any) => d.key)
 //  : [];
 //  if (selected) {
 //  //向选中数组中添加key值
 //  setSelectedRowKeys([...selectedRowKeys, record.key]);
 //  //更新child数组,将selectParentData中的数据全部过滤添加
 //  setCheckedJob(Array.from(new Set([...checkedJob, ...selectParentData])));
 //  } else {
 //  //从父级数组中移除key值
 //  setSelectedRowKeys(
 //   [...selectedRowKeys].filter((d: any) => d !== record.key)
 //  );
 //  //更新child数组,将selectParentData中的数据全部过滤掉
 //  let newArr: any = [];
 //  [...checkedJob].forEach((v) => {
 //   if (selectParentData.indexOf(v) === -1) {
 //   newArr.push(v);
 //   }
 //  });
 //  setCheckedJob(newArr);
 //  }
 // };

 //控制表格的展开收起
 const onExpand = (expanded: any, record: any) => {
 //expanded: true展开,false:关闭
 if (expanded) {
  setExpandedRowKeys([...expandedRowKeys, record.key]);
 } else {
  setExpandedRowKeys(
  [...expandedRowKeys].filter((d: any) => d !== record.key)
  );
 }
 };

 const onClick = (e: any, record: any) => {
 //存在搜索时,需要进行处理selectParentData
 let initialParent = initialData.current.find(
  (d: any) => d.key === record.key
 );
 let selectParentData = initialParent.checkboxData
  ? initialParent.checkboxData.map((d: any) => d.key)
  : [];
 if (e.target.checked) {
  //向选中数组中添加key值
  setSelectedRowKeys([...selectedRowKeys, record.key]);
  //更新child数组,将selectParentData中的数据全部过滤添加
  setCheckedJob(Array.from(new Set([...checkedJob, ...selectParentData])));
 } else {
  //从父级数组中移除key值
  setSelectedRowKeys(
  [...selectedRowKeys].filter((d: any) => d !== record.key)
  );
  //更新child数组,将selectParentData中的数据全部过滤掉
  let newArr: any = [];
  [...checkedJob].forEach((v) => {
  if (selectParentData.indexOf(v) === -1) {
   newArr.push(v);
  }
  });
  setCheckedJob(newArr);
 }
 };
 const expandedRowRender = (record: any) => {
 return (
  <div style={{ paddingLeft: 50, boxSizing: "border-box" }}>
  <p>请选择岗位,或勾选类别全选岗位</p>
  <div>
   <Checkbox.Group value={checkedJob}>
   {record.checkboxData.map((item: any) => {
    return (
    <Checkbox
     value={item.key}
     key={item.key}
     onChange={checkChange}
    >
     {item.title}
    </Checkbox>
    );
   })}
   </Checkbox.Group>
  </div>
  </div>
 );
 };
 const rowSelection = {
 selectedRowKeys,
 // onSelect,
 // getCheckboxProps: (record: any) => ({
 // disabled: selectAllDisabled,
 // }),
 renderCell: (checked: any, record: any) => {
  //当前record.key对应大初始化数据的一级所有数据
  let parentArr = initialData?.current?.find(
  (d: any) => d.key === record.key
  );
  //从所有已经选择过的数据中过滤出在parentArr中的数据
  let checkArr = parentArr?.checkboxData?.filter(
  (item: any) => checkedJob.indexOf(item.key) > -1
  );
  return (
  <Checkbox
   indeterminate={
   parentArr?.checkboxData &&
   !!checkArr?.length &&
   checkArr.length < parentArr.checkboxData.length
    ? true
    : false
   } //比较 当过滤后选中数据的长度 < 初始化数据的长度时,设置 indeterminate 状态为true,否则为false
   onClick={(e) => onClick(e, record)}
   checked={checked}
   disabled={selectAllDisabled}
  ></Checkbox>
  );
 },
 };
 return (
 <div
  style={{
  background: "#fff",
  padding: 24,
  boxSizing: "border-box",
  width: 982,
  }}
 >
  <Search
  placeholder="请输入岗位名称"
  onSearch={(value) => {
   console.log(loop(value));
   setData(loop(value));
  }}
  />
  <Table
  showHeader={false}
  columns={columns}
  expandable={{
   expandedRowRender,
   onExpand,
   expandedRowKeys,
  }}
  dataSource={data}
  pagination={false}
  rowSelection={rowSelection}
  />
 </div>
 );
};
const columns = [{ title: "title", dataIndex: "title", key: "title" }];

以上这篇Ant design vue table 单击行选中 勾选checkbox教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript 面向对象之重载
May 04 Javascript
Tips 带三角可关闭的文字提示
Oct 06 Javascript
JavaScript Memoization 让函数也有记忆功能
Oct 27 Javascript
JS事件Event元素(兼容IE,Firefox,Chorme)
Nov 01 Javascript
解决checkbox的attr(checked)一直为undefined问题
Jun 16 Javascript
JS实现仿腾讯微博无刷新删除微博效果代码
Oct 16 Javascript
JavaScript实现移动端滑动选择日期功能
Jun 21 Javascript
JS中script标签defer和async属性的区别详解
Aug 12 Javascript
Vue键盘事件用法总结
Apr 18 Javascript
详解vue-cli + webpack 多页面实例配置优化方法
Jul 13 Javascript
JavaScript动态绑定详解
Sep 14 Javascript
vue实现的网易云音乐在线播放和下载功能案例
Feb 18 Javascript
Antd的Table组件嵌套Table以及选择框联动操作
Oct 24 #Javascript
解决Antd 里面的select 选择框联动触发的问题
Oct 24 #Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
Oct 24 #Javascript
jquery插件懒加载的示例
Oct 24 #jQuery
在react-antd中弹出层form内容传递给父组件的操作
Oct 24 #Javascript
Antd下拉选择,自动匹配功能的实现
Oct 24 #Javascript
在react项目中使用antd的form组件,动态设置input框的值
Oct 24 #Javascript
You might like
【动漫杂谈】关于《请在T台上微笑》
2020/03/03 日漫
实现树状结构的两种方法
2006/10/09 PHP
PHP 伪静态隐藏传递参数名的四种方法
2010/02/22 PHP
PHP执行zip与rar解压缩方法实现代码
2010/12/05 PHP
html中使用javascript调用本地程序(exe、doc等)实现代码
2013/04/26 Javascript
jQuery选择器中含有空格的使用示例及注意事项
2013/08/25 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
JavaScript实现算术平方根算法-代码超简单
2015/09/11 Javascript
jQuery实现自动输入email、时间和域名的方法
2016/08/24 Javascript
js实现右键自定义菜单
2016/12/03 Javascript
jQuery实现最简单实用的分秒倒计时
2017/02/05 Javascript
canvas 绘制圆形时钟
2017/02/22 Javascript
JavaScript程序设计高级算法之动态规划实例分析
2017/11/24 Javascript
Linux Centos7.2下安装nodejs&amp;npm配置全局路径的教程
2018/05/15 NodeJs
vue-cli初始化项目中使用less的方法
2018/08/09 Javascript
vue引入axios同源跨域问题
2018/09/27 Javascript
vue路由中前进后退的一些事儿
2019/05/18 Javascript
从零学Python之引用和类属性的初步理解
2014/05/15 Python
Python的Flask框架中Flask-Admin库的简单入门指引
2015/04/07 Python
Python编程中使用Pillow来处理图像的基础教程
2015/11/20 Python
numpy使用技巧之数组过滤实例代码
2018/02/03 Python
Python闭包函数定义与用法分析
2018/07/20 Python
pytorch 常用函数 max ,eq说明
2020/06/28 Python
基于Python爬取股票数据过程详解
2020/10/21 Python
python中openpyxl和xlsxwriter对Excel的操作方法
2021/03/01 Python
div或img图片高度随宽度自适应的方法
2020/02/06 HTML / CSS
意大利在线药房:Saninforma
2021/02/11 全球购物
《长城》教学反思
2014/02/14 职场文书
法学专业毕业生求职信
2014/06/12 职场文书
党支部创先争优承诺书
2014/08/30 职场文书
父亲节活动总结
2015/02/12 职场文书
民政工作个人总结
2015/02/28 职场文书
祝寿主持词
2015/07/02 职场文书
2016国培学习心得体会
2016/01/08 职场文书
国产动画《万圣街》日语配音版制作决定!
2022/03/20 国漫