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 相关文章推荐
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(下:动画篇)
Mar 24 Javascript
javascript 广告后加载,加载完页面再加载广告
Nov 25 Javascript
js opener的使用详解
Jan 11 Javascript
JS 弹出层 定位至屏幕居中示例
May 21 Javascript
JS实现的生成随机数的4个函数分享
Feb 11 Javascript
jQuery实现的超酷苹果风格图标滑出菜单效果代码
Sep 16 Javascript
JS实现兼容性好,带缓冲的动感网页右键菜单效果
Sep 18 Javascript
详解AngularJS中的filter过滤器用法
Jan 04 Javascript
Reactjs实现通用分页组件的实例代码
Jan 19 Javascript
VScode格式化ESlint方法(最全最好用方法)
Sep 10 Javascript
微信小程序实现横向滚动导航栏效果
Dec 12 Javascript
微信小程序实现同时上传多张图片
Feb 03 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
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
2011/04/07 PHP
分享php代码将360浏览器导出的favdb的sqlite数据库文件转换为html
2015/12/09 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
2016/02/14 PHP
yii2 页面底部加载css和js的技巧
2016/04/21 PHP
PHP优化之批量操作MySQL实例分析
2020/04/23 PHP
Laravel框架源码解析之模型Model原理与用法解析
2020/05/14 PHP
php实现商城购物车的思路和源码分析
2020/07/23 PHP
7个Javascript地图脚本整理
2009/10/20 Javascript
Javascript 面向对象特性
2009/12/28 Javascript
nodejs实现获取当前url地址及url各种参数值
2015/06/25 NodeJs
Ajax与服务器(JSON)通信实例代码
2016/11/05 Javascript
Javascript实现倒计时(防页面刷新)实例
2016/12/13 Javascript
浅谈如何使用 webpack 优化资源
2017/10/20 Javascript
Vue-cli Eslint在vscode里代码自动格式化的方法
2018/02/23 Javascript
浅谈Vue-cli单文件组件引入less,sass,css样式的不同方法
2018/03/13 Javascript
深入浅析Vue.js 中的 v-for 列表渲染指令
2018/11/19 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
vue 父组件通过v-model接收子组件的值的代码
2019/10/27 Javascript
详解Vue Cli浏览器兼容性实践
2020/06/08 Javascript
python获取当前日期和时间的方法
2015/04/30 Python
python计算一个序列的平均值的方法
2015/07/11 Python
在MAC上搭建python数据分析开发环境
2016/01/26 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
numpy中矩阵合并的实例
2018/06/15 Python
解决python3中的requests解析中文页面出现乱码问题
2019/04/19 Python
python GUI库图形界面开发之PyQt5工具栏控件QToolBar的详细使用方法与实例
2020/02/28 Python
Python参数传递实现过程及原理详解
2020/05/14 Python
波兰最大的宠物用品网上商店:FERA.PL
2019/08/11 全球购物
Booking.com德国:预订最好的酒店和住宿
2020/02/16 全球购物
个人优缺点自我评价
2014/01/27 职场文书
十佳护士先进事迹
2014/05/08 职场文书
党员民主生活会材料
2014/12/15 职场文书
课改心得体会范文
2016/01/25 职场文书
工作计划范文之财务管理
2019/08/09 职场文书
Python控制台输出俄罗斯方块移动和旋转功能
2021/04/18 Python
2022微信温控新功能上线
2022/05/09 数码科技