国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答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的處理。

目錄結構

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

    注意:

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

    如何修改默認啟動端口?

    可以在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
    主站蜘蛛池模板: 国产成人精品aaaa视频一区 | a毛片在线 | 亚洲视频一区二区 | 国产精品亚洲精品观看不卡 | 日韩欧美中文在线 | 九九福利 | 久久免费精品国产72精品剧情 | 久久国产精品最新一区 | 国产在线精品99一卡2卡 | 亚洲区精品久久一区二区三区 | 纯毛片| 精品一区二区在线观看 | 免费h视频在线观看 | 久久精品一区二区三区不卡牛牛 | 国内精品伊人久久久久 | 午夜视频在线观看免费视频 | 国产精品日韩精品 | 成人看的一级毛片 | 国产一区二区成人 | 曰韩在线 | 久久精品综合国产二区 | 日本精品在线观看 | 波多野结衣免费在线 | 久久成人a毛片免费观看网站 | 日韩精品一区二区三区国语自制 | 国产综合精品一区二区 | 日韩欧美综合在线 | 亚洲国产一区二区三区精品 | 日韩欧美国产精品第一页不卡 | 国产一区在线看 | 日韩一区二区三区免费 | 日本va视频| 欧美日韩国产一区二区三区播放 | 暧暧免费视频 | 伊人久久中文字幕久久cm | 国产黄色片在线观看 | 久久久久久综合一区中文字幕 | 亚洲高清色 | 久久国产精品最新一区 | 日韩精品一区在线 | 一区二区三区网站 |