vue-14-服務(wù)器渲染與Nuxt

SSR服務(wù)器端渲染

服務(wù)端渲染(SSR)與客戶端渲染(BSR)都是數(shù)據(jù)渲染的主要的方式

客戶端渲染

前端利用ajax等數(shù)據(jù)交互手段獲取服務(wù)端提供的數(shù)據(jù)之后,渲染到HTML頁(yè)面。

服務(wù)器端渲染

整個(gè)網(wǎng)站先在服務(wù)器中運(yùn)行,然后返回一個(gè)完整的HTML字符串,將這個(gè)字符串當(dāng)成響應(yīng)內(nèi)容輸出給瀏覽器。

SSR優(yōu)勢(shì)

  • 利于搜索引擎抓取我們的頁(yè)面。
  • build之后,會(huì)靜態(tài)化page頁(yè)面,所以訪問(wèn)速度快。

Nuxt.js (重點(diǎn))

Nuxt.js 是基于 vue 的服務(wù)器端渲染框架。

安裝 create-nuxt-app 工具

npm install -g create-nuxt-app

使用 create-nuxt-app 創(chuàng)建 nuxtjs 項(xiàng)目

create-nuxt-app myapp1

其他創(chuàng)建 nuxtjs 項(xiàng)目的方法:

# 運(yùn)行 create-nuxt-app
npx create-nuxt-app myapp1

# 或者
yarn create nuxt-app myapp1

創(chuàng)建 nuxt 項(xiàng)目的過(guò)程中,會(huì)問(wèn)我們選擇哪種渲染方式,這里一定要選擇 Universal(通用的、普遍的)。

spa 是單頁(yè)面應(yīng)用,這種模式下,文件不會(huì) ssr 渲染,所以 nuxt 就沒(méi)有意義了。

// 如果想更改渲染方式,可以修改 nuxt.config.js 中的 mode 屬性。
mode: 'Universal'   // Universal 可以ssr; spa 不會(huì)ssr

nuxt 項(xiàng)目創(chuàng)建完畢后,先進(jìn)入到項(xiàng)目中,然后運(yùn)行起來(lái):

cd myapp1
npm run dev

應(yīng)用現(xiàn)在運(yùn)行在 http://localhost:3000 上運(yùn)行。

修改服務(wù)端口

package.json

"config": {
    "nuxt": {
        "host": "0.0.0.0",
        "port": "3333"
    }
},
"script":{
    
}

scss

nuxt 本身不直接支持 scss,需要先安裝模塊:

cnpm i node-sass sass-loader -D

打開(kāi) layouts/default.vue 頁(yè)面,編寫(xiě)scss代碼測(cè)試。

<style lang="scss" scoped>
</style>

rem文件引入

// 不要使用這種方式引入rem,因?yàn)樗⑿马?yè)面時(shí),會(huì)報(bào)找不到document錯(cuò)誤,這是ssr渲染造成的問(wèn)題。
import '~/assets/js/rem.js'

import 這種導(dǎo)入的作用是把碎片化的文件合并到一起。

在 static 目錄下,建立 js/rem.js 文件。

static 目錄是存放獨(dú)立的文件的。

我們應(yīng)該使用 script 標(biāo)簽引入 rem.js 文件,但 nuxtjs 中沒(méi)有 html 頁(yè)面,需要寫(xiě)在 nuxt.config.js 中。

在 nuxt.config.js 文件中:

head: {
    script:[
        { src: '/js/rem.js', async: true, defer: true }
    ]
},

config 頁(yè)面中 head 屬性中所描述的文件,都直接在 static 中查找。

nuxtjs 沒(méi)有所謂的 index.html 入口頁(yè),這個(gè) index.html 實(shí)際是有 nuxt.config.js 編譯而成的。

iscroll 、swiper 等插件也應(yīng)該用此種方式引入。

重啟網(wǎng)站服務(wù)后,就能夠正常訪問(wèn)網(wǎng)站了。

刷新的時(shí)候,如果字體特別大,可以在 layouts/default.vue 中給 div{ font-size:0.3rem }

主布局頁(yè)

layouts/default.vue 這個(gè)頁(yè)面是主布局頁(yè)面(入口頁(yè))。

div{
    display: flex;
    justify-content: space-around;
    align-items: center;

    li{
        text-align:center;

        a{
            color:white;
            text-decoration: none;
        }

        .nuxt-link-exact-active{
            color: green !important;
        }
    }
}

nuxt標(biāo)簽可以理解成出口,每次觸發(fā)路由跳轉(zhuǎn)時(shí),這部分內(nèi)容會(huì)自動(dòng)更新。該標(biāo)簽?zāi)J(rèn)解析page/index.vue

路由

在 pages 文件夾下創(chuàng)建 buycar/index.vue 文件

在任意 vue 頁(yè)面中寫(xiě)鏈接

<nuxt-link to="/mine">我的</nuxt-link>

當(dāng)點(diǎn)擊鏈接后,視圖層會(huì)自動(dòng)更新。

獲取遠(yuǎn)程數(shù)據(jù)

下載

cnpm i axios -S

引入

import axios from 'axios';

使用

asyncData方法會(huì)在組件(限于page頁(yè)面組件)每次加載之前被調(diào)用。它可以在服務(wù)端或路由更新之前被調(diào)用。

  • 因?yàn)?asyncData 在前端渲染頁(yè)面之前調(diào)用,所以 asyncData 中沒(méi)有 this。
  • 先通過(guò) asyncData 中的代碼獲取到遠(yuǎn)程的數(shù)據(jù),然后再把得到的遠(yuǎn)程數(shù)據(jù)合并到當(dāng)前前端組件 data 中,然后在渲染頁(yè)面,這就是 ssr 渲染的過(guò)程。
export default {
    async asyncData({ params }) {
        let { data } = await axios.get('/1.json');
        console.log('data:', data);
        return data;    // 這個(gè)return會(huì)把結(jié)果和data屬性的值自動(dòng)合并,視圖層直接調(diào)用即可。
    }
};

如果不喜歡 es6 的 async/await,那么也可以使用回調(diào)函數(shù)。

asyncData({ params }, callback){
    axios.get(`http://127.0.0.1:3000/goods`).then(res=>{
        callback(null, {
            a:1,
            arr:res.data
        })
    })    
}

在 static 中新建 1.json 做模擬數(shù)據(jù),例如 {a:1, b:2}

在視圖層可以直接使用return返回來(lái)的數(shù)據(jù)

{{ a }}

vuex

安裝

cnpm i vuex -S

在 store 目錄下,新建 index.js 文件

在 Nuxt 中已經(jīng)對(duì) vuex 進(jìn)行了處理,所以此處直接導(dǎo)出 state 和 mutations 即可。

export const state = ()=>({
    a : 102
})

export const mutations = {
    add(state){
        state.a++
    }
}

export const actions = {
    add(context){
        context.commit('add');
    }
}

export const getters = {
    abc(state){
        return state.a*2;
    }
}

組件頁(yè)

<button @click="add">{{a}}</button>
import {mapState, mapMutations, mapActions, mapGetters} from 'vuex';

export default {
    computed:{
        ...mapState(['a']),
        ...mapGetters(["abc"])
    },
    methods:{
        ...mapActions(['add'])
    },
    mounted(){
        console.log( this.$store )
    }
};

記得重啟服務(wù),否則會(huì)報(bào) state 不存在這種錯(cuò)誤。

打包

項(xiàng)目都開(kāi)發(fā)完畢之后,我們需要將開(kāi)發(fā)環(huán)境下的碎片化的文件做合并,這個(gè)過(guò)程就叫做打包(發(fā)布)。

我們最終交付上線的是打包后的文件(交付的是生產(chǎn)環(huán)境下的代碼)。

打包的方法有兩種:

  • 如果mode=universal(ssr)模式的話,generate可以生成dist目錄
npm run generate
  • 如果mode=spa模式的話,build和generate都可以生成dist目錄
npm run build

可以看看 package.json 文件中的 scripts 屬性,每個(gè)腳本都有特殊的作用。

部署

將上一步的 dist 文件夾放入網(wǎng)站服務(wù)器下,這樣別人就可以通過(guò)瀏覽器直接訪問(wèn)了。

有很多種部署網(wǎng)站的方法,比如 nodejs:

文件結(jié)構(gòu)

www/
    node_modules/
    dist/
    app.js

app.js 代碼

// npm install express
const express = require('express');
const app = express();
app.use(express.static('dist'));
app.listen(80);

開(kāi)啟網(wǎng)站服務(wù)

node app.js

用戶打開(kāi)瀏覽器訪問(wèn)這個(gè)nodejs站點(diǎn)即可

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容