<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        Nuxt.js實現一個SSR的前端博客的示例代碼

        來源:懂視網 責編:小采 時間:2020-11-27 21:51:03
        文檔

        Nuxt.js實現一個SSR的前端博客的示例代碼

        Nuxt.js實現一個SSR的前端博客的示例代碼:為什么要用Nuxt.js 公司現有的項目只有落地頁是通過前端本身server讀取pug文件進行服務端渲染的,當然是為了首屏加載速度以及SEO。Nuxt.js 是一個基于Vue.js的通用應用框架,預設了利用Vue.js開發服務端渲染的應用所需要的各種配置,只需要安裝官方文檔的要求
        推薦度:
        導讀Nuxt.js實現一個SSR的前端博客的示例代碼:為什么要用Nuxt.js 公司現有的項目只有落地頁是通過前端本身server讀取pug文件進行服務端渲染的,當然是為了首屏加載速度以及SEO。Nuxt.js 是一個基于Vue.js的通用應用框架,預設了利用Vue.js開發服務端渲染的應用所需要的各種配置,只需要安裝官方文檔的要求

        為什么要用Nuxt.js

        公司現有的項目只有落地頁是通過前端本身server讀取pug文件進行服務端渲染的,當然是為了首屏加載速度以及SEO。Nuxt.js 是一個基于Vue.js的通用應用框架,預設了利用Vue.js開發服務端渲染的應用所需要的各種配置,只需要安裝官方文檔的要求進行開發,就可以很好的解決SSR的問題。我們以一個簡單的博客為例,來實踐一下Nuxt.js。

        項目介紹

        當前基于Nuxt.js的簡化版博客,包括注冊、登錄、文章列表頁面、文章詳情頁、以及用戶列表頁等幾個頁面,用戶信息使用了Vux進行存儲,異步數據使用了asyncData進行獲取,配合了nuxtServerInit、cookie來處理刷新頁面后Vux數據丟失的問題,同時使用了error模板頁面處理常規錯誤,使用了中間件進行了簡單的權限校驗。該項目不足點,統一封裝了axios的方法,但是沒有考慮到服務端請求接口,token的處理。

        目錄結構

      1.  assets: 資源文件。用于組織未編譯的靜態資源如 LESS、SASS或 JavaScript。
      2. components: 組件。
      3. layouts: page: 模板頁面,默認為 default.vue可以在這個目錄下創建全局頁面的統一布局,或是錯誤處理頁面頁,需要提供一個nuxt 標簽,類似于router-view
      4. middleware: 中間件,放置自定義的中間件,會在加載組件之前調用。可以在頁面中調用: middleware: '中間件名稱'。
      5. pages: 頁面,index.vue 為根頁面,Nuxt.js 框架讀取該目錄下所有的 .vue文件并自動生成對應的路由配置,如需要動態參數id,則可以添加_id的文件,必須是下劃線加參數名。
      6. plugin: 插件,用于組織那些需要在 根Vue.js應用實例化之前需要運行的 Javascript 插件。
      7. static: 靜態文件,靜態文件目錄 static用于存放應用的靜態文件,此類文件不會被 Nuxt.js 調用 Webpack 進行構建編譯處理。
      8. store: 用于組織vuex狀態管理。具體使用請移步至 官網。
      9. nuxt.config.js: nuxt.config.js文件用于組織Nuxt.js 應用的個性化配置,配置head,loading,css,plugins等。
      10. Nuxt.js生命周期

        1. incoming Request 瀏覽器發出的請求)
        2. nuxtServerInit 服務端接受請求后,要檢查當前有沒有 nuxtServerInit配置項,如果有就執行這個函數
        3. store action 用來操作vuex
        4. middleware 可以做jWT等一些操作。
        5. validate() 檢驗參數,參數檢驗失敗,可以在layout里的error里面進行捕捉。
        6. asyncData()& fetch() asyncData用來渲染組件,fetch用來渲染vuex
        7. Render

        Nuxt擴展以后的生命周期和方法以下:

        beforeCreate: ƒ beforeCreate()
        components: {NuxtLoading: {…}}
        computed: {isOffline: ƒ}
        context: {isStatic: false, isDev: true, isHMR: true, app: {…}, payload: undefined, …}
        created: ƒ created()
        data: ƒ data()
        head: {title: "nuxt-meituan-ssr", meta: Array(3), link: Array(1), style: Array(0), script: Array(0)}
        methods: {refreshOnlineStatus: ƒ, refresh: ƒ, errorChanged: ƒ, setLayout: ƒ, loadLayout: ƒ}
        mounted: ƒ mounted()
        nuxt: {…}
        render: ƒ render(h, props)
        router: VueRouter {app: Vue, apps: Array(1), options: {…}, beforeHooks: Array(2), resolveHooks: Array(0), …}
        watch: {nuxt.err: "errorChanged"}

        注意:

      11. Vue.js生命周期的鉤子只有beforeCreate和created會在服務端和客戶端渲染。
      12. 以上生命周期里都獲取不到window對象。
      13. asyncData和fetch我們可以拿到數據,不要嘗試掛載數據到data上,此時獲取不到this對象。
      14. 開發總結

        如何修改默認啟動端口?

        可以在package.json下面修改配置,如下。

        "config":{
         "nuxt":{
         "host":"127.0.0.1",
         "port":"3304"
         }
        }

        如何添加全局的樣式?

        可以在assets里添加全局Css文件,如在assets下的Css文件夾目錄下添加了一個index.css文件,然后在nuxt-config.js里配置該css文件路徑即可。 css:['~assers/css/index.css']

        通過別名訪問圖片在template里是正確的,為何在Css設置背景圖卻報錯?

        在css配置的是,需要將'~/'后面的'/'去除掉。

         <img src="~/static/logo.jpg"/> 
         backround-image:url('~static/logo.jpg');

        如何添加路由動畫?

        同樣,我們在Css文件里添加一些動畫代碼,一般樣式會在其后面添加-active和-leave-active,其實和Vue動畫形式一致。其中以page開頭的動畫,默認會作用于全部頁面,如果想給特定的頁面加動畫,可以在對應的頁面script里引用,如 transitions: 'bounce'即可。

        .page-enter-active, .page-leave-active {
         transition: opacity .3s
         }
         .page-enter, .page-leave-active {
         opacity: 0
         }
         .bounce-enter-active {
         animation: bounce-in .8s;
         }
         .bounce-leave-active {
         animation: bounce-out .5s;
         }
         @keyframes bounce-in {
         0% { transform: scale(1) }
         50% { transform: scale(1.01) }
         100% { transform: scale(1) }
         }
         @keyframes bounce-out {
         0% { transform: scale(1) }
         50% { transform: scale(1.01) }
         100% { transform: scale(1) }
         }

        路由參數如何傳遞?

        同Vue-router,有聲明式和編程式兩種方式,無非是標簽變成了 router.push(...)

         nuxt-link :to="{name:'article',params:{id:1234}}" >聲明式</nuxt-link>
         // 編程式
         this.$router.push({
         name:'article',
         params:{
         id:1234
         }
         })

        動態路由如何進行參數檢驗?

        Nuxt.js提供了一個validate的生命周期鉤子,可以在此進行參數的校驗。以文章詳情校驗id為例,我們需要判斷傳入的id是否是數字,可以像下面這樣處理。

         validate({ params }) {
         return /^\d+$/.test(params.id)
         }

        如何添加404等錯誤頁面?

        可以在layout下新建一個error.vue頁面,內容如下,當訪問一個不存在的頁面的時候,或者參數檢驗失敗的時候,或者我們在middleware中間件處理拋出異常的時候,都會跳轉到該頁面。

        <template>
         <div class="container">
         <h1 v-if="error.statusCode === 404">頁面不存在</h1>
         <h1 v-else>應用發生錯誤異常</h1>
         <nuxt-link to="/">首 頁</nuxt-link>
         </div>
        </template>
        
        <script>
        export default {
         props: ['error'],
         layout: 'blog' // 指定模板頁面
        }
        </script>

        middleware中的文件拋出錯誤

        export default function({ store, error, redirect }) {
         if (!store.state.user.userInfo.auth) {
         error({
         message: '沒有權限哦!',
         statusCode: 403
         })
         }
        }

        頂部進度條如何設置?

        loading 屬性配置 可以在nuxt-config.js設置loading的顏色,使用了this. loading可能無法在created里立即使用。此種配置loading有嚴重的缺陷,無法知道真正的加載進度。也可以自定義加載組件,loading: '~components/loading.vue'。

        export default {
         mounted () {
         this.$nextTick(() => {
         this.$nuxt.$loading.start()
         setTimeout(() => this.$nuxt.$loading.finish(), 500)
         })
         }
         }

        異步數據如何獲取?

        Nuxt.js提供了兩個函數,asyncData和fetch函數。asyncData 獲取組件的數據,fetch 在渲染頁面之前獲取數據填充應用的狀態樹(store)。

        asyncData可以使用promise也可以使用async函數,記住,此時返回的東西需要用一個對象進行包裹,不能掛載到data里,此時沒有this對象。

        // 方式一
         asyncData({ app,params,route,query,error}) {
         return getUserlist({}).then(res => {
         let user = [];
         user = res.list
         console.log(user,'user')
         return {user}
         })
         .catch(err => {
         console.log(err)
         })
        },
        
        // 方式二
        async asyncData({ app }) {
         let data = await getUserlist({});
         let user = data.list;
         return { user }
        }

        fetch函數同上,可以使用promise也可以使用async函數,通常會commit一個mutation。

        export default {
         fetch ({ store, params }) {
         return axios.get('http://my-api/stars')
         .then((res) => {
         store.commit('setStars', res.data)
         })
         }
        }
        </script>
        // 或者使用 async 或 await 的模式簡化代碼如下:
        <template>
         <h1>Stars: {{ $store.state.stars }}</h1>
        </template>
        
        <script>
        export default {
         async fetch ({ store, params }) {
         let { data } = await axios.get('http://my-api/stars')
         store.commit('setStars', data)
         }
        }
        </script>

        如何動態修改title的內容?

        如果是寫死的,可以直接修改head的配置。

         head() {
         return {
         // title: '',這里一旦聲明,在asyncdata里修改也不起作用,直接以這個為準
         meta: [
         {
         hid: 'description', // nuxt.config 替換唯一標識 hid { hid: 'description', name: 'description', content: 'Nuxt.js project' }
         name: 'content',
         content: '文章詳情'
         }
         ]
         }
         },

        如果是動態數據從數據源里獲取,然后通過asynData里的app對象,動態修改head的title。

         asyncData({ app, params }) {
         const id = params.id;
         return getArticleDetail({ id })
         .then(result => {
         app.head.title = result.title;
         })
         .catch(err => {})
         }

        如何進行權限JWT驗證?

        登錄成功以后,我們會在cookie和Vuex中緩存token信息,當界面刷新的時候,會走store里的nuxtServerInit 函數,該函數僅在每個服務器端渲染中運,可以使用req.headers.cookie獲取瀏覽器的cookie,再次更新store里的值,接著會走到中間件,中間件進行驗證,如果有token信息則繼續,沒有則跳轉到登錄頁。
        1. 為什么要在nuxtServerInit更新store的值?
        需要在middleware里使用,否則刷新后store里的值為空了。
        2. 客戶端調用接口可以拿到token,服務器端如何拿到?
        可以通過nuxtServerInit里的req拿到請求信息的cookie,然后請求接口。
        3. 前后端分離,刷新的時候如何保證用戶名、token等信息依然存在?
        可以像上面一樣,每次取cookie的值再次更新store,但這樣有一個問題,cookie可能會被篡改,后端代碼需要做驗證。也可以每次刷新重新通過token請求接口,更新用戶信息。

        store代碼

        import Vue from 'vue';
        import Vuex from 'vuex';
        import user from './modules/user';
        import { COOKIE_KEY } from '~/assets/js/constant.js';
        Vue.use(Vuex);
        const store = () =>
         new Vuex.Store({
         modules: {
         user
         },
         actions: {
         async nuxtServerInit({ commit, dispatch }, { req, app }) {
         if (req.headers.cookie) {
         let parsedResult = {};
         req.headers.cookie.split(';').forEach(cookie => {
         const currentCookie = cookie.split('=');
         parsedResult[currentCookie[0].trim()] = (currentCookie[1] || '').trim();
         });
         const userInfo = {
         name: parsedResult[COOKIE_KEY.NAME],
         token: parsedResult[COOKIE_KEY.TOKEN]
         };
         commit('user/setUserInfo',userInfo);
         }
         }
         }
         });
        
        export default store;

        中間件代碼

        export default function({ store, error, redirect }) {
         if (!store.state.user.userInfo.token || !store.state.user.userInfo.name) {
         // error({
         // message: 'You are not connected',
         // statusCode: 403
         // })
         redirect('/');
         }
        }

        nginx部署

         npm run build
        選擇build以后的四個文件: .nuxt, static, nuxt.config.js, package.json上傳到服務器。
        pm2 pm2 start npm --name 'package.json.name' -- run start
        nginx配置

        查看網頁源代碼可以看到:

         server{
         listen 3000;
         server_name felix12345.club; 
         gzip on;
         gzip_buffers 32 4K;
         gzip_comp_level 6;
         gzip_min_length 100;
         gzip_types application/javascript text/css text/xml;
         gzip_disable "MSIE [1-6]\."; 
         gzip_vary on;
         proxy_buffer_size 64k;
         proxy_buffers 32 32k;
         proxy_busy_buffers_size 128k;
         location / {
         root /data/ww/nuxt;
         proxy_pass http://127.0.0.1:3002;
         proxy_set_header X-Real-IP $remote_addr;
         }
         }

        這樣,使用Nuxt.js實現了一個服務端渲染的簡易博客。

        在線訪問地址: http://felix12345.club:3000/article/

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Nuxt.js實現一個SSR的前端博客的示例代碼

        Nuxt.js實現一個SSR的前端博客的示例代碼:為什么要用Nuxt.js 公司現有的項目只有落地頁是通過前端本身server讀取pug文件進行服務端渲染的,當然是為了首屏加載速度以及SEO。Nuxt.js 是一個基于Vue.js的通用應用框架,預設了利用Vue.js開發服務端渲染的應用所需要的各種配置,只需要安裝官方文檔的要求
        推薦度:
        標簽: ssr 博客 blog
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 曰韩无码AV片免费播放不卡 | 久久精品国产亚洲AV无码娇色| 性无码免费一区二区三区在线| 精品亚洲AV无码一区二区三区| 国产免费一区二区三区VR| 精品视频在线免费观看| 亚洲国产区男人本色在线观看| 亚洲欧洲精品成人久久奇米网| 日本免费人成视频在线观看| 亚洲av无码有乱码在线观看| 亚洲国产成人高清在线观看| 成年人在线免费观看| 久久九九全国免费| 亚洲av成人一区二区三区在线播放| 国产V亚洲V天堂A无码| 永久免费AV无码网站在线观看| 性xxxx视频免费播放直播 | 最近2019中文字幕免费直播| 羞羞漫画小舞被黄漫免费| 亚洲日韩区在线电影| 亚洲精品无码专区2| 无码专区永久免费AV网站| 18禁在线无遮挡免费观看网站| 亚洲av永久中文无码精品综合| 亚洲丁香色婷婷综合欲色啪| 亚洲精品成人网久久久久久| 性色av无码免费一区二区三区| 欧洲人免费视频网站在线| 免费视频成人国产精品网站| 狠狠色香婷婷久久亚洲精品| 亚洲成av人影院| 亚洲国产成人久久一区WWW| 一个人免费观看在线视频www| 国产一级淫片a免费播放口| 激情吃奶吻胸免费视频xxxx| 亚洲熟妇丰满xxxxx| 亚洲一欧洲中文字幕在线| 精品亚洲aⅴ在线观看| 国产亚洲精品a在线无码| 亚洲免费在线观看| 亚洲欧洲精品成人久久曰影片 |