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)即可