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 定义初始化数组函数
Sep 07 Javascript
javascript 主动派发事件总结
Aug 09 Javascript
jQuery链使用指南
Jan 20 Javascript
浅谈javascript原型链与继承
Jul 13 Javascript
JS简单实现父子窗口传值功能示例【未使用iframe框架】
Sep 20 Javascript
加载 vue 远程代码的组件实例详解
Nov 20 Javascript
JS实现的合并多个数组去重算法示例
Apr 11 Javascript
详解微信小程序的 request 封装示例
Aug 21 Javascript
详解mpvue scroll-view自动回弹bug解决方案
Oct 01 Javascript
video.js 一个页面同时播放多个视频的实例代码
Nov 27 Javascript
vue elementUI使用tabs与导航栏联动
Jun 21 Javascript
js点击事件的执行过程实例分析【冒泡与捕获】
Apr 11 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 从数据库提取二进制图片的处理代码
2009/09/09 PHP
Zend的Registry机制的使用说明
2013/05/02 PHP
解析php开发中的中文编码问题
2013/08/08 PHP
WordPress中登陆后关闭登陆页面及设置用户不可见栏目
2015/12/31 PHP
屏蔽PHP默认设置中的Notice警告的方法
2016/05/20 PHP
Linux下 php7安装redis的方法
2018/11/01 PHP
推荐dojo学习笔记
2007/03/24 Javascript
js apply/call/caller/callee/bind使用方法与区别分析
2009/10/28 Javascript
Javascript面向对象设计一 工厂模式
2011/12/20 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
2012/04/07 Javascript
Javascript 遍历页面text控件详解
2014/01/06 Javascript
深入浅析JavaScript中prototype和proto的关系
2015/11/15 Javascript
jQuery div拖拽用法实例
2016/01/14 Javascript
Java  Spring 事务回滚详解
2016/10/17 Javascript
vue.js移动端app实战1:初始配置详解
2017/07/24 Javascript
AngularJS 打开新的标签页实现代码
2017/09/07 Javascript
基于vue+axios+lrz.js微信端图片压缩上传方法
2019/06/25 Javascript
Vue 监听元素前后变化值实例
2020/07/29 Javascript
python socket网络编程之粘包问题详解
2018/04/28 Python
matplotlib savefig 保存图片大小的实例
2018/05/24 Python
python实现字符串中字符分类及个数统计
2018/09/28 Python
Ubuntu16.04安装python3.6.5步骤详解
2020/01/10 Python
Pandas将列表(List)转换为数据框(Dataframe)
2020/04/24 Python
浅谈Python爬虫原理与数据抓取
2020/07/21 Python
Pycharm 如何一键加引号的方法步骤
2021/02/05 Python
使用HTML5和CSS3表单验证功能
2017/05/05 HTML / CSS
美国在线鲜花速递:ProFlowers
2017/01/05 全球购物
全球立体声:World Wide Stereo
2018/09/29 全球购物
结构工程个人自荐信范文
2013/11/30 职场文书
饲料采购员岗位职责
2013/12/19 职场文书
公积金转移接收函
2014/01/11 职场文书
小学生环保倡议书
2014/05/15 职场文书
我们的节日春节活动方案
2014/08/22 职场文书
校庆团日活动总结
2014/08/28 职场文书
2014年高数考试作弊检讨书
2014/12/14 职场文书
Mysql 数据库中的 redo log 和 binlog 写入策略
2022/04/26 MySQL