小程序debug更加方便
众所周知,小程序的调试工具是不支持vue devtool 的,我们有的时候想要调试一个响应式变量都需要通过事件或者把vm引用到全局变量上
这样做有些繁琐,所以经过我长时间的摸索总结出以下的方案用于微信小程序的调试
- 我们使用vue devtool 的时候如果选择了一个组件默认的情况下会把当前实例的引用添加到全局上面,默认的名称为
$vm
+数字 - 本着这种目的我写了一个vue全局混入来吧页面级别的组件添加到全局上
- 我还编写了一个可以通过组件名称搜索的全局函数
searchComponentByName
暴露在全局上面方便查找组件 - vue和vuex事件控制台输出
// debugMiddleware.js
const exportFn = process.env.NODE_ENV === 'development' ? function(Vue) {
if (process.env.NODE_ENV === 'development') {
// 挂载对象,如果parent对象存在就使用parent(window),不然就是用 Object
const mountObj = typeof parent === 'object' ? parent : Object
// 广度优先遍历搜索组件
// eslint-disable-next-line no-inner-declarations
function searchComponentByName(root, keyword) {
// 第一个参数不是对象,那么就是直接通过根元素进行搜索
if (typeof root !== 'object') {
keyword = root
root = mountObj.$vmRoot
}
// keyword 支持字符串或者正则表达式
if (typeof keyword === 'string') {
keyword = keyword.toUpperCase()
}
if (!root || !root.$children || root.$children.length === 0) {
return null
}
const stack = [root]
let current
// eslint-disable-next-line no-cond-assign
while (current = stack.shift()) {
if (current.$options && current.$options.name && current.$options.name.toUpperCase().match(keyword)) {
return current
}
if (current.$children && current.$children.length !== 0) {
stack.push(...current.$children)
}
}
}
// 在全局暴露一个通过组件名称搜索的函数
mountObj.searchComponentByName = searchComponentByName
// // 函数劫持,劫持 uni.$emit 用于控制台打印
const oldUniEmit = uni.$emit
// uni.$emit 依赖于vue事件流,uni.$emit属于全局事件
let isEmitGlobal = false
uni.$emit = function(eventName, param) {
isEmitGlobal = true
return oldUniEmit.apply(uni, arguments)
}
const oldVueEmmit = Vue.prototype.$emit
Vue.prototype.$emit = function(event, args) {
console.info(`%c ${isEmitGlobal ? 'global' : 'Vue'}.$emit `, `background-color: #41b883;color: #fff`, `${event}`, args, this)
isEmitGlobal = false
return oldVueEmmit.apply(this, arguments)
}
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
this.$options.store.subscribe((mutation, state) => {
console.info(`%c Vux.mutation `, `background-color: #41b883;color: #fff`, `${mutation.type}`, mutation.payload)
})
this.$options.store.subscribeAction((action, state) => {
console.info(`%c Vuex.action `, `background-color: #41b883;color: #fff`, `${action.type}`, action.payload)
})
}
},
created() {
if (process.env.NODE_ENV === 'development') {
// 如果当前组件类型是页面就把this挂载
if (this.mpType === 'page') {
mountObj.__count = mountObj.__count ? mountObj.__count++ : 1
const count = mountObj.__count
mountObj['$vm' + count] = this
// 把root挂载到全局
mountObj.$vmRoot = this.$root
}
}
},
beforeDestroy() {
if (process.env.NODE_ENV === 'development') {
if (this.mpType === 'page') {
if (mountObj.__count) {
mountObj.__count--
}
}
}
}
})
}
} : null
export default exportFn
// main.js
// 如果测试环境就给所有组件添加debugMiddleware
if (process.env.NODE_ENV === 'development') {
Vue.use(debugMiddleware)
}
这样我们就可以在小程序控制台通过 $vm1 获取到当前页面的引用
0 个评论
要回复文章请先登录或注册