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 一个自定义长度的文本自动换行的函数
Aug 19 Javascript
使用jscript实现二进制读写脚本代码
Jun 09 Javascript
JS 无法通过W3C验证的处理方法
Mar 09 Javascript
封装了一个js图片轮换效果的函数
Sep 28 Javascript
JS实现点击下载的小例子
Jul 10 Javascript
js实现的页面矩阵图形变换特效
Jan 26 Javascript
javascript实现方法调用与方法触发小结
Mar 26 Javascript
Bootstrap table使用方法记录
Aug 23 Javascript
vue 音乐App QQ音乐搜索列表最新接口跨域设置方法
Sep 25 Javascript
layui 富文本图片上传接口与普通按钮 文件上传接口的例子
Sep 23 Javascript
vue列表数据发生变化指令没有更新问题及解决方法
Jan 16 Javascript
js实现网页随机验证码
Oct 19 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
一个分页的论坛
2006/10/09 PHP
php中配置文件操作 如config.php文件的读取修改等操作
2012/07/07 PHP
PHP多线程批量采集下载美女图片的实现代码(续)
2013/06/03 PHP
将php数组输出html表格的方法
2014/02/24 PHP
php中$美元符号与Zen Coding冲突问题解决方法分享
2014/05/28 PHP
PHP+Ajax实现无刷新分页实例详解(附demo源码下载)
2016/04/07 PHP
防止网站内容被拷贝的一些方法与优缺点好处与坏处分析
2007/11/30 Javascript
原生javascript实现图片轮播效果代码
2010/09/03 Javascript
jQuery中height()方法用法实例
2014/12/24 Javascript
理解JS绑定事件
2016/01/19 Javascript
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
2018/05/22 Javascript
详解vue移动端项目代码拆分记录
2019/03/15 Javascript
微信小程序 数据缓存实现方法详解
2019/08/26 Javascript
vue制作抓娃娃机的示例代码
2020/04/17 Javascript
40行代码把Vue3的响应式集成进React做状态管理
2020/05/20 Javascript
浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑
2020/09/12 Javascript
python利用hook技术破解https的实例代码
2013/03/25 Python
Python列出一个文件夹及其子目录的所有文件
2016/06/30 Python
对numpy中的transpose和swapaxes函数详解
2018/08/02 Python
python pandas实现excel转为html格式的方法
2018/10/23 Python
python 接收处理外带的参数方法
2018/12/03 Python
Python中shapefile转换geojson的示例
2019/01/03 Python
python实现批量视频分帧、保存视频帧
2019/05/31 Python
查看Python依赖包及其版本号信息的方法
2019/08/13 Python
python实现的发邮件功能示例
2019/09/11 Python
python matplotlib imshow热图坐标替换/映射实例
2020/03/14 Python
HTML5不支持标签和新增标签详解
2016/06/27 HTML / CSS
台湾三立电视电商平台:电电购
2019/09/09 全球购物
销售会计工作职责
2013/12/02 职场文书
《充气雨衣》教学反思
2014/04/07 职场文书
民族团结先进集体事迹材料
2014/05/22 职场文书
机关党员三严三实心得体会
2014/10/13 职场文书
圣诞晚会主持词开场白
2015/05/28 职场文书
孔繁森观后感
2015/06/10 职场文书
运动会入场词
2015/07/18 职场文书
python实现自定义日志的具体方法
2021/05/28 Python