实战踩坑
js
audioPlay(event) {
返回目录1. js 页面音频播放
audioPlay(event) {
// console.log('音乐播放', event)
var audios = document.getElementsByTagName('audio')
// 暂停函数
function pauseAll() {
var self = this;
[].forEach.call(audios, function(i) {
// 将audios中其他的audio全部暂停
i !== self && i.pause()
})
}
// **给play事件绑定暂停函数**
[].forEach.call(audios, function(i) {
i.addEventListener('play', pauseAll.bind(i))
})
} videoPlay(event) {
// console.log('视频播放', event)
var videos = document.getElementsByTagName('video')
// 暂停函数
function pauseAll() {
var self = this
;[].forEach.call(videos, function(i) {
// 将audios中其他的audio全部暂停
i !== self && i.pause()
})
}
// 给play事件绑定暂停函数
[].forEach.call(videos, function(i) {
i.addEventListener('play', pauseAll.bind(i))
})
}2. js 图片转 base64,base64 转文件
//将图片转换为Base64
function getImgToBase64(url, callback) {
var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d"),
img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function () {
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
callback(dataURL);
canvas = null;
};
img.src = url;
}
//将base64转换为文件
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
//可以将图片转换为base64
getImgToBase64("img/test.png", function (data) {
var myFile = dataURLtoFile(data, "testimgtestimgtestimg");
console.log(myFile);
});3. js 文本框监听粘贴事件,获取粘贴板上的图片数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="myInput" />
<script>
document.getElementById('myInput').addEventListener('paste',function(e){
if ( !(e.clipboardData && e.clipboardData.items) ) {
return;
}
for (var i = 0, len = e.clipboardData.items.length; i < len; i++) {
var item = e.clipboardData.items[i];
if (item.kind === "string") {
item.getAsString(function (str) {
console.log(str);
})
} else if (item.kind === "file") {
var f= item.getAsFile();
console.log(f);
}
}
});
</script>
</body>
</html>4. js reduce() 拆分数组
const arr = [
{ id: 1, name: 1, pinyin: "A" },
{ id: 2, name: 2, pinyin: "B" },
{ id: 3, name: 3, pinyin: "B" },
{ id: 4, name: 4, pinyin: "C" },
{ id: 5, name: 5, pinyin: "C" },
{ id: 6, name: 6, pinyin: "C" },
{ id: 7, name: 7, pinyin: "D" },
{ id: 8, name: 8, pinyin: "D" },
{ id: 9, name: 9, pinyin: "D" },
];- 获取索引值
// 动态获取索引列表
getIndexList(arr) {
// 1. 排序
var mySort = arr.sort()
// var mySort = arr.sort(this.sortBy('pinyin', true))
// 2. 过滤
mySort = mySort.map((item, index) => {
return item.pinyin
})
console.log('mySort',mySort) // ['A','B',‘B’,'C','C','C','D','D','D']
// 3. 去重
const mySet = Array.from(new Set(mySort))
return mySet // ['A','B','C','D']- 按索引拆分数组
getCellList(arr) {
// 1. 排序
arr = arr.sort()
const result = arr.reduce(function(initArray, item) {
const p = item.pinyin
if (initArray[p]) {
initArray[p].push(item)
} else {
initArray[p] = [item]
}
return initArray
}, [])
// // console.log('getCellList', result)
return result
},- 根据对象的 key 提取 value 拼成新数组
const temp = this.getCellList(arr);
this.friendList = Object.keys(temp).map((item) => temp[item]);- reduce 语法
arr.reduce(function(prev,cur,index,arr){
...
}, init);arr 表示原数组;
prev 表示上一次调用回调时的返回值,或者初始值 init;
cur 表示当前正在处理的数组元素;
index 表示当前正在处理的数组元素的索引,若提供 init 值,则索引为 0,否则索引为 1;
init 表示初始值。
原理
① 初始化一个空数组
② 将需要去重处理的数组中的第 1 项在初始化数组中查找,如果找不到(空数组中肯定找不到),就将该项添加到初始化数组中
③ 将需要去重处理的数组中的第 2 项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中
④ ……
⑤ 将需要去重处理的数组中的第 n 项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中
⑥ 将这个初始化数组返回
5. js 获取输入框输入前后的值
使用场景:比较输入框前后的值是否相等,判断是否需要执行对应的方法
- @focus 方法把点击输入框时的初始值保存下来
- @change 方法把输入后的 value 值传出
- 在 element UI 中 @change 是 blur 或点击回车才执行的,可以用
@blur替换
上代码
<el-input
v-model.trim="remark"
placeholder="请输入备注"
@focus="setDefault(remark)"
@change="changeRemark($event,id)"
/>6. js 一次性渲染大量数据解决方案
refresh(total, onceCount, arrval) {
console.log('总数,每次渲染条数', total, onceCount)
// total -> 渲染数据总数 onceCount -> 一次渲染条数
let count = 0 // 初始渲染次数值
const loopCount = total / onceCount // 渲染次数
//------------<
const that = this
let once = []
let cell = []
let show = []
//------------>
function refreshAnimation() {
/*
* 在此处渲染数据
*/
//------------<
once = arrval.slice(count * onceCount, (count + 1) * onceCount)
// (count * onceCount, onceCount)
// console.log(`渲染${count}`, once)
cell = that.getCellList(once)
show = Object.keys(cell).map(item => cell[item])
// console.log(`渲染${count}`, show)
show.forEach(e => {
that.friendList.push(e)
})
// that.friendList = that.friendList.concat(show)
// console.log(`friends${count}`, that.friendList)
//------------>
if (count < loopCount) {
count++
window.requestAnimationFrame(refreshAnimation)
}
}
window.requestAnimationFrame(refreshAnimation)
},
//调用
refresh(arr.length,5,arr)7. js 获取图片宽高等信息
// 获取图片宽高
getImgInfo(url) {
return new Promise((resolve, reject) => {
const img = new Image()
img.src = url
img.onload = function() {
const imgInfo = {
width: img.width,
height: img.height
}
resolve(imgInfo)
}
img.onerror = function() {
reject(new Error('图片加载错误!'))
}
})
},8. js 获取视频宽高,时长等信息
// 获取视频的信息
getVideoInfo(url) {
return new Promise((resolve, reject) => {
const video = document.createElement('video')
video.src = url
video.onloadedmetadata = function(e) {
const videoInfo = {
width: video.videoWidth,
height: video.videoHeight,
duration: video.duration
}
resolve(videoInfo)
}
video.onerror = function() {
reject(new Error('图片加载错误!'))
}
})
},9. js 点击播放一个文件关闭其他资源
// play_source : 给需要控制的文件的类名,音频视频都用这个
// 只播放一个音频或视频
playOne() {
var source = document.getElementsByClassName('play_source')
// console.log(source) // 获取所有要控制的音频视频元素
// 暂停函数
function pauseAll() {
var self = this
;[].forEach.call(source, function(i) {
// 将source中其他的source全部暂停
i !== self && i.pause()
})
}
// **给play事件绑定暂停函数**
[].forEach.call(source, function(i) {
i.addEventListener('play', pauseAll.bind(i))
})
}10. js 常用正则匹配
// g-global 全局搜索 i- 忽略大小写搜索 m-多行搜索
// 手机号
// 匹配所有号码(手机卡 + 数据卡 + 上网卡)
const phoneReg=/^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[01356789]\d{2}|4(?:0\d|1[0-2]|9\d))|9[189]\d{2}|6[567]\d{2}|4(?:[14]0\d{3}|[68]\d{4}|[579]\d{2}))\d{6}$/
// 手机号-普通版
var reg = /^(0|86|17951)?(13[0-9]|15[012356789]|18[0-9]|14[57]|17[678])[0-9]{8}$/
// 手机号-简单版
var reg = /^1[34578]\d{9}$/
// qq号
const qqReg=/^[1-9][0-9]{4,9}$/gim
// 身份证
const IdReg = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
// 邮箱
const emailReg=/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/
var reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
// URL
const urlReg = /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i;
// IP
const ipReg = /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/gi;
// 邮政编码
const reg = /^[1-9]\d{5}$/g;
// 检查字符串是否存在中文
const reg = /[\u4e00-\u9fa5]/gm;
// 去除空格
trim(str) {
var reg = /^\s+|\s+$/g;
return str.replace(reg, '');
},
// 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
const reg=/^[a-zA-Z]\w{5,17}$/
// 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间)
const reg=/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$/11. vue.js 输入框限制特殊符号
// 全局声明
Vue.prototype.validForbid = function (value) {
// 限制input不能输入特殊符号
value = value
.replace(
/[`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g,
""
)
.replace(/\s/g, "");
return value;
};// 页面使用 @input="e => uploadWord.title = validForbid(e)"
<el-input
v-model="uploadWord.title"
maxlength="10"
show-word-limit
@input="e => uploadWord.title = validForbid(e)"
/>12. qrcode.js 识别图片二维码
场景: 上传图片前识别图片是否二维码
- npm install --save qrcode-decoder 引入
// npm install --save qrcode-decoder
import QrcodeDecoder from 'qrcode-decoder'
async decodeImg(file) {
// file是通过input或elementUI组件中的upload 上传的二维码图片文件
// 获取预览图片路径方法
var getObjectURL = function(file) {
var url = null
if (window.createObjectURL !== undefined) { // basic
url = window.createObjectURL(file)
} else if (window.URL !== undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file)
} else if (window.webkitURL !== undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file)
}
return url
}
console.log(getObjectURL(file)) // 查看是否成功获取图片路径
var QRCode = new QrcodeDecoder()
const img = await getObjectURL(file)
const isQrcode = await QRCode.decodeFromImage(img).then((res) => {
console.log(' QRCode.decodeFromImage', res.data)
return !!res.data
})
// 这里仅返回ture和false用于判断, 没有返回解析二维码得到的文本
return isQrcode
},13. vue.js 引入第三方 js
methods: {
loadVaptchaScript() {
return new Promise(resolve => {
var script = document.createElement('script')
script.src = '@/utils.qrcode.js'
script.async = true
script.onload = script.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
resolve()
script.onload = script.onreadystatechange = null
}
}
document.getElementsByTagName('head')[0].appendChild(script)
})
},
}
//获取预览图片路径
var getObjectURL = function(file){
var url = null ;
if (window.createObjectURL!=undefined) { // basic
url = window.createObjectURL(file) ;
} else if (window.URL!=undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file) ;
} else if (window.webkitURL!=undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file) ;
}
return url ;
}
console.log(getObjectURL(newfile[0]));// newfile[0]是通过input file上传的二维码图片文件
qrcode.decode(getObjectURL(newfile[0]));
qrcode.callback = function(imgMsg){
console.log("imgMsg",imgMsg);
}14. js 获取今天 0 点和 23 点 59 分 59 秒
// 0点
new Date(new Date(new Date().toLocaleDateString()).getTime());
// 23:59:59
new Date(
new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1
);15. 使用 async/await 替代 promise
// 声明一个方法, 延迟打印输入的时间
function asyncfunc(time) {
return new Promise((reslove, reject) => {
setTimeout(() => {
console.log("setTimeout", time);
reslove(time);
}, time);
});
}
// 1. 使用 promise链式调用执行
asyncfunc(3000).then((time) => {
console.log("done", time); // 3000
})(
// 结果 3秒后输出
// setTimeout 3000
// done 3000
// 2. 使用 async/await执行
async () => {
const time = await asyncfunc(5000);
console.log("done", time);
}
)();
// 结果 5秒后输出
// setTimeout 5000
// done 5000
// async function 调用后返回的 Promise 本身是立即执行的,所以如果你不想管后面发生了什么,也可以直接这样调用。
// Promise.all / Promise.race
const temp = [1000, 2000, 3000, 4000];
(async () => {
const result = await Promise.all(
temp.map((time) => {
return asyncfunc(time);
})
);
console.log("done", result);
})();
// Promise {<pending>}
// init.js:1 setTimeout 1000
// init.js:1 setTimeout 2000
// init.js:1 setTimeout 3000
// init.js:1 setTimeout 4000
// init.js:1 done (4) [1000, 2000, 3000, 4000]- 异常处理
// 上面说到,async function 实际上就是 Promise,而 Promise 并不能通过 try-catch 来捕获异常(事实上我们没有办法捕获异步回调中的的异常), 是通过 reject 调用相应的回调的。而 await 实际上会在被 reject 时 throw 相应的异常:
(async () => {
try {
await Promise.reject("aha");
} catch (e) {
console.log(e);
}
})();
// 会得到 aha。
// 相应的,在 async function 中 throw 也会导致其返回的 Promise reject:
(async () => {
throw "aha";
})().catch((err) => {
console.log(err); // aha
});参考链接: https://zhuanlan.zhihu.com/p/23249103?utm_medium=social&utm_source=weibo
16. js 复制一个数组
//拷贝一个数组(相当于复制并创建一个新的数组,对新数组进行操作bu影响原来的数组)
// 方法一
var arr = [1, 2, 3, 4];
var arr1 = arr.concat();
// 方法二
var arr = [1, 2, 3, 4, 5];
var arr1 = arr.slice(0);
//方法三(ES6中的Rest运算符)
var arr = [1, 2, 3, 4];
var arr1 = [...arr];
//方法四
var arr = [1, 2, 3, 4];
arr1 = Array.from(arr);
//方法五
var arr1 = [],
arr = [1, 2, 3, 4],
len = arr.length;
for (var i = 0; i < len; i++) {
arr1.push(arr[i]);
}
console.log(arr1);
//方法六
var arr = [1, 2, 3, 4];
var arr1 = Object.assign([], arr);
//方法七(for..of..循环)
var arr = [1, 2, 3, 4];
var arr1 = [];
for (var val of arr) {
arr1.push(val);
}
//方法八(for..of..+arr.entries()方法)
var arr = [1, 2, 3, 4];
var arr1 = [];
for (var item of arr.entries()) {
arr1[item[0]] = item[1];
}17. js 区分统计中英文长度
validateTextLength(value) {
//中文、中文标点、全角字符按1长度,英文、英文符号、数字按0.5长度计算
let cnReg = /([\u4e00-\u9fa5]|[\u3000-\u303F]|[\uFF00-\uFF60])/g;
let mat = value.match(cnReg);
let length = 0;
if (mat) {
return (length = mat.length + (value.length - mat.length) * 0.5);
} else {
return (length = value.length * 0.5);
}
}18. js 上传文件进度条
axios({
url,
method: "post",
data,
headers: {},
//原生获取上传进度的事件
onUploadProgress: function (progressEvent) {
let complete =
(((progressEvent.loaded / progressEvent.total) * 100) | 0) + "%";
console.log("上传 " + complete);
},
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});19. js 进制转换
// 10转16并补一个0
ten2hex(num) {
var result = num.toString(16).toUpperCase()
if (result.length < 2) {
result = '0' + result
}
return result
},
// 16转10
hex2ten(hex) {
var ten = parseInt(hex,16);
return ten
}
// string转16
str2hex(str) {
var val = "";
for (var i = 0; i < str.length; i++) {
if (val == "")
val = str.charCodeAt(i).toString(16);
else
val += str.charCodeAt(i).toString(16);
}
return val
},
// 16转string
hex2str(hexCharCodeStr) {
var trimedStr = hexCharCodeStr.trim();
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x"?trimedStr.substr(2):trimedStr;
var len = rawStr.length;
if (len % 2 !== 0) {
// alert("Illegal Format ASCII Code!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16); // ASCII Code Value
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
},
// 16转buffer
hex2ab(hex) {
const buffer = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(h => {
return parseInt(h, 16)
}))
return buffer.buffer
},
// buffer转16
ab2hex(buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},
20. js crc8检验
// crc8校验
encodeCrc8(hex) {
var _crc8 = [
0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35
];
var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function(h) {
return parseInt(h, 16)
}))
var ucLen = typedArray.length;
var ucPtr = typedArray;
var ucCRC8 = 0;
var i = 0;
while (ucLen--) {
ucCRC8 = _crc8[ucCRC8 ^ ucPtr[i]];
i++;
}
return ucCRC8.toString(16).toUpperCase();
},21. js 点击输入框自动全选内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input id="input" value="" />
</body>
<script>
var input = document.getElementById("input");
input.addEventListener("focus", function (e) {
input.select();
});
</script>
</html>22. vue.js 解决打包更新版本,浏览器缓存问题
每次打包更新版本发到服务器上,导致偶尔会出现不能及时更新最新代码,浏览器存在缓存的问题。总不能让每个用户都强制刷新一下或者打开一个无痕窗口吧
vue.config.js(vue cli3.x 生成的项目默认没有这个文件,需要自己创建)
// 时间戳保证不会版本重复
const Timestamp = new Date().getTime();
module.exports = {
....
configureWebpack: { // webpack 配置
output: { // 输出重构 打包编译后的 文件名称 【模块名称.版本号.时间戳】
filename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`,
chunkFilename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`
},
}
...
};
nginx 配置,让 index.html 不缓存。
location = / index.html {
add_header Cache-Control "no-cache, no-store";
}- no-cache, no-store 可以只设置一个
- no-cache 浏览器会缓存,但刷新页面或者重新打开时 会请求服务器,服务器可以响应 304,如果文件有改动就会响应 200
- no-store 浏览器不缓存,刷新页面需要重新下载页面
23. vue.js 实现判断页面是否编辑及编辑页面未保存离开弹窗提示
<script>
export default {
name: 'Form',
props: [],
beforeRouteLeave (to, from, next) {//离开当前页
if(this.updateCount > 1){ //更新次数大于1 说明用户修改过当前页数据 因为获取详情时会更新一次
if(from.path.includes('nowPath')){
this.$confirm('即将离开当前页,请确定是否保存当前数据?', '离开当前页', {
confirmButtonText: '保存',
cancelButtonText: '不保存',
type: 'warning'
}).then(() => {
//...todo 这里调接口 保存数据
next()
}).catch(() => {next()});
}else{next()}
}else{
next()
}
},
data() {
return {
updateCount:0,//判断用户是否更新当前数据
form:{
radio:'',
select:[]
input:''
}
}
},
computed:{},
// 用watch或者用updated都可以,根据实际情况选择
watch:{
form: {
handler (val) {
if (val) {
this.updateCount++
}
},
deep: true
}
},
updated:function () {
this.updateCount = this.updateCount + 1
},
mounted:function () {
this.getInitData()
},
methods: {
getInitData:function(){
//...todo 页面进来,先获取默认数据
}
},
}
</script>