美文网首页vue相关知识Vue
vue 2.0 单页面应用动态修改微信中的title

vue 2.0 单页面应用动态修改微信中的title

作者: 愿你如夏日清凉的风 | 来源:发表于2017-03-28 10:44 被阅读953次

    使用vue做单页面应用的时候,修改title始终是一个非常重要的问题。由于单页面应用(SPA项目)里整个页面只在第一次完全刷新,后面只会局部刷新(一般不包括head及里面的title),微信浏览器首次加载页面初始化title后,就再也不监听 document.title的change事件,所以无法在服务器端控制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的时候写的,可以根据自己的需要来改成vue 2.0的代码。

    如果要兼容大部分常用的移动端,光上面这种写法是肯定不够的。
    好在通过网上搜索和自己的摸索,找到了两种解决办法,两种解决办法都能用,基本上也是通过看网上其他朋友给出的解决方案来优化的,今天抽点时间把他们整理一下,以便后面使用,也希望能帮到一些需要的朋友,代码中可能会有一些问题,发现了的朋友还望多多指点。

    两种方法的原理:都是动态给页面加上一个内容为空的iframe,随后立即删除这个iframe,这时候就会刷新title。
    第一种方法需要注意:由于微信iOS浏览器内核由UIWebView更新为WKWebView,所以必须版本升级到微信6.5.5此功能才可以正常使用,WKWebView 是苹果在iOS 8中引入的新组件,目的是提供一个现代的支持最新Webkit功能的网页浏览控件,摆脱过去 UIWebView的老、旧、笨,特别是内存占用量巨大的问题。它使用与Safari中一样的Nitro JavaScript引擎,大大提高了页面js执行速度。
    第二种方法具体来说就是通过动态创建iframe,设置相应的样式属性,并在iframe中增加一张图片,使其在每次创建的时候都会去加载这张图片,然后立即删除这个iframe,做这个目的就是为了微信重新去更新相应的一些属性,然后触发document.title的change事件,将新的title的值替换。

    我们把修改title的代码单独写在一个utils.js文件,可以放在你项目的根目录下,也可以单独添加一个文件夹放,只要知道引用的地址是什么就好,我们现在的项目就直接放在了跟main.js同级的目录下。

    下面是utils.js文件中的内容:

    
    // 第一种修改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';
            // 替换成站标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的设置:
    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);
    };
    
    // 在文件的最下方输出这两个方法:
    module.exports = {
        setWechatTitle,
        setTitleHack
    };
    

    准备好上面的代码,接下来就看你需要在哪里使用了,如果是单页面应用的话,我们一般是在router.js文件中使用,因为路由导航发生时会执行钩子,我们可以使用 router.beforeEach 注册一个全局的 before 钩子,然后在router.beforeEach((to, from, next) => {...})修改title。
    使用方式如下:

    一,先在router.js文件中引入utils.js文件。

    import { setTitleHack } from './utils';
    

    vue 2.0定义路由的时候,可以将所有的路由都放在一个组件配置对象中,同时,可以配置 meta 字段,在其中添加一个title的属性,值就是你这个页面要显示页面上方的title,像下面这样:

    const routes = [
        {path: '/auth', component: auth, name: 'auth', meta: {title: '�授权页'}},
        {path: '/home', component: Home, name: 'home', meta: {title: ' 首页' }},
    ];
    

    显示到手机上的效果如下:


    WechatIMG1.jpg

    二,在beforeEach中直接像下面这样写就可以了。

    router.beforeEach((to, from, next) => {
        setTitleHack(to.meta.title);
        next();
    });
    

    三,还有一种情况就是在单个组件中使用,比如说你当前这个页面的title是根据不同用户的姓名来,而用户的姓名都是通过后台来获取的,是动态的,所以,需要在用户详情的页面中来动态修改title,使用方式其实也差不多,下面就让我们来看一下代码:

    同样也是先引用,我这次把两个方法都引用进来,上面我们用的是setTitleHack,下面我们来用一下setWechatTitle:

    import { setWechatTitle, setTitleHack } from './../utils';
    

    在我现在这个项目中,取数据的过程是在beforeCreate钩子中做的,项目中获取数据用的是vue-resource,修改title就在取到了数据以后,下面来看代码:

    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 + '团');
                            // 取到名称之后直接修改title。
                        } else {
                            MessageBox('提示', msg);
                        }
                    }, ({data:{msg}}) => {
                        MessageBox('提示', msg);
                    });
            },
    

    以上两种方法我在项目中都用过,亲测有效。

    相关文章

      网友评论

      本文标题:vue 2.0 单页面应用动态修改微信中的title

      本文链接:https://www.haomeiwen.com/subject/cufjottx.html