目录
- vue结构
- 1、sessionStorage
- 2、路由跳转及携带参数
- 3、正则验证test
- 3、$set的使用
- 4、find的用法
- 5、findIndex()的用法
- 6、filter()的用法
- 7、includes()的用法
- 8、some()的用法
- 9、every()的用法
- 10、reduce的用法
- 11、splice的用法
- 12、移动端实现高度满屏
- 13、数组对象去重
- 14、vue修改路由递归
- 15、获取对象的key值
- 15、获取对象的value值
- 16、获取数组对象中某一属性值的集合
- 17、for循环删除
- 18、防抖
- 19、节流
- 20、浏览器临时缓存处理
- 21、浏览器永久缓存处理
- 22、常用获取日期函数封装
- 23、路由守卫
- 24、word/excel下载
- 25、element-ui table表前端分页
- 26、element-ui 常用table页面
- 27、浏览器滚轮样式修改
- 28、科学记数法转数字
- 29、取两个数组中不同的值
- 30、Array结构转tree结构
- 31、tree结构转Array结构
- 32、响应状态码
- 33、数组取交集并集差集
- 34、数组对象取交集差集
- 35、数组对象去重
- 36、formData拼接封装
- 37、点击下载
- 38、日期格式化
- 39、el-input禁止输入非数字以外字符
- 40、常用el-input字符限制
vue结构
var vm = new Vue({
el: '#app', // 控制区域
data: { }, // 定义数据
methods: { }, // 定义事件方法
filters: { }, // 定义私有的过滤器
directives: { }, // 定义私有的指令
components: { }, // 定义实例内部私有的组件
watch:{ }, // 监听值的变化,然后执行相对应的函数(或者步骤)
beforeCreate() { }, // 实例刚在内存中被创建出来,还没初始化好 data 和 methods 属性之前调用此函数
created() { }, // 实例已经在内存中创建完成,此时 data 和 methods 属性初始化完成,页面(HTML)加载完成之前(未开始编译模板)调用此函数。执行顺序:父组件 -> 子组件
beforeMount() { }, // 此时已经完成了模板的编译,但是还没有挂载到页面中,在挂载开始之前调用此函数
mounted() { }, // 此时已经将编译好的模板,挂载到了页面指定的容器中显示。页面(HTML)加载完成之后调用此函数。执行顺序:子组件 -> 父组件
beforeUpdate() { }, // 状态更新之前调用此函数,此时 data 中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始重新渲染 DOM 节点
updated() { }, // 状态更新完成之后调用此函数,此时 data 中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了
beforeDestroy() { }, // 实例销毁之前调用此函数。在这一步,实例仍然完全可用
destroyed() { }, // 实例销毁后调用此函数。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁
})
1、sessionStorage
//存
sessionStorage.setItem('id', JSON.stringify(res.data))
//取
let a= sessionStorage.getItem('id')
//清空session
sessionStorage.clear()
/ 封装模块 使用localStorage实现持久化 只是进行保存
// 从localStorage中取出一项数据 名字叫name
export const getItem = name => {
return JSON.parse(localStorage.getItem(name))
}
// 向localStorage中设置一项数据 名字为name里面设置值为obj
export const setItem = (name, obj) => {
localStorage.setItem(name, JSON.stringify(obj))
}
// 删除
export const removeitem = name => {
localStorage.removeItem(name)
}
2、路由跳转及携带参数
注意点:query刷新不会丢失query里面的数据、params刷新会丢失params里面的数据。
//路由跳转
this.$router.push({path: "/a",});
//携带参数,页面刷新数据会丢失
/a?id=a
this.$router.push({path: "/a",query: {id:a,},});
//子页面取值
id: this.$route.query.id,
//页面刷新数据不会丢失
this.$router.push({ name: 'user', params: { id: '123' }})
this.$router.push({
path: `/user/${id}`,
})
//子页面取值
id: this.$route.params.id,
//对应路由
{
path: '/user/:id',
name: 'user',
component: user
}
3、正则验证test
//自定义的验证邮箱
let validEmail = (value, callback) => {
let reg = /^\w+@[a-zA-Z\d]{2,}(\.com|\.cn|\.com\.cn|\.org|\.edu|\.net)$/
if (!reg.test(value)) {
return callback(new Error('非法的邮箱'))
}
callback()
}
3、$set的使用
当数据没有被双向绑定的时候,我们就需要使用set了
给对象增加一个key
//this.$set(原数组, 索引值, 需要赋的值)
methods() {
this.$set(this.student, 'age', 15)
console.log(this.student)
}
4、find的用法
const persons= [{
name: 'Judy', sex: 'Female'
}, {
name: 'Tom', sex: 'Male'
}, {
name: 'Grace', sex: 'Female'
}]
person= persons.find(item=> item.name ==='Judy' && item.sex === 'Female');
console.log(person); // {name: "Judy", sex: "Female"}
5、findIndex()的用法
[1, 2, 5, -1, 9].findIndex((n) => n < 0)
//返回符合条件的值的位置(索引)
// 3
6、filter()的用法
var arr = [10, 20, 30, 40, 50]
var newArr = arr.filter(item => item > 30);
console.log(newArr); //[40, 50]
实现模糊查询
data: function () {
return {
msg: "",
data: [{
name: "a",
age: 12
}, {
name: "b",
age: 11
}, {
name: "c",
age: 15
}, {
name: "d",
age: 18
}, {
name: "e",
age: 10
}, ]
};
},
computed: {
data1() {
if (this.msg) {
return this.data.filter((item) => item.name === this.msg)
}else{
return this.data
}
}
},
7、includes()的用法
//includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。
//includes可以包含两个参数,第二个参数表示判断的起始位置
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
8、some()的用法
//不创建新数组、不改变原数组、判断为true则马上return true,否则return false;
let arr = [1,2,3,4,5];
let result1 = arr.some((item,index)=> {
return item > 2 && item < 4;
});
let result2 = arr.some((item,index)=>{
return item > 5;
});
console.log(result1); // 输出ture
console.log(result2); // 输出false
9、every()的用法
//不创建新数组、不改变原数组、判断为false则马上return false,否则return true;
let arr = [1,2,3,4,5];
let result1 = arr.every((item)=> {
return item > 2;
});
let result2 = arr.every((item)=>{
return item < 6;
});
console.log(result1); // 输出false
console.log(result2); // 输出true
10、reduce的用法
let arr = ["q", "w", "e", "r"]
let b = arr.reduce(function (pre, cur) {
console.log(pre, cur);
return pre + cur
})
输出:
q w
qw e
qwe r
//数组去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(newArr);// [1, 2, 3, 4]
11、splice的用法
arr.splice(0, 1);//下标为0的位置删除1个元素
12、移动端实现高度满屏
div{
height: 100%;
width: 100%;
position: absolute;
top: 0px;
bottom: 0px;
}
13、数组对象去重
let arr = [{
a: "1",
b: "2",
c: "3"
},
{
a: "2",
b: "3",
c: "4"
},
{
a: "2",
b: "3",
c: "4"
},
{
a: "1",
b: "2",
c: "3"
},
]
var newArr = []; //新数组
for (var i = 0; i < arr.length; i++) {
var flag = true;
for (var j = 0; j < newArr.length; j++) {
if (arr[i].a == newArr[j].a && arr[i].b == newArr[j].b && arr[i].c == newArr[j].c) {
flag = false;
};
};
if (flag) {
newArr.push(arr[i]);
};
};
14、vue修改路由递归
let obj = [{
a: 1,
b: 2,
children: [{
a: 3,
b: 4,
children: [{
a: 10,
b: 11
}]
}]
}, {
a: 4,
b: 5
}]
function app(obj) {
let res = []
obj.forEach(item => {
var router = {
path: item.a,
name: item.b,
children: item.children || []
}
if (item.children) {
var childrenlist = app(item.children)
router.children = childrenlist
}
res.push(router)
})
return res
}
console.log(app(obj));
15、获取对象的key值
let a2 = {
b: 3,
c: 4,
}
console.log(Object.keys(a2));
//["b","c"]
15、获取对象的value值
let a2 = {
b: 3,
c: 4,
}
console.log(Object.keys(a2));
//[3,4]
16、获取数组对象中某一属性值的集合
var user = [
{
id: 1,
name: "李四"
},
{
id: 2,
name: "张三"
},
{
id: 3,
name: "李五"
}
]
var userName = Array.from(user,({name})=>name);
console.log(userName); // ["李四", "张三", "李五"]
17、for循环删除
双层for循环删除
for (let i = a.length - 1; i >= 0; i--) {
for (let j = b.length - 1; j >= 0; j--) {
if (a[i].Id === b[j].Id) {
a.splice(i, 1);
break;
}
}
}
//封装
deleteData(arr1,arr2,sameData){
for (let i = arr1.length - 1; i >= 0; i--) {
for (let j = arr2.length - 1; j >= 0; j--) {
if (arr1[i].sameData === arr2[j].sameData) {
arr1.splice(i, 1);
break;
}
}
}
},
单层for循环删除–正序循环删除
const arr = [1,2,3,4,5,6,7,8]
for(let i = 0, len = arr.length; i < len; i++) {
if(arr[i] < 5) {
arr.splice(i, 1)
i--;
}
}
// arr = [5, 6, 7, 8] 符合预期
单层for循环删除–倒序循环删除
const arr = [1,2,3,4,5,6,7,8]
for(let i = arr.length - 1; i >= 0; i--) {
if(arr[i] < 5) {
arr.splice(i, 1)
}
}
// arr = [5, 6, 7, 8] 符合预期
18、防抖
第一种
function debounce(fn, delay) {
let timer
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
// 测试1
function task() {
console.log('run task')
}
const debounceTask = debounce(task, 1000)
window.addEventListener('scroll', debounceTask)
//测试2
function task() {
console.log('run task')
}
const debounceTask = debounce(task, 1000)
btn.onclick = function () {
debounceTask()
}
第二种
export function debounce(func, delay, immediate = false) {
let timer,
context = this;
return (...args) => {
if (immediate) {
func.apply(context, args);
immediate = false;
return;
}
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args);
}, delay);
};
}
19、节流
function throttle(fn, delay) {
let last = 0 // 上次触发时间
return (...args) => {
const now = Date.now()
if (now - last > delay) {
last = now
fn.apply(this, args)
}
}
}
// 测试
function task() {
console.log('run task')
}
const throttleTask = throttle(task, 1000)
window.addEventListener('scroll', throttleTask)
20、浏览器临时缓存处理
/**
* window.sessionStorage 浏览器临时缓存
* @method set 设置临时缓存
* @method get 获取临时缓存
* @method remove 移除临时缓存
* @method clear 移除全部临时缓存
*/
export const Session = {
// 设置临时缓存
set(key: string, val: any) {
window.sessionStorage.setItem(key, JSON.stringify(val));
},
// 获取临时缓存
get(key: string) {
let json: any = window.sessionStorage.getItem(key);
return JSON.parse(json);
},
// 移除临时缓存
remove(key: string) {
window.sessionStorage.removeItem(key);
},
// 移除全部临时缓存
clear() {
window.sessionStorage.clear();
},
};
21、浏览器永久缓存处理
/**
* window.localStorage 浏览器永久缓存
* @method set 设置永久缓存
* @method get 获取永久缓存
* @method remove 移除永久缓存
* @method clear 移除全部永久缓存
*/
export const Local = {
// 设置永久缓存
set(key: string, val: any) {
window.localStorage.setItem(key, JSON.stringify(val));
},
// 获取永久缓存
get(key: string) {
let json: any = window.localStorage.getItem(key);
return JSON.parse(json);
},
// 移除永久缓存
remove(key: string) {
window.localStorage.removeItem(key);
},
// 移除全部永久缓存
clear() {
window.localStorage.clear();
},
};
22、常用获取日期函数封装
/**
* 时间日期转换
* @param date 当前时间,new Date() 格式
* @param format 需要转换的时间格式字符串
* @description format 字符串随意,如 `YYYY-mm、YYYY-mm-dd`
* @description format 季度:"YYYY-mm-dd HH:MM:SS QQQQ"
* @description format 星期:"YYYY-mm-dd HH:MM:SS WWW"
* @description format 几周:"YYYY-mm-dd HH:MM:SS ZZZ"
* @description format 季度 + 星期 + 几周:"YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ"
* @returns 返回拼接后的时间字符串
*/
export function formatDate(date: Date, format: string): string {
let we = date.getDay(); // 星期
let z = getWeek(date); // 周
let qut = Math.floor((date.getMonth() + 3) / 3).toString(); // 季度
const opt: { [key: string]: string } = {
'Y+': date.getFullYear().toString(), // 年
'm+': (date.getMonth() + 1).toString(), // 月(月份从0开始,要+1)
'd+': date.getDate().toString(), // 日
'H+': date.getHours().toString(), // 时
'M+': date.getMinutes().toString(), // 分
'S+': date.getSeconds().toString(), // 秒
'q+': qut, // 季度
};
// 中文数字 (星期)
const week: { [key: string]: string } = {
'0': '日',
'1': '一',
'2': '二',
'3': '三',
'4': '四',
'5': '五',
'6': '六',
};
// 中文数字(季度)
const quarter: { [key: string]: string } = {
'1': '一',
'2': '二',
'3': '三',
'4': '四',
};
if (/(W+)/.test(format))
format = format.replace(RegExp.$1, RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? '星期' + week[we] : '周' + week[we]) : week[we]);
if (/(Q+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 4 ? '第' + quarter[qut] + '季度' : quarter[qut]);
if (/(Z+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 3 ? '第' + z + '周' : z + '');
for (let k in opt) {
let r = new RegExp('(' + k + ')').exec(format);
// 若输入的长度不为1,则前面补零
if (r) format = format.replace(r[1], RegExp.$1.length == 1 ? opt[k] : opt[k].padStart(RegExp.$1.length, '0'));
}
return format;
}
/**
* 获取当前日期是第几周
* @param dateTime 当前传入的日期值
* @returns 返回第几周数字值
*/
export function getWeek(dateTime: Date): number {
let temptTime = new Date(dateTime.getTime());
// 周几
let weekday = temptTime.getDay() || 7;
// 周1+5天=周六
temptTime.setDate(temptTime.getDate() - weekday + 1 + 5);
let firstDay = new Date(temptTime.getFullYear(), 0, 1);
let dayOfWeek = firstDay.getDay();
let spendDay = 1;
if (dayOfWeek != 0) spendDay = 7 - dayOfWeek + 1;
firstDay = new Date(temptTime.getFullYear(), 0, 1 + spendDay);
let d = Math.ceil((temptTime.valueOf() - firstDay.valueOf()) / 86400000);
let result = Math.ceil(d / 7);
return result;
}
23、路由守卫
//全局守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
//路由独享守卫
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
beforeRouteEnter (to, from, next) {},
beforeRouteUpdate (to, from, next) {},
beforeRouteLeave (to, from, next) {}
24、word/excel下载
netDownLoadNet(num).then((res) => {
if (!res || !res) {
return;
}
let blob = new Blob([res], {
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8",//word
// type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',//excel
});
const link = document.createElement("a");
link.style.display = "none";
link.href = URL.createObjectURL(blob);
link.download = "帮助文档.docx"; //下载的文件名
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
export function netDownLoadNet(type) {
return request({
url: `/netDownLoadNet/${type}`,
method: 'get',
contentType: 'application/json',
responseType: 'blob',
})
}
25、element-ui table表前端分页
<el-table :data="state.tableData.slice((state.pagination.pageNum-1)*state.pagination.pageSize,state.pagination.pageNum*state.pagination.pageSize)" style="width: 100%" :header-cell-style="{background:'#eef1f6',color:'#606266'}">
<el-table-column type="index" :index="indexMethod" label="序号" width="80" />
<el-table-column label="操作" width="120">
<template #default="scope">
<el-button type="text" size="small" @click="handle(scope.$index, scope.row)">处理</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination v-model:currentPage="state.pagination.pageNum" background="true" :page-sizes="[10, 20, 30, 40]" :page-size="state.pagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="state.tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange">
</el-pagination>
</div>
const state = reactive({
tableData: <any>[],
pagination: {
pageNum: 1,
pageSize: 10,
},
});
const indexMethod = (index: number) => {
return state.pagination.pageSize * (state.pagination.pageNum - 1) + index + 1;
};
const handleSizeChange = (val: number) => {
state.pagination.pageSize = val;
};
const handleCurrentChange = (val: number) => {
console.log(state.pagination.pageNum);
};
26、element-ui 常用table页面
<template>
<div class="app-container">
<div class="filter-container">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="审批人">
<el-input v-model="formInline.user" placeholder="审批人"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="formInline.region" placeholder="活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
<el-button type="primary" @click="onAdd">新增</el-button>
<el-button type="primary" @click="onReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-table :data="tableData" style="width: 100%">
<el-table-column label="Date" prop="date">
</el-table-column>
<el-table-column label="Name" prop="name">
</el-table-column>
<el-table-column align="right">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form :model="form" :rules="rules" label-position="left" label-width="120px" style="margin-left:50px;">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
</div>
</el-dialog>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
</div>
</template>
<script>
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
export default {
name: "roles",
components: { Pagination },
data() {
return {
formInline: {
user: "",
region: "",
},
total: 5,
listQuery: {
page: 1,
limit: 10,
},
textMap: {
update: "编辑",
create: "新增",
},
dialogStatus: "",
dialogFormVisible: false,
tableData: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
},
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄",
},
],
form: {
name: "",
region: "",
},
rules: {
name: [
{ required: true, message: "name is required", trigger: "change" },
],
region: [
{ required: true, message: "region is required", trigger: "change" },
],
},
};
},
created() {},
methods: {
onSubmit() {
console.log("submit!");
},
onAdd() {
this.dialogStatus = "create";
this.dialogFormVisible = true;
},
onReset() {
this.form = {
name: "",
region: "",
};
this.getList();
},
getList() {},
handleEdit(index, row) {
console.log(index, row);
this.dialogStatus = "update";
this.dialogFormVisible = true;
},
handleDelete(index, row) {
console.log(index, row);
},
},
};
</script>
27、浏览器滚轮样式修改
.contain {
width:100px;
overflow-y: scroll;
&::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: #e4e4e4;
border-radius: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: #a1a3a9;
border-radius: 6px;
}
}
28、科学记数法转数字
function getFullNum(num) {
//处理非数字
if (isNaN(num)) {
return num
};
//处理不需要转换的数字
var str = '' + num;
if (!/e/i.test(str)) {
return num;
};
return (num).toFixed(18).replace(/\.?0+$/, "");
}
console.log(getFullNum(1.1689243924737556E-4));//0.00011689243924737556
29、取两个数组中不同的值
string数组
function getNoSameVal(arr1, arr2) {
var temp = arr1.concat(arr2);
var rel = {};
var end = [];
for (var i = 0; i < temp.length; i++) {
temp[i] in rel ? rel[temp[i]]++ : rel[temp[i]] = 1;
}
for (x in rel) {
if (rel[x] == 1) {
end.push(x);
}
}
return end
}
let a = ['2', '12'];
let b = ["1", "2", "3", "4", "2", "2"];
console.log(test(a, b));//['1', '3', '4', '12']
obj数组
let arr1 = [{
a: 1,
b: 2
}, {
a: 3,
b: 1
}];
let arr2 = [{
a: 1,
b: 2
}, {
a: 3,
b: 5
}];
const arr3 = arr1
.map(JSON.stringify)
.concat(arr2.map(JSON.stringify))
.filter((v, i, arr) => {
return arr.indexOf(v) === arr.lastIndexOf(v);
})
.map(JSON.parse);
console.log(arr3);//[{a:3,b:1}, {a: 3,b: 5}]
30、Array结构转tree结构
/** 数组结构数据 */
const arrayData = [
{ id: 2, title: '中国', parent_id: 0 },
{ id: 3, title: '广东省', parent_id: 2 },
{ id: 4, title: '广州市', parent_id: 3 },
{ id: 5, title: '天河区', parent_id: 4 },
{ id: 6, title: '湖南省', parent_id: 2 },
{ id: 1, title: '俄罗斯', parent_id: 0 }
]
使用递归的方法
/**
* 递归查找添加children
* @param {数组数据} data
* @param {存放返回结果} result
* @param {父id} pid
*/
function getChildren(data, result, pid) {
for (const item of data) {
if (item.parent_id === pid) {
const newItem = { children: [], ...item }
result.push(newItem)
getChildren(data, newItem.children, item.id)
}
}
}
/**
* 转化方法
* @param {数组数据} data
* @param {父id} pid
* @returns
*/
function arrayToTree(data, pid) {
let result = []
getChildren(data, result, pid)
return result
}
console.log(arrayToTree(arrayData, 0));
使用循环的方法
/**
* 数组结构转为树结构
* @param {*} data 数组数据
* @returns
*/
function arrayToTree(data) {
const result = []
const obj = data.reduce((pre, cur) => {
pre[cur.id] = cur
return pre
}, {})
for (let item of data) {
if (item.parent_id === 0) {
result.push(item)
continue
}
if (item.parent_id in obj) {
const parent = obj[item.parent_id];
parent.children = parent.children || [];
parent.children.push(item);
}
}
return result
}
31、tree结构转Array结构
const treeData = [
{
id: 2, title: '中国', parent_id: 0,
children: [
{
id: 3, title: '广东省', parent_id: 2,
children: [
{
id: 4, title: '广州市', parent_id: 3,
children: [
{ id: 5, title: '天河区', parent_id: 4 }
]
}
]
},
{ id: 6, title: '湖南省', parent_id: 2 }
]
},
{ id: 1, title: '俄罗斯', parent_id: 0, },
]
使用递归的方法
/**
* 树结构数组扁平化
* @param {*} data 树结构的数组
* @returns
*/
function treeToArray(data) {
return data.reduce((pre, cur) => {
const { children = [], ...item } = cur;
return pre.concat([{ ...item }], treeToArray(children))
}, []);
}
使用循环的方法
/**
* 根据id查找所在目录路径
* @param {树结构的数组数据} tree
* @param {要查找的id} id
* @param {初始路径} path
* @returns
*/
function parseTreePath(tree, id, path = "") {
for (let i = 0; i < tree.length; i++) {
let tempPath = path;
// 避免出现在最前面的/
tempPath = `${tempPath ? tempPath + "/ " : tempPath}${tree[i].title}`;
if (tree[i].id == id) return tempPath;
else if (tree[i].children) {
let reuslt = parseTreePath(tree[i].children, id, tempPath);
if (reuslt) return reuslt;
}
}
};
console.log(parseTreePath(treeData, 5));
32、响应状态码
export const checkStatus = (status: number): void => {
switch (status) {
case 400:
message.error("请求失败!请您稍后重试");
break;
case 401:
message.error("登录失效!请您重新登录");
break;
case 403:
message.error("当前账号无权限访问!");
break;
case 404:
message.error("你所访问的资源不存在!");
break;
case 405:
message.error("请求方式错误!请您稍后重试");
break;
case 408:
message.error("请求超时!请您稍后重试");
break;
case 500:
message.error("服务异常!");
break;
case 502:
message.error("网关错误!");
break;
case 503:
message.error("服务不可用!");
break;
case 504:
message.error("网关超时!");
break;
default:
message.error("请求失败!");
}
};
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本
33、数组取交集并集差集
const collectionA = [1, 2, 3, 4]
const collectionB = [2, 4, 6, 8]
const collectionC = collectionA.filter(c => collectionB.some(d => d === c)) // [2, 4]
console.log(collectionC);
const collectionD = collectionA.filter(c => !collectionB.some(d => d === c)) // [1, 3]
console.log(collectionD);
const collectionE = collectionB.filter(c => !collectionA.some(d => d === c)) // [6, 8]
console.log(collectionE);
34、数组对象取交集差集
数组对象求交集
let a= [{id:'111',name:'a1'},{id:'222',name:'a2'}];
let b = [{id:'111',name:'b1'},{id:'222',name:'b2'},{id:'333',name:'b3'}];
let arr1 = [...b].filter(x => [...a].some(y => y.id === x.id));
console.log(arr1); //[{id:'111',name:'b1'},{id:'222',name:'b2'}]
let arr2 = [...a].filter(x => [...b].some(y => y.id === x.id));
console.log(arr2); //[{id:'111',name:'a1'},{id:'222',name:'a2'}]
数组对象求差集
let a= [{id:'111',name:'a1'},{id:'222',name:'a2'}];
let b = [{id:'111',name:'b1'},{id:'222',name:'b2'},{id:'333',name:'b3'}];
let arr1 = [...b].filter(x => [...a].every(y => y.id !== x.id));
console.log(arr1); //[{id:'333',name:'b3'}]
let arr2 = [...a].filter(x => [...b].every(y => y.id !== x.id));
console.log(arr2); //[]
35、数组对象去重
let arr = [{id:'111',name:'a1'},{id:'222',name:'a2'},{id:'111',name:'b1'},{id:'222',name:'b2'},{id:'333',name:'b3'}];
function dropFilter(test) {
// ele:当前元素的值,index:当前元素的索引值,arr:原数组
return test.filter((ele,index,arr)=>{
// 通过索引筛掉相同的项 id为对象中唯一值
return arr.findIndex(item=>item.id===ele.id) === index
})
}
dropFilter(arr);
//[{id:'111',name:'a1'},{id:'222',name:'a2'},{id:'333',name:'b3'}];
dropReduce(list) {
// 定义一个空对象,利用对象的键的唯一进行去重
let obj = {}
// 去重(cur:init默认list,next:数组子项,index:表示当前正在处理的数组元素的索引,arr:表示原数组) id为对象中唯一值
return list.reduce((cur,next,index,arr) => {
obj[next.id]?"":obj[next.id]=true && cur.push(next)
return cur
}, [])
}
dropReduce(arr)
//[{id:'111',name:'a1'},{id:'222',name:'a2'},{id:'333',name:'b3'}];
36、formData拼接封装
传入form的obj对象
getFormData(object) {
const formData = new FormData()
Object.keys(object).forEach((key) => {
const value = object[key]
if (Array.isArray(value)) {
value.forEach((subValue, i) =>
formData.append(key + `[${i}]`, subValue)
)
} else {
formData.append(key, object[key])
}
})
return formData
},
37、点击下载
handleDownload(file) {
let a = document.createElement('a')
let event = new MouseEvent('click')
a.download = file.name //文件名称
a.href = file.response || file.url //文件地址
a.target = '_blank'
a.dispatchEvent(event)
},
38、日期格式化
获取年月日时分秒
function formatDate (data) {
function add0(num) {
return num < 10 ? '0' + num : num
} // 个位数的值在前面补0
const date = new Date(data)
const Y = date.getFullYear()
const M = date.getMonth() + 1
const D = date.getDate()
const h = date.getHours()
const m = date.getMinutes()
const s = date.getSeconds()
const dateString =
Y +
'-' +
add0(M) +
'-' +
add0(D) +
' ' +
add0(h) +
':' +
add0(m) +
':' +
add0(s)
return dateString
}
39、el-input禁止输入非数字以外字符
<el-input v-model="val" @input="changeVal"></el-input>
changeAmount() {
let value = this.val
let lastValidValue = value.replace(/[^\d]/g, '')
if (parseInt(lastValidValue) < 0 || isNaN(parseInt(value))) {
this.val = lastValidValue
} else {
this.val = parseInt(value)
}
},
40、常用el-input字符限制
rules: {
name: [
{ required: true, message: "请输入活动名称", trigger: "blur" },
{
min: 1,
max: 25,
message: "长度在 1 到 25 个字符",
trigger: "blur",
},
// {
// pattern: /^[\u4E00-\u9FA5]{1,}$/,
// message: "只能输入汉字",
// trigger: "blur",
// },
// {
// pattern: /^[A-Za-z0-9]{1,}$/,
// message: "只能输入英文数字",
// trigger: "blur",
// },
],
},
数字:/^[0-9]*$/
n位的数字:/^\d{n}$/
至少n位的数字:/^\d{n,}$/
m-n位的数字:/^\d{m,n}$/
价格:/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/
零和非零开头的数字:/^(0|[1-9][0-9]*)$/
非零开头的最多带两位小数的数字:/^([1-9][0-9]*)+(\.[0-9]{1,2})?$/
带1-2位小数的正数或负数:/^(\-)?\d+(\.\d{1,2})$/
正数、负数、和小数:/^(\-|\+)?\d+(\.\d+)?$/
有两位小数的正实数:/^[0-9]+(\.[0-9]{2})?$/
有1~3位小数的正实数:/^[0-9]+(\.[0-9]{1,3})?$/
非零的正整数:/^[1-9]\d*$/ 或 /^([1-9][0-9]*){1,3}$/ 或 /^\+?[1-9][0-9]*$/
非零的负整数:/^\-[1-9][]0-9"*$/ 或 /^-[1-9]\d*$/
非负整数:/^\d+$/ 或 /^[1-9]\d*|0$/
非正整数:/^-[1-9]\d*|0$/ 或 /^((-\d+)|(0+))$/
非负浮点数:/^\d+(\.\d+)?$/ 或 /^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$/
非正浮点数:/^((-\d+(\.\d+)?)|(0+(\.0+)?))$/ 或 /^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$/
正浮点数:/^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$/ 或 /^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/
负浮点数:/^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$/ 或 /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/
浮点数:/^(-?\d+)(\.\d+)?$/ 或 /^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$/
// 其他特殊校验
4~20位英文+数字: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{4,20}$/
大写英文: /^[A-Z]+$/
邮箱: /^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+)$/ 或 /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
手机: /^1[3456789]\d{9}$/ 或 /^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/
只能汉字: /^[\u4e00-\u9fa5]{0,}$/
电话号码: ("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):/^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$/
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间):/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$/
强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-10之间):/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$/
还在补充中ing…