前段時間項目忙到一半,產品忽然說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)
便可
優勢
缺點
本文涉及的知識點和細節點仍是蠻多的,本身在整理的時候,也認真的消化吸取了一波;有些小知識點,寫起來比較佔篇幅,再者比較時間匆忙,筆者在此就一筆帶過了。
固然,若是你們有更好的解決方法,歡迎留言,一塊兒探討~