注册

Console党福音!封装 console.log 再也不用打注释了!

背景


大家好~, 我是刚入职场不久的前端小帅,每周分享我的一丢丢想法,希望能够帮助到大家~


众所周知,console在项目开发调试中是不可或缺的,在日常工作中经常会使用到它,但使用多了之后会发现,虽然它足够短小精炼,但耐不住用的多,再加上注释指示,工作量隐约还是不小的(懒惰,因此我对它进行小小的封装,让它用起来更短更方便,分享给大家,希望能够对大家开发有所帮助


优势



  • 面向 Vue2
  • 拒绝通用的注释打印
  • 针对对象值自动序列化
  • 支持一行输出 N个变量打印
  • 支持输出data变量和局部变量
  • 支持限制特定页面输出变量
  • 更短的函数名

示例:


data() {
return {
joker: 'jym',
handsomeMan: 'me',
info: {
job: {
name: '专业炒粉'
}
}
}
},
methods: {
getJoker() {
const demo = 'test'
this.$c('joker', 'handsomeMan', 'info', 'info.job.name', { demo }) //输出语句
}
}

输出结果:

image.png


**是的,只需要一行代码!!! **


是的,只需要一行代码!!!


(如果是原来的console.log打印 光想就已经累了......)


封装


接下来看看是如何封装的吧~


方法名再短点!


// main.js
Vue.prototype.$c = function() {...}

因为要全局使用,因此直接挂载到 Vue 的原型对象上,这样各个组件里都能通过this.$c()进行调用


传参与打印



如何访问对应Vue实例的数据



因为我们需要访问this.xxx, 获取到this指向必不可缺,因此结合this的小知识,封装的函数必须是普通函数而不是箭头函数,这样在vue实例中调用时this.$cthis会指向Vue实例自身,我们就可以访问this下的数据啦~



传参



参数肯定需要支持多个,数组冗余了 ,直接扁平化输入

再结合Vue里是通过this.xxx获取数据,可知我们传入的需要是字符串

可得步骤



  • 传入多个待打印的变量名
  • 遍历每个变量名
  • 通过 this变量名 获取到data里的值
  • 判断是否为对象,分别处理
  • 打印
  • over

// main.js
Vue.prototype.$c = function(...words) {
words.forEach(word => {
const val = this[word]
if (Object.prototype.toString.call(val).slice(8, -1) === 'Object') {
console.log(`${word} ======> `)
console.log(JSON.stringify(val, null, 2))
return
}
console.log(`${word} ======> `, val)
return
})
}

对于对象类型的变量,通常我们需要获取实时的对象,直接console.log(obj), 但这样获取的obj通常不是准确的值,想要获取实时的值则需要调用console.log(JSON.stringify(obj, null, 2))通过json字符串化打印实时的值



什么?JSON.stringify后面两个参数是干嘛的?



我TM直接就是一个


参数一 接收 函数或数组,用来转换过滤对象

参数二 接收 数字或字符串,用于指定缩进的空格数或缩进字符串


示例:


const obj = {
name: 'mach',
age: 24,
sex: 1
}
console.log(JSON.stringify(obj, ['name', 'age']))
// {"name":"mach","age":24}

console.log(JSON.stringify(obj, ['name', 'age'], 2))
// {
// "name": "mach",
// "age": 24
// }

OK, 这个时候我们进行打印测试一下


//xxx.vue
data() {
return {
name: 1,
age: 2,
obj: {
name: 'mach',
age: 24,
sex: 1
}
}
},
created() {
this.$c('name', 'age', 'obj')
}

image.png


这时候看看效果,注释有了!变量的值也有了!


局部变量


现在能够访问Vue实例的值了,那少不了局部变量。

问题来了,访问Vue实例是应用了this指向,那局部变量该怎么获取到呢?


最核心的肯定获取是局部变量的执行上下文


呃呃呃呃呃 闭包? eval 试了一下貌似都不行


呃呃呃 , 有了,就是你了!


// xxx.vue
methods:{
getList() {
const joker = 'you'
}
}
this.$c({ 'joker': joker })

高端的食材,往往只需要最朴素的烹饪方式~

忙碌了两小时之后,小师傅开始传入对象


直接用对象传变量名和变量值!


// 简写
this.$c({ joker })

瞧瞧 { joker } 同样很短小,非常适合开发,美吱吱~~


于是函数长这样,对局部变量和Vue data里的变量做区分:



  • 判断 对象 则是局部变量
  • 判断 字符串 则是vue实例数据

Vue.prototype.$c = function(...words) {
words.forEach(word => {
if (typeof word === 'string') {
const val = this[word]
if (Object.prototype.toString.call(val).slice(8, -1) === 'Object') {
console.log(`${word} ======> `)
console.log(JSON.stringify(val, null, 2))
return
}
console.log(`${word} ======> `, val)
return
}
const [name, value] = Object.entries(word)[0]
if (Object.prototype.toString.call(value).slice(8, -1) === 'Object') {
console.log(`${name} ======> `)
console.log(JSON.stringify(value, null, 2))
return
}
console.log(`${name} ======> `, value)
})
}

使用


// xxx.vue
methods:{
getList() {
const joker = 'you'
this.$c('name', 'age', 'obj', { joker })
}
}

image.png


Perfect ~


指明位置及套个漂亮显眼的框


对了,因为$c的函数是定义在main.js里的,因此控制台打印会显示是出现在main.js


image.png


解决办法就是在壳里加个 this.$options.name,指明调试语句来自哪个组件

再给打印区套个漂亮的壳,便于做区分


Vue.prototype.$c = function(...words) {
console.log(`来自${this.$options.name}-🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉`) // 新增
words.forEach(word => {
if (typeof word === 'string') {
const val = this[word]
if (Object.prototype.toString.call(val).slice(8, -1) === 'Object') {
console.log(`${word} ======> `)
console.log(JSON.stringify(val, null, 2))
return
}
console.log(`${word} ======> `, val)
return
}
const [name, value] = Object.entries(word)[0]
if (Object.prototype.toString.call(value).slice(8, -1) === 'Object') {
console.log(`${name} ======> `)
console.log(JSON.stringify(value, null, 2))
return
}
console.log(`${name} ======> `, value)
})
console.log('🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉')
}

测试打印结果:


image.png


圆满结束啦


访问嵌套属性的值


还有嘞 ~ 有人问,刚刚只是访问变量第一层,如果只想访问变量的第n层怎么办?


很简单,核心就是嵌套调用~


const val = this[word]

改成


const val = word.split('.').reduce((pre, cur) => {
return pre[cur]
}, this)

这个时候通过 xxx.xxxx.xx 就可以访问Vue实例下数据的值啦~


data(){
return {
obj: {
name: 'joker'
age: 24
}
}
}
this.$c('obj.age', 'obj.name')

image.png

这里xxx.xxxx.xxxxx|xxxx|xxxxx-xxxx-xx没啥区别,就是做分割罢了,但用.好分辨点贴近开发


解决完Vue实例下数据的嵌套访问,这时候有人会问,访问局部变量的嵌套属性咋办


Emmm 好问题 , 转动我的机灵小脑袋~~~~~ 有了!!!


const obj = {
accont: {
xx: {
id: 11,
name: 'rich'
},
money: 10086
}
}
const xx = obj.accont.xx // 新增

// 调用
this.$c({xx})

高端的食材,往往只需要最朴素的烹饪方式 ~


const joker = {
info: {
name: 'jym',
age: 18,
height: 185
}
}
const name = joker.info.name
this.$c({ joker }, { name })

image.png


这样纸代码看起来也清晰嘛~ 嗯,针不戳


限制特定页面输出变量


假设我现在只需要path1path2的页面输出变量,关闭其他页面的输出,咋做嘞~


简简单单,咱已经拿到指向Vue实例的this,可以直接访问当前路由地址和名做一下限制即可


在函数开头加上


Vue.prototype.$c = function(...words) {
const whitelist = ['path1', 'path2']
const currentPath = this.$route.path

if (!whitelist.includes(currentPath)) return
......
}

现在就只有path1, path2的页面下的组件可以输出啦,是不是很方便呢?


只有 Vue2 可以这么封装吗?


虽然这个封装的代码是面向 Vue2, 但很显然封装的核心对于Vue是通用的,把this换成组件实例即可,如Vue3里是this(选项式) 或者 getCurrentInstance()(组合式),至于React,就只能朴素一丢丢喏(你懂得)


代码 没写 我就不贴了


集帅们 也可以把代码打在评论区,供参考借鉴~~


总结


全部代码:


Vue.prototype.$c = function(...words) {
const whitelist = ['path1', 'path2']
const currentPath = this.$route.path
if (!whitelist.includes(currentPath)) return

console.log(`🎉🎉🎉🎉🎉🎉🎉🎉来自-${this.$options.name}-🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉`)
words.forEach(word => {
if (typeof word === 'string') {
const val = word.split('.').reduce((pre, cur) => {
return pre[cur]
}, this)
if (Object.prototype.toString.call(val).slice(8, -1) === 'Object') {
console.log(`${word} ======> `)
console.log(JSON.stringify(val, null, 2))
return
}
console.log(`${word} ======> `, val)
return
}
const [name, value] = Object.entries(word)[0]
if (Object.prototype.toString.call(value).slice(8, -1) === 'Object') {
console.log(`${name} ======> `)
console.log(JSON.stringify(value, null, 2))
return
}
console.log(`${name} ======> `, value)
})
console.log('🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉')
console.log('')
}

优势



  • 无需通用的注释打印
  • 支持限制特定页面输出变量
  • 针对对象值自动序列化
  • 支持一行输出 N个变量打印
  • 支持打印data变量和局部变量
  • 更短的函数名

总的来说,这个封装主要是我在项目console烦了,特别是加上注释和对象json序列化,于是这几天蚌埠住了,整了这个封装,总的来说我觉得效果是不错滴,一行顶之前 N 行, 不用加注释,也不需要该死的 JSON.stringify(xx, null, 2)


但是特殊打印就回归正常 console.log 哦, 没必要封装太深入


希望能够帮助到那些和我一样的console党~ (wink), 觉得有帮助可以点赞关注一下我喔~~~


往期奇思妙想:


《这个前端Api管理方案会更好?》

《这个前端Api管理方案会更好?(二)》


作者:爱吃好果汁丶
来源:juejin.cn/post/7300122001768071168

0 个评论

要回复文章请先登录注册