使用vue做單頁面應(yīng)用的時(shí)候蟋恬,修改title始終是一個(gè)非常重要的問題翁潘。由于單頁面應(yīng)用(SPA項(xiàng)目)里整個(gè)頁面只在第一次完全刷新,后面只會(huì)局部刷新(一般不包括head及里面的title)歼争,微信瀏覽器首次加載頁面初始化title后拜马,就再也不監(jiān)聽 document.title的change事件,所以無法在服務(wù)器端控制title沐绒。
如果不考慮iOS微信瀏覽器中上面使用俩莽,可以用下面的方法:
router.map({
'/auth': {
title: '入口頁面',
component(resolve) {
require(['./views/auth'], resolve);
}
})}
在beforeEach中通過document.title來改變title的值。
router.beforeEach(({ to, from, next }) => {
document.title = to.title || 'title名稱'
})
上面這種方法還是在用vue 1.0的時(shí)候?qū)懙那钦冢梢愿鶕?jù)自己的需要來改成vue 2.0的代碼扮超。
如果要兼容大部分常用的移動(dòng)端,光上面這種寫法是肯定不夠的。
好在通過網(wǎng)上搜索和自己的摸索出刷,找到了兩種解決辦法璧疗,兩種解決辦法都能用,基本上也是通過看網(wǎng)上其他朋友給出的解決方案來優(yōu)化的馁龟,今天抽點(diǎn)時(shí)間把他們整理一下崩侠,以便后面使用,也希望能幫到一些需要的朋友坷檩,代碼中可能會(huì)有一些問題却音,發(fā)現(xiàn)了的朋友還望多多指點(diǎn)。
兩種方法的原理:都是動(dòng)態(tài)給頁面加上一個(gè)內(nèi)容為空的iframe矢炼,隨后立即刪除這個(gè)iframe系瓢,這時(shí)候就會(huì)刷新title。
第一種方法需要注意:由于微信iOS瀏覽器內(nèi)核由UIWebView更新為WKWebView裸删,所以必須版本升級(jí)到微信6.5.5此功能才可以正常使用八拱,WKWebView 是蘋果在iOS 8中引入的新組件,目的是提供一個(gè)現(xiàn)代的支持最新Webkit功能的網(wǎng)頁瀏覽控件涯塔,擺脫過去 UIWebView的老肌稻、舊、笨匕荸,特別是內(nèi)存占用量巨大的問題爹谭。它使用與Safari中一樣的Nitro JavaScript引擎,大大提高了頁面js執(zhí)行速度榛搔。
第二種方法具體來說就是通過動(dòng)態(tài)創(chuàng)建iframe诺凡,設(shè)置相應(yīng)的樣式屬性,并在iframe中增加一張圖片践惑,使其在每次創(chuàng)建的時(shí)候都會(huì)去加載這張圖片腹泌,然后立即刪除這個(gè)iframe,做這個(gè)目的就是為了微信重新去更新相應(yīng)的一些屬性尔觉,然后觸發(fā)document.title的change事件凉袱,將新的title的值替換。
我們把修改title的代碼單獨(dú)寫在一個(gè)utils.js文件侦铜,可以放在你項(xiàng)目的根目錄下专甩,也可以單獨(dú)添加一個(gè)文件夾放,只要知道引用的地址是什么就好钉稍,我們現(xiàn)在的項(xiàng)目就直接放在了跟main.js同級(jí)的目錄下涤躲。
下面是utils.js文件中的內(nèi)容:
// 第一種修改title的方法 :
const setWechatTitle = function(title) {
document.title = title;
let mobile = navigator.userAgent.toLowerCase();
if (/iphone|ipad|ipod/.test(mobile)) {
let iframe = document.createElement('iframe');
iframe.style.visibility = 'hidden';
// 替換成站標(biāo)favicon路徑或者任意存在的較小的圖片即可
iframe.setAttribute('src', '//m.baidu.com/favicon.ico');
let iframeCallback = function() {
setTimeout(function() {
iframe.removeEventListener('load', iframeCallback)
document.body.removeChild(iframe)
}, 10)
};
iframe.addEventListener('load', iframeCallback)
document.body.appendChild(iframe)
}
};
// 第二種修改title的方法,其中包含iframe的設(shè)置:
let setTitleHack = function (t) {
document.title = t;
let iframe = document.createElement('iframe');
iframe.style.visibility = 'hidden';
iframe.style.width = '1px';
iframe.style.height = '1px';
iframe.src = '//m.baidu.com/favicon.ico';
iframe.onload = function () {
setTimeout(function () {
iframe.remove();
}, 10);
};
document.body.appendChild(iframe);
};
// 在文件的最下方輸出這兩個(gè)方法:
module.exports = {
setWechatTitle,
setTitleHack
};
準(zhǔn)備好上面的代碼贡未,接下來就看你需要在哪里使用了种樱,如果是單頁面應(yīng)用的話蒙袍,我們一般是在router.js文件中使用,因?yàn)槁酚蓪?dǎo)航發(fā)生時(shí)會(huì)執(zhí)行鉤子缸托,我們可以使用 router.beforeEach 注冊(cè)一個(gè)全局的 before 鉤子左敌,然后在router.beforeEach((to, from, next) => {...})修改title。
使用方式如下:
一俐镐,先在router.js文件中引入utils.js文件矫限。
import { setTitleHack } from './utils';
vue 2.0定義路由的時(shí)候,可以將所有的路由都放在一個(gè)組件配置對(duì)象中佩抹,同時(shí)叼风,可以配置 meta 字段,在其中添加一個(gè)title的屬性棍苹,值就是你這個(gè)頁面要顯示頁面上方的title无宿,像下面這樣:
const routes = [
{path: '/auth', component: auth, name: 'auth', meta: {title: '?授權(quán)頁'}},
{path: '/home', component: Home, name: 'home', meta: {title: ' 首頁' }},
];
顯示到手機(jī)上的效果如下:
二,在beforeEach中直接像下面這樣寫就可以了枢里。
router.beforeEach((to, from, next) => {
setTitleHack(to.meta.title);
next();
});
三孽鸡,還有一種情況就是在單個(gè)組件中使用,比如說你當(dāng)前這個(gè)頁面的title是根據(jù)不同用戶的姓名來栏豺,而用戶的姓名都是通過后臺(tái)來獲取的彬碱,是動(dòng)態(tài)的,所以奥洼,需要在用戶詳情的頁面中來動(dòng)態(tài)修改title巷疼,使用方式其實(shí)也差不多,下面就讓我們來看一下代碼:
同樣也是先引用灵奖,我這次把兩個(gè)方法都引用進(jìn)來嚼沿,上面我們用的是setTitleHack,下面我們來用一下setWechatTitle:
import { setWechatTitle, setTitleHack } from './../utils';
在我現(xiàn)在這個(gè)項(xiàng)目中瓷患,取數(shù)據(jù)的過程是在beforeCreate鉤子中做的骡尽,項(xiàng)目中獲取數(shù)據(jù)用的是vue-resource,修改title就在取到了數(shù)據(jù)以后擅编,下面來看代碼:
beforeCreate(){
let group_id = this.$route.params.id;
let dataUrl = "group/detail?group_id=" + group_id;
this.$http.get(dataUrl)
.then(({data:{code, content, jssdk, msg}}) => {
if (code === 0) {
this.content = content;
setWechatTitle(content.header.name + '團(tuán)');
// 取到名稱之后直接修改title爆阶。
} else {
MessageBox('提示', msg);
}
}, ({data:{msg}}) => {
MessageBox('提示', msg);
});
},
以上兩種方法我在項(xiàng)目中都用過,親測(cè)有效沙咏。