最近在做一个商城官网,需要优化网站排名,公司要求做seo,项目架构用的vue SSR服务端渲染,由于vue是单页面应用,所以主要通过对路由的跳转动态切换title和meta里的内容来实现。

项目搭建就不多说了,主要是在gitHub上面下载的一个模版,后期会整理好再发一篇文章。

一、首先router.js给每个页面组件加上meta属性,然后meta属性里边定义一个title和index(因为tdk数据是后台请求到的数据,index是传给后台的参数,tdk的type :0.通用 1.首页 2.名人堂首页 3.文章首页 4.问答首页 5.领券中心 6.新人专享 7.选画中心页 8.名家子网)

 export function createRouter() {
    return new Router({
        mode: 'history',
        fallback: false,
        scrollBehavior: () => ({ y: 0 }),
        routes: [
            { path: '/', component: Home, meta: { title: '', index: 1 } },
            { path: '/login', component: Login, meta: { title: '' } },
            { path: '/register', component: Register, meta: { title: '' } },
            { path: '/setPassword', component: setPassword, meta: { title: '' } },
            { path: '/forgetPassword', component: forgetPassword, meta: { title: '' } },
            { path: '/resetPassword', component: resetPassword, meta: { title: '' } },
            { path: '/goods-:goods_id.html', component: Goods, meta: { title: '' } },
            { path: '/all', component: All, meta: { title: '' } },
            { path: '/shopCar', component: shopCar, meta: { title: '' } },
            { path: '/allfamous', component: Famous, meta: { title: '' } },
            { path: '/famouscompilations', component: famousCompilations, meta: { title: '', index: 2 } },
            { path: '/famousdetails', component: famousDetails, meta: { title: '' } },
            { path: '/xuanhua', component: xuanHua, meta: { title: '', index: 7 } },
            { path: '/huaniao', component: huaNiao, meta: { title: '' } },
            { path: '/renwu', component: renWu, meta: { title: '' } },
            { path: '/shanshui', component: shanShui, meta: { title: '' } },
            { path: '/shufa', component: shuFa, meta: { title: '' } },
            { path: '/dongwu', component: dongWu, meta: { title: '' } },
            { path: '/search', component: search, meta: { title: '' } },
            { path: '/article/', component: articleIndex, meta: { title: '', index: 3 } },
            { path: '/article_details', component: articleDetails, meta: { title: '' } },
            { path: '/question/', component: questionIndex, meta: { title: '', index: 4 } },
            { path: '/question_details', component: questionDetails, meta: { title: '' } },
            { path: '/ticketCenter', component: ticketCenter, meta: { title: '' } },
            { path: '/newUser', component: newUser, meta: { title: '' } },
            { path: '/userCenter', component: userCenter, meta: { title: '' } },
            { path: '/accountBalance', component: accountBalance, meta: { title: '' } },
            { path: '/recharge', component: recharge, meta: { title: '' } },
            { path: '/submitOrder', component: submitOrder, meta: { title: '' } },
            { path: '/address', component: adddressList, meta: { title: '' } },
            { path: '/orderPay', component: orderPay, meta: { title: '' } },
        ]
    })

二、app.js里边定义函数请求数据调用函数动态改变title,meta里边name属性的keywords和description(请求用的axios,没有安装的需要npm install axios安装一下,若已安装淘宝镜像,可以cnpm install axios)

if (process.browser) {//(因为项目是用vue SSR服务端渲染方式实现,服务端访问不到window对象,所以判断process.browser是在客户端)
        let head = document.getElementsByTagName('head'); // 创建head标签
        let meta1 = document.createElement('meta'); // 创建meta标签
        let meta2 = document.createElement('meta');
        meta1.name = "keywords"; // 设置name
        meta2.name = "description";
        //获取其他页的tdk
        function getMetaContent(index, h, m1, m2) {
            var params = {
                "Tdk": {
                    "type": index
                }
            }
            axios.post('这里换成后台给的接口', params)
                .then(function(res) {
                    let key = res.data.Tdk.tdk_keywords;
                    let desc = res.data.Tdk.tdk_description;
                    let title = res.data.Tdk.tdk_title;;
                    document.title = title || '设置默认内容';
                    m1.content = key || '设置默认内容';
                    m2.content = desc || '设置默认内容';
                    h[0].appendChild(m1)
                    h[0].appendChild(m2)
                })
        }
(商品页后台单独给的数据,数据是通过apiJson请求到的,参数需要自己修改,通过传商品的id请求到不同商品的tdk然后下边调用动态切换商品的title和meta里的name属性)
        //获取商品页的tdk
        function getGoodsMetaContent(index, h, m1, m2) {
            var params = {
                Goods: {
                    id: index,
                    "GoodsImgs[]": {
                        count: 0,
                        GoodsImgs: {
                            "goods_id@": "Goods/id",
                            use_flag: 1,
                            "@order": "rank-"
                        }
                    },
                    Artist: {
                        "id@": "Goods/artist_id"
                    }
                }
            };
            axios.post('这里改成后台给的接口', params)
                .then(function(res) {
                    let key = res.data.Goods.tdk_keywords;
                    let desc = res.data.Goods.tdk_description;
                    let title = res.data.Goods.tdk_title;;
                    document.title = title || '设置默认内容';
                    m1.content = key || '设置默认内容';
                    m2.content = desc || '设置默认内容';
                    h[0].appendChild(m1)
                    h[0].appendChild(m2)
                })
        }
		
		//路由跳转之前动态切换title和meta的name属性
        router.beforeEach((to, from, next) => {
            var i;
            //如果有商品id,说明跳入的是商品页,参数为商品id,如果没有则参数为router里定义好的meta里的index
            if (to.params.goods_id) {
                i = to.params.goods_id;
            } else if (from.meta.index || to.meta.index) {
                i = to.meta.index;
                var j = from.meta.index;
            } else {
                next();
            }
            if (i == j) return // 减少请求次数
            if (meta1.name == "keywords" || meta2.name == "description") { // 如果之前有获取过关键字,先清空内容
                meta1.content = '';
                meta2.content = '';
            }
            //如果跳入商品页执行getGoodsMetaContent,否则执行getMetaContent
            if (to.params.goods_id) {
                var i = to.params.goods_id;
                getGoodsMetaContent(i, head, meta1, meta2)
            } else {

                getMetaContent(i, head, meta1, meta2);
            }
            next()
        })
    }

这样就可以动态改变title和meta的name的属性了。如果想学习一下怎么搭建vue SSR服务端渲染,请看我下一篇文章。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐