nuxtjs重构项目遇到的坑

作者: 相遇一头猪 | 来源:发表于2019-07-07 23:41 被阅读13次

    VUE-TO-NUXT

    之前博客是用vue写的,由于SPA应用对SEO不友好,所以决定把项目用nuxt重构。

    SPA是什么

    SPA是一种网络应用程序(WebApp)模型。在传统的网站中,不同的页面之间的切换都是直接从服务器加载一整个新的页面,而在SPA这个模型中,是通过动态地重写页面的部分与用户交互,而避免了过多的数据交换。

    Vue的SPA应用为什么对SEO不友好

    如果你的应用程序初始展示 loading,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。

    也就是说,当爬虫抓取页面完毕时,你的数据可能还没有渲染到页面,因此就难以保证我们的页面可以被搜索引擎正常收录。

    Vue项目由一个<div id="app"></div>包裹,里面的内容都是由js动态生成,而爬虫是无法抓取js代码,因此SPA应用对SEO不友好。

    Nuxtjs是什么

    Nuxt是一个vue版本的SSR框架,基于Nuxt,我们可以简单的把Vue的SPA应用转化成SSR单页面应用。当然,Nuxt也可以不做SSR,但我们的目标就是SSR,不然也没必要去修改。

    Nuxt解决的问题:
    1. 解决SPA中首屏慢的问题。
    2. 减少了普通SPA对于SEO的不利影响。

    安装

    官方提供了一个模版,可通过vue-cli直接安装

        /*
            用过vue的,一般都有安装vue-cli。
            如果没有安装vue-cli,先自行安装再运行以下命令。
        */
        $ vue init nuxt-community/starter-template <project name>
    

    生成的目录结构

        ├── .nuxt 
        ├── assets
        ├── components
        ├── layouts
        ├── middleware
        ├── node_modules
        ├── pages
        ├── plugins
        ├── static
        ├── store
        ├── nuxt.config.js
        ├── package.json
        ├── README.md
    

    简单说一下目录结构对应存放的内容

    1. assets: 存放静态资源,放置需要经过 webpack 打包处理的资源文件,如 scss,图片,字体等。
    2. components: 组件,页面的一部分。
    3. layouts: 布局。页面默认布局为 default,它规定了一个页面如何布局页面。
    4. middleware: 中间件。存放中间件。可以在页面中调用: middleware: 'middlewareName' 。
    5. node_modules: 安装的第三方库。
    6. pages: 页面。此目录下的.vue文件会自动生成一个router(看不到)。
      (1) index.vue为根页面。
      (2) 如果需要二级路由,则创建一个新的文件夹。
      (3) 以_开头的.vue文件对应动态路由。
      官网直通车
    7. plugins: 插件。安装的第三方库需要各自创建文件在这里导入。
    8. static: 静态文件。放置不需要经过 webpack 打包的静态资源。
    9. store: 状态管理。跟Vuex在vue中的写法有点不同。
    10. nuxt.config.js: 用于组织Nuxt.js 应用的个性化配置。

    Vue项目重构为Nuxt

    安装

    通过vue-cli生成一个项目

        $ vue init nuxt-community/starter-template my-web
        $ cd my-web
        $ npm install
        $ npm run dev
    

    项目启动,默认是3000端口。注意生成的项目已经包含vuex和vue-router。

    安装第三方库

        $ npm install element-ui highlight.js @nuxtjs/axios --save
    

    这里就跟Vue不同了,在Vue里面我们需要在main.js导入第三方库,然后用Vue.use()。
    在Nuxt,需要在plugins目录下创建对应的js文件,然后把需要原先写在main.js里面的内容写到创建的js文件中,如

        //在plugins目录下新建element-ui.js
        
        import Vue from 'vue'
        import Element from 'element-ui'
        import 'element-ui/lib/theme-chalk/index.css'
    
        Vue.use(Element)
    
        //在plugins目录下新建highlight.js
    
        import Vue from 'vue'
        import hljs from 'highlight.js'
        import 'highlight.js/styles/googlecode.css' 
    
        Vue.directive('highlight',function (el) {
            let blocks = el.querySelectorAll('pre code');
            blocks.forEach((block)=>{
            hljs.highlightBlock(block)
            })
        })
    

    注意@nuxtjs/axios比较特殊,有兴趣的可以自行搜索看看。

    然后在nuxt.config.js中写入

        //插件只在浏览器里使用,这种情况下下,你可以用 ssr: false ,使得插件只会在客户端运行,如果element-ui不这样写会报错。
        plugins: ['~plugins/highlight.js',{ src: '@/plugins/element-ui.js', ssr: false }]
        //这是 @nuxtjs/axios
        modules: ['@nuxtjs/axios']
    

    好了,第三方库已经安装并且可以使用了。

    图片和common.css

    图片放入assets目录,并在assets新建css文件夹,把common.css放入css文件夹,此时还需要通过配置common.css才能生效。

        //nuxt.config.js
        css: [
        '~assets/css/common.css'
        ]
    

    组件移到components目录

    原先Vue项目有对应路由的component移到pages目录

    修改根组件文件名为index.vue。二级页面新建文件夹,文件夹名为页面的名字,然后把页面放到文件夹下,修改名字为index.vue。

    router-link改为nuxt-link

    在layouts中新建布局

    新建blog.vue,上下布局

    <template>
        <div  id="blog">
            <Introduce>
            </Introduce>
            <el-row  type="flex" class="layout-flex" >
                <el-col  class="layout-menu-right">
                    <div class="layout-content">
                        <div class="layout-content-main">
                                <nuxt />  //就这里,如果页面是这个布局,页面会插入这里
                        </div>
                    </div>
                </el-col>
            </el-row>
        </div>
    </template>
    

    给pages中对应页面加上layout

    <script>
    export default {
        layout: 'blog'
    }
    </script>
    

    以下是遇到的坑

    博客导航栏公用一个组件导致的问题

    在原先的Vue项目中,导航栏共用一个.vue组件,组件通过query来获取数据。

    改为Nuxt项目后,点击导航,URL会改变,页面不会刷新(页面没有任何变化),解决办法是通过watch监听路由。

        watch: {
            $route() {
                //this.$route.query.type 
            }
        }
    

    在created使用localstorage会报错

    解决办法是改为在mounted中使用。

    没有keep-alive

    由于是服务端渲染,所以不支持组件的keep-alive。

    store写法不同

    原先的Vue项目Store写法:

    import Vue from 'vue';
    import Vuex from 'vuex';
    Vue.use(Vuex);
    
    export default new Vuex.Store({
        state:{
          
        },
        getters: {
    
        }
        mutations: {
    
        },
        actions: {
    
        }
    })
    

    Nuxt项目自带store目录,其中包含与模块对应的每个文件,并且state的值应该始终是function。

        //需将状态导出为函数,将变量和操作作为 store/index.js 中的对象导出
        import Vuex from 'vuex'
        
        export const state = () => ({
           counter: 0
        })
    
        export const mutations = {
            increment (state) {
                state.counter++
            }
        }
    

    注意store修改需要通过mutation或者action,不然会报错。

    Vuex直通车

    相关文章

      网友评论

        本文标题:nuxtjs重构项目遇到的坑

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