前段时间项目忙到一半,产品忽然说h5页面要加个top-bar(以前说好的混合开发呢)。WFT,项目作到了一半,忽然要加这个; 看了下设计图,大概是这样的javascript
直接在view-router外添加,在路由处配置是否显示该top-bar便可 路由配置css
{ path: 'xxx', name: 'xxx', component: xxx, meta: { title: 'xxxxx', topBar: false } } // topBar 为false则不显示
复制代码
top-bar组件大体以下html
<template>
<div class="top-bar" v-if="$route.meta.topBar !== false">
{{$route.meta.title}}
</div>
</template>
<script>
export default {
name: 'topBar'
}
</script>
<style lang="sass" scoped>
</style>
复制代码
而后在app.vue内引入TopBar组件vue
<template>
<div id="app"> <top-bar></top-bar> <router-view class="container"></router-view> </div> </template> <script> import TopBar from '@/components/common/TopBar' export default { name: 'App', components: { TopBar } } </script> 复制代码
优势java
缺点node
全局注册top-bar组件,在须要的页面调用; index.js内添加
api
import TopBar from '@/components/common/TopBar'
Vue.components(TopBar)
复制代码
页面内,将meta 赋值给当前页面的 page 对象sass
<top-bar>{{page.title}}</top-bar>
复制代码
路由配置不变bash
优势app
缺点
建立一个TopBar的组件构造器,须要extend
,在每次路由跳转的时候,生成一个构造器实例;此方法的难点在于如何在路由跳转的时候,获取TopBar组件的实例;有如下注意点
$mount
方法来获取组件实例;$mount
会在vue内调用compile方法;编译后,咱们即可拿到$el;从而进行手动挂载;关于$mount用法,能够参考官网 点击这里
mixin 以下, topBarMixin.js
import Vue from 'vue'
import '@/style/topBar.scss'
let TopBar = null
let App = null
const getApp = function (vm) {
App = vm.$el
return App
}
const clearTopBar = function () {
if (TopBar) { // 先清掉以前的,防止keep-alive的cache产生多个topbar
const topBarElement = TopBar.$el
const parentNode = topBarElement.parentNode
parentNode.removeChild(topBarElement)
}
}
const compile = function (meta) {
const show = (meta.topBar !== false)
const title = meta.title || ''
if (!show) {
return
}
clearTopBar() // 先清除以前的TopBar
const TopBarComponent = Vue.extend({
data () {
return {
show,
title
}
},
template: ` // 模板 <div class="xsj-top-bar" v-if="show"> <div class="xsj-top-bar-content"> <div class="top-bar-arrow" @click="back"> <icon name="return" class="return"></icon> </div> <div class="top-bar-title">{{title}}</div> </div> </div>`
})
TopBar = new TopBarComponent().$mount() // 挂载获取实例
if (App.nodeType === 1) {
App.insertBefore(TopBar.$el, App.firstChild)
} else {
throw new Error('没法给非元素节点增长topbar')
}
}
export default {
methods: {
_resetTitle (title = TopBar.title) { // 可手动调用修改当前title的内容
this.$nextTick(() => { // 在页面模板挂载上去之后,执行
if (TopBar.show) {
TopBar.title = title
document.title = title
}
})
}
},
beforeRouteEnter (to, from, next) {
const meta = to.meta
next(vm => {
getApp(vm)
compile(meta)
})
}
}
复制代码
index.js 内直接调用Vue.mixin(topBarMixin)
优势
缺点
方法四和方法三实现逻辑差很少,只不过把组件构造器换为组件实例TopBar.vue;
$mount
挂载获取实例TopBar.vue以下
<template>
<div class="top-bar" v-if="bar.topBar !== false">
{{bar.title}}
</div>
</template>
<script>
export default {
name: 'TopBar',
props: {
bar: {
type: Object,
default () {
return {}
}
}
}
}
</script>
复制代码
mixin 以下, topBarMixin.js文件
import Vue from 'vue'
import TopBar from '@/components/common/TopBar' // 引入TopBar组件
let App = null
const getApp = function (vm) {
App = vm.$el
return App
}
export default {
name: 'AddTopBar',
beforeRouteEnter (to, from, next) {
next(vm => {
getApp(vm)
const tb = new Vue(TopBar).$mount() // 挂载获取实例
if (App.nodeType === 1) {
clearTopBar() // 先清掉以前的TopBar,防止keep-alive的cache产生多个topbar
App.insertBefore(tb.$el, App.firstChild)
tb._props.bar = to.meta // 将路由数据传给top-bar
} else {
throw new Error('没法给非元素节点增长topbar')
}
})
}
}
复制代码
入口处调用 Vue.mixin(topBarMixin)
便可
优势
缺点
本文涉及的知识点和细节点仍是蛮多的,本身在整理的时候,也认真的消化吸取了一波;有些小知识点,写起来比较占篇幅,再者比较时间匆忙,笔者在此就一笔带过了。
固然,若是你们有更好的解决方法,欢迎留言,一块儿探讨~