Vue打印錯誤日志問題
Vue3全局方法和靜態(tài)配置文件的最佳實踐
Vue3中打印錯誤日志的最佳實踐: 推薦引入全局自定義方法clog,任何地方打印任何類型
在Vue3.0中全局的方法一般有下面兩個
- 方式一 使用 app.config.globalProperties
- 方式二 通過依賴和注入(provide 和 inject)來完成
但是這兩種方法使用起來都非常的不方便
推薦如下方案
Vue3全局方法最佳方案
1.添加一個工具類,例如utils.ts
import moment from "moment"; // 判斷對象,數(shù)組,字符串是否為空,例如: undefined , null , '' , ' ' , {} , [] 全部判斷為空 export function isNull(obj: any): boolean { if (obj === null || obj === undefined) { return true } if (typeof obj === 'object') { let json = JSON.stringify(obj) if (json === '{}') { return true } if (json === '[]') { return true } return false } let str = String(obj) if (str === 'undefined' || str === 'null' || str === '' || !str || !/[^\s]/.test(str)) { return true } return false } // 控制臺日志,支持傳一個參數(shù)(對象/字符串), 也支持傳兩個參數(shù)(標(biāo)志,日志消息<可以是對象,可以是字符串>) export function clog(flag, value: any = 'xxxxxxxxxxxxxxxxxxx=Default-value_override+xxxxxxxxxxxxxxxxx'): string { try { let tmp = "" // 如果value為默認(rèn)值,則沒有傳遞第二個參數(shù),只處理第一個參數(shù) if (value === `xxxxxxxxxxxxxxxxxxx=Default-value_override+xxxxxxxxxxxxxxxxx`) { tmp = JSON.stringify(flag); console.log(tmp) } else if (isNull(value)) { tmp = JSON.stringify(flag); console.log(tmp + ":") } else if (isNull(flag)) { tmp = JSON.stringify(value); console.log(":" + tmp) } else { tmp = JSON.stringify(value); console.log(flag + ":" + tmp) } return tmp } catch (err) { console.log("log", err) return " 空對象或者空字符串 " } } // 日期格式化 export function dateFormatter(str, isDate = false) { if (isNull(str)) return undefined if (isDate === true) { return moment(str).format( 'YYYY-MM-DD' ) } else { return moment(str).format( 'YYYY-MM-DD HH:mm:ss' ) } } //把日期字符串轉(zhuǎn)換為純數(shù)字,例如20191231235959 export function dateFormatterNumber(str, hasTime = true, hasSecond = true): string { let d = new Date(str); if (isNull(str)) { let d = new Date(); } let year = d.getFullYear(); let month = (d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1); let day = d.getDate() < 10 ? '0' + d.getDate() : d.getDate(); if (hasTime) { let hour = d.getHours() < 10 ? '0' + d.getHours() : d.getHours(); let minute = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes(); let second = d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds(); console.log(year, month, day, year + "" + month + "" + day + "" + hour + "" + minute + "" + (hasSecond === true ? second : "")) return year + "" + month + "" + day + "" + hour + "" + minute + "" + (hasSecond === true ? second : ""); } else { return year + "" + month + "" + day; } } //表單校驗 export async function validate(ref: any) { if (ref == null) { return true } let isValidate = true await ref.validate((valid, fields) => { if (valid) { } else { isValidate = false console.log('validate false!', fields) } }) return isValidate } // 節(jié)流 export function throttle(this: any, fn: Function, interval = 500) { let last = 0; return (...args) => { let now = +new Date(); // 還沒到時間 if (now - last < interval) return; last = now; fn.apply(this, args); }; } export function html2Escape(sHtml: string) { const dict = { '<': '<', '>': '>', '&': '&', '"': '"' }; return sHtml.replace(/[<>&"]/g, (c: string) => { return dict[c]; }); } //防抖動 let timestamp, timeout export function debounce(func, wait, immediate) { let args, context, result const later = () => { // 距離上一次觸發(fā)的時間間隔 const last = (timestamp === undefined ? 0 : +new Date() - timestamp) // 上次被包裝函數(shù)被調(diào)用時間間隔last小于設(shè)定時間間隔wait if (last < wait && last > 0) { //是否等待時間間隔達(dá)到后調(diào)用防抖 加上條件判斷防止時間間隔內(nèi)連續(xù)觸發(fā)多個定時任務(wù) if (timeout == null) timeout = setTimeout(later, wait - last) } else { timeout = null // 如果設(shè)定為immediate===true,因為開始邊界已經(jīng)調(diào)用過了此處無需調(diào)用 if (!immediate) { timestamp = +new Date() result = func.apply(context, args) if (!timeout) context = args = null } } } return later() } /** * 對象數(shù)組深拷貝 * @param {Array,Object} source 需要深拷貝的對象數(shù)組 * @param {Array} noClone 不需要深拷貝的屬性集合 */ export function deepClone(source: any, noClone: string[] = []): any { if (!source && typeof source !== 'object') { throw new Error('error arguments deepClone') } const targetObj: any = source.constructor === Array ? [] : {} Object.keys(source).forEach((keys: string) => { if (source[keys] && typeof source[keys] === 'object' && noClone.indexOf(keys) === -1) { targetObj[keys] = deepClone(source[keys], noClone) } else { targetObj[keys] = source[keys] } }) return targetObj }
2.這么用
import { clog, isNull } from '@/utils' clog(jsonObj)
Vue3引入靜態(tài)配置文件最佳方案
1. 在public目錄下面添加一個配置文件config.js
2. 在html.index文件中引入此文件
3. 在vue文件中直接訪問就行
config.js
const config = { BaseApiUrl: 'http://localhost:44311/', Version: '2.0.20220506', }
html.index
<!DOCTYPE html> <html lang="zh-cn"> <head> <title>Vue3Vite</title> <script type="text/javascript" src="tools.js"></script> <script type="text/javascript" src="config.js"></script> </head> <body> <div id="app"></div> <script type="module" src="/src/main.js"></script> </body> </html>
使用舉例
import axios from 'axios' // 創(chuàng)建axios對象,設(shè)置baseURL const service = axios.create({ baseURL: config.BaseApiUrl + '/', // 直接訪問config對象即可 timeout: 30000, }) export default service
Vue3全局方法方案二
1.先吧全局方法寫到tools.js文件中
tools.js
//動態(tài)創(chuàng)建vue對象 const mountPrintData = function (printData, vhtmlDivId = 'print') { clog('mountPrintData') clog(printData) const App = { data() { return { data: printData, } }, } const app = Vue.createApp(App) app.mount('#' + vhtmlDivId) } // 控制臺日志,支持傳一個參數(shù)(對象/字符串), 也支持傳兩個參數(shù)(標(biāo)志,日志消息<可以是對象,可以是字符串>) const clog = function (flag, value = 'xxxxxxxxxxxxxxxxxxx=Default-value_override+xxxxxxxxxxxxxxxxx') { try { let tmp = '' // 如果value為默認(rèn)值,則沒有傳遞第二個參數(shù),只處理第一個參數(shù) if (value === `xxxxxxxxxxxxxxxxxxx=Default-value_override+xxxxxxxxxxxxxxxxx`) { tmp = JSON.stringify(flag) console.log(tmp) } else if (isNull(value)) { tmp = JSON.stringify(flag) console.log(tmp + ':') } else if (isNull(flag)) { tmp = JSON.stringify(value) console.log(':' + tmp) } else { tmp = JSON.stringify(value) console.log(flag + ':' + tmp) } return tmp } catch (err) { console.log('log', err) return ' 空對象或者空字符串 ' } } // 判斷對象,數(shù)組,字符串是否為空,例如: 'undefined' , 'null' , '' , ' ' , {} , [] 全部判斷為空 const isNull = function (obj) { if (typeof obj === 'object') { let json = JSON.stringify(obj) if (json === '{}') { return true } if (json === '[]') { return true } return false } let str = String(obj) if (str === 'undefined' || str === 'null' || str === '' || !str || !/[^\s]/.test(str)) { return true } return false }
2.在Index.html中引入
按如下引入后tools.js中的方法就可以在任何位置直接使用了
<script type="text/javascript" src="tools.js"></script>
3.在ts,js代碼中直接使用
<template> ... </template> <script lang="ts"> export default { setup() { clog(`test`) //直接使用 } } </script>
Vue2中打印日志的最佳實踐
在vue的單頁面應(yīng)用中建議在public目錄添加如下的tools.js全局js靜態(tài)方法
在index.html中這樣引用:
<script type="text/javascript" src="tools.js"></script>
如此,在任何地方打印控制臺日志就可以這么寫: clog(xxx) xxx可以是字符串,也可以是對象。
PS: 打印json對象簡單的方法: console.log(JSON.stringify(jsonObj))
tools.js
//判斷對象,數(shù)組,字符串等是否為空 function isNull(obj){ let str = String(obj) if (str === 'undefined' || str === 'null' || str === '' || !str || !/[^\s]/.test(str)) { return true } if (typeof obj === 'object') { let json = JSON.stringify(obj) if (json === '{}') { return true } if (json === '[]') { return true } return false } else { return false } } // 控制臺日志,支持傳一個參數(shù)(對象/字符串), 也支持傳兩個參數(shù)(標(biāo)志,日志消息<可以是對象,可以是字符串>) function clog(flag, value= 'xxxxxxxxxxxxxxxxxxx=Default-value_override+xxxxxxxxxxxxxxxxx') { try { // 如果value為默認(rèn)值,則沒有傳遞第二個參數(shù),只處理第一個參數(shù) if (value === `xxxxxxxxxxxxxxxxxxx=Default-value_override+xxxxxxxxxxxxxxxxx`) { let tmp = JSON.stringify(flag); console.log(tmp) } else if (isNull(value)) { let tmp = JSON.stringify(flag); console.log(tmp + ":") } else if (isNull(flag)) { let tmp = JSON.stringify(value); console.log(":" + tmp) } else { let tmp = JSON.stringify(value); console.log(flag + ":" + tmp) } } catch (err) { console.log("log", err) } } //深拷貝對象 function copySelf(obj) { var newobj = obj.constructor === Array ? [] : {}; if (typeof obj !== "object") { return; } for (var i in obj) { newobj[i] = typeof obj[i] === "object" ? copySelf(obj[i]) : obj[i]; } return newobj; } //批量導(dǎo)入局部組件 (批量導(dǎo)入全局組件參見vue官網(wǎng)) //使用方法 components: importComponents(require.context('./', false, /Yi.*\.vue$/)), // 導(dǎo)入當(dāng)前目錄以"Yi" 開頭,以".vue"結(jié)尾的全部組件 //require.context('./components', false, /Yi.*\.vue$/) : webpack的方法, 第一個參數(shù)為文件路徑, 第二個參數(shù)為是否包含子文件夾, 第三個參數(shù)為正則 function importComponents(comps) { let res_components = {} comps.keys().forEach((fileName) => { let comp = comps(fileName) res_components[fileName.replace(/^\.\/(.*)\.\w+$/, '$1')] = comp.default }) return res_components } //獲取當(dāng)前時間, 出參為格式化后的日期字符串 function timeNow() { var time = new Date(); // 程序計時的月從0開始取值后+1 var m = time.getMonth() + 1; var t = time.getFullYear() + "-" + m + "-" + time.getDate() + " " + time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds(); return t; } //一天的開始, 入?yún)镈ate類型, 出參為格式化后的日期字符串 function timeDayBegin(time) { var m = time.getMonth() + 1; var t = time.getFullYear() + "-" + m + "-" + time.getDate() + " 00:00:00"; return t; } //一天的結(jié)束, 入?yún)镈ate類型, 出參為格式化后的日期字符串 function timeDayEnd(time) { var m = time.getMonth() + 1; var t = time.getFullYear() + "-" + m + "-" + time.getDate() + " 23:59:59"; return t; } //字符串?dāng)?shù)組轉(zhuǎn)整型數(shù)字鍵 function strArr2IntArr(arrStr) { for (var i = 0; i < arrStr.length; i++) { arrStr[i] = parseFloat(arrStr[i]) } return arrStr; }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3路由組件內(nèi)的路由守衛(wèi)onBeforeRouteLeave和onBeforeRouteUpdate使用
這篇文章主要介紹了Vue3路由組件內(nèi)的路由守衛(wèi)onBeforeRouteLeave和onBeforeRouteUpdate使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05Nuxt pages下不同的頁面對應(yīng)layout下的頁面布局操作
這篇文章主要介紹了Nuxt pages下不同的頁面對應(yīng)layout下的頁面布局操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11element-ui中el-row中設(shè)置:gutter間隔不生效問題
這篇文章主要介紹了element-ui中el-row中設(shè)置:gutter間隔不生效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08詳解如何解決vue開發(fā)請求數(shù)據(jù)跨域的問題(基于瀏覽器的配置解決)
這篇文章主要介紹了詳解如何解決vue開發(fā)請求數(shù)據(jù)跨域的問題(基于瀏覽器的配置解決),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-11-11