背景
大家好~, 我是刚入职场不久的前端小帅,每周分享我的一丢丢想法,希望能够帮助到大家~
众所周知,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 })
}
}
输出结果:
**是的,只需要一行代码!!! **
是的,只需要一行代码!!!
(如果是原来的console.log
打印 光想就已经累了......)
封装
接下来看看是如何封装的吧~
方法名再短点!
Vue.prototype.$c = function() {...}
因为要全局使用,因此直接挂载到 Vue
的原型对象上,这样各个组件里都能通过this.$c()
进行调用
传参与打印
如何访问对应Vue实例的数据
因为我们需要访问this.xxx
, 获取到this
指向必不可缺,因此结合this
的小知识,封装的函数必须是普通函数而不是箭头函数,这样在vue
实例中调用时this.$c
时this
会指向Vue
实例自身,我们就可以访问this
下的数据啦~
传参
参数肯定需要支持多个,数组冗余了 ,直接扁平化输入
再结合Vue
里是通过this.xxx
获取数据,可知我们传入的需要是字符串
可得步骤
- 传入多个待打印的变量名
- 遍历每个变量名
- 通过
this
和 变量名
获取到data
里的值
- 判断是否为对象,分别处理
- 打印
- over
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']))
console.log(JSON.stringify(obj, ['name', 'age'], 2))
OK, 这个时候我们进行打印测试一下
data() {
return {
name: 1,
age: 2,
obj: {
name: 'mach',
age: 24,
sex: 1
}
}
},
created() {
this.$c('name', 'age', 'obj')
}
这时候看看效果,注释有了!变量的值也有了!
局部变量
现在能够访问Vue
实例的值了,那少不了局部变量。
问题来了,访问Vue
实例是应用了this指向
,那局部变量该怎么获取到呢?
最核心的肯定获取是局部变量的执行上下文
呃呃呃呃呃 闭包? eval
? 试了一下貌似都不行
呃呃呃 , 有了,就是你了!
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)
})
}
使用
methods:{
getList() {
const joker = 'you'
this.$c('name', 'age', 'obj', { joker })
}
}
Perfect ~
指明位置及套个漂亮显眼的框
对了,因为$c的函数是定义在main.js
里的,因此控制台打印会显示是出现在main.js
里
解决办法就是在壳里加个 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('🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉')
}
测试打印结果:
圆满结束啦
访问嵌套属性的值
还有嘞 ~ 有人问,刚刚只是访问变量第一层,如果只想访问变量的第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')
这里xxx.xxxx.xx
和xxx|xxxx|xx
和xxx-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 })
这样纸代码看起来也清晰嘛~ 嗯,针不戳
限制特定页面输出变量
假设我现在只需要path1
和path2
的页面输出变量,关闭其他页面的输出,咋做嘞~
简简单单,咱已经拿到指向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