开发了一个钉钉内置WebApp,对于钉钉的header操作API非常不满,IOS和安卓下表现不一致,操作困难,API文档写的不详细等等。
这里自己尝试实现一遍这个头部,方便以后使用。
需求:
① header不参与各组件和路由跳转
② header分成左侧返回箭头、中间title和右侧操作区域3部分
③ 左侧箭头可控制是否显示和返回路由URL设置;title使用router设置meta.title;右侧操作要求可以设置文本和各页面点击响应不同事件。
实现:
① 首先肯定是写个头部组件啦,废话不说,源码如下:
// headerMenu.vue
② 然后把上面的头部组件(header-menu)放在App.vue中router-view上方:
// App.vue
③ 然后是实现header-menu组件和各个子组件之间的通讯问题,这里本人通过挂载在根vue实例下的一个事物总线实现:
// main.js
import Vue from 'vue'
import '@/permission' // 引入全局导航守卫
Vue.prototype.$newVue = new Vue()
// xxx.vue文件使用这个公共头部:
beforeRouteEnter(to, from, next) {
next(vm => {
vm.$newVue.$emit('header-setting', {
needBack: false
})
})
}
至于这里为什么要放到beforeRouteEnter这个钩子,因为放到了mounted钩子,前进后退无法触发。
到这里看起来全局头部就完工了,然而实测过程中发现还有小坑,例如我在当前路由设置了this.needButton:true,后退时没有设置this.needButton:false,那么右侧的操作区域就会存留前一个路由留下来的缓存事件。每个页面都设置重复的操作就显得很low啦,于是优化一波,在全局导航守卫钩子中来初始化这个头部。
// permission.js
import router from './router'
router.beforeEach((to, from, next) => {
router.app.$newVue.$emit('header-setting', {
needButton: false,
button: {
text: '',
callback: function() {}
}
})
next()
})