前言
今天抽空過(guò)了遍nuxt文檔添履,寫了個(gè)實(shí)踐demo郁轻,關(guān)于nuxt我已經(jīng)斷斷續(xù)續(xù)看了好幾遍了泥兰,自我感覺(jué)也算是入門了吧庄涡,從開發(fā)到上線心里都有底量承。后期打算在項(xiàng)目用起來(lái)的是nuxt框架,一些函數(shù)工具庫(kù),比如ramda撕捍,lodash等等拿穴,后臺(tái)服務(wù)估計(jì)會(huì)使用### fastify 這個(gè)庫(kù),目測(cè)非常方便忧风,嘗試嘗試默色。
基礎(chǔ)只是還是以官方文檔為主,嘗試過(guò)程中如果有什么問(wèn)題可以留言狮腿,看到會(huì)回復(fù)腿宰,文章如有錯(cuò)誤,歡迎指正缘厢。
預(yù)處理器的使用
安裝需要的loader后指定lang就可以直接使用吃度。
npm i less less-loader --save--dev
//全局css
css: [
{
src: 'static/less/base.sass',
lang: 'less'
}
],
//頁(yè)面中使用
<style lang="less" scoped></style>
頁(yè)面loading
//禁用
module.exports = {
loading: false
}
//顏色條
module.exports = {
loading: { color: '#3B8070' }
}
//使用組件
添加一個(gè)loading組件 (官方示例如下,詳情可看官方文檔)
引用該組件
module.exports = {
loading: '~components/loading.vue'
}
/// components/loading.vue
<template lang="html">
<div class="loading-page" v-if="loading">
<p>Loading...</p>
</div>
</template>
<script>
export default {
data: () => ({
loading: false
}),
methods: {
start () {
this.loading = true
},
finish () {
this.loading = false
}
}
}
</script>
<style scoped>
.loading-page {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.8);
text-align: center;
padding-top: 200px;
font-size: 30px;
font-family: sans-serif;
}
</style>
按照官方引用組件的方法贴硫,我測(cè)試報(bào)了個(gè)錯(cuò)椿每,把~/ 改成 ./ 解決。估計(jì)是nuxt解析vue文件的問(wèn)題英遭。
使用插件间护、第三方模塊
//通過(guò)script標(biāo)簽
head: {
script: [
{ src: 'https://res.wx.qq.com/open/js/jweixin-1.2.0.js' }
]
},
//plugins配置 , ssr:false 設(shè)置只在客戶端使用
plugins: [
{ src: '~plugins/flexible.js', ssr: false }
],
//在頁(yè)面中使用axios贪绘,配置vendor使其只打包一次
//頁(yè)面
<template>
<h1>{{ title }}</h1>
</template>
<script>
import axios from 'axios'
export default {
async asyncData ({ params }) {
let { data } = await axios.get(`https://my-api/posts/${params.id}`)
return { title: data.title }
}
}
</script>
//配置文件
module.exports = {
build: {
vendor: ['axios']
}
}
使用第三方組件庫(kù)
在nuxt里使用第三方UI組件庫(kù)也非常簡(jiǎn)單兑牡。以iview為例(我個(gè)人非常中意的組件庫(kù))
///在plugins下新建 iview.js
import Vue from 'vue'
import iView from 'iview';
Vue.use(iView);
////配置文件引入css和plugin
module.exports = {
css: [
{ src: 'iview/dist/styles/iview.css'}
],
plugins: [
{ src: '~plugins/iview.js', ssr: false }
],
}
路由
//基礎(chǔ)路由示例, 詳情請(qǐng)看官方文檔
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'user',
path: '/user',
component: 'pages/user/index.vue'
},
{
name: 'user-one',
path: '/user/one',
component: 'pages/user/one.vue'
}
]
}
nuxt為我們省去了定義路由的過(guò)程税灌,頁(yè)面結(jié)構(gòu)自動(dòng)生成路由均函,不得不說(shuō),這對(duì)開發(fā)效率是有比較大的提升菱涤。官方還提供了路由切換動(dòng)畫苞也,中間件等配置,我們可以在切換路由時(shí)良好的控制頁(yè)面粘秆。
中間件
開發(fā)后臺(tái)管理頁(yè)面的時(shí)候如迟,我們經(jīng)常有autu認(rèn)證需求,如果沒(méi)有登錄攻走,或者權(quán)限問(wèn)題殷勘,都有一個(gè)腳本去控制跳轉(zhuǎn),中間件就派上用場(chǎng)了昔搂。
// middleware/auth.js
export default function ({ store, redirect }) {
if (!store.state.user) {
return redirect('/login')
}
}
//頁(yè)面單獨(dú)使用
export default {
middleware: 'auth'
}
///全局使用
module.exports = {
router: {
middleware: 'auth'
}
}
上面我們定義了一個(gè)auth中間件玲销,如果用戶未登錄,則跳轉(zhuǎn)登錄頁(yè)摘符。
視圖和錯(cuò)誤頁(yè)
一般開發(fā)SPA頁(yè)面贤斜,我們一般是組件+頁(yè)面混合開發(fā)策吠,,nuxt則是固定布局layouts瘩绒,路由必須采用一個(gè)layouts猴抹,默認(rèn)default,頁(yè)面內(nèi)部我們可以像個(gè)vue開發(fā)那樣引入多個(gè)components锁荔。
nuxt可以定義個(gè)錯(cuò)誤頁(yè)蟀给,在layouts下定義個(gè)error.vue文件。具體代碼可以看官方文檔
asyncData
nuxt擴(kuò)展的異步數(shù)據(jù)方法阳堕,對(duì)于頁(yè)面數(shù)據(jù)坤溃,我們一般有頁(yè)面data定義的形式和vuex統(tǒng)一管理的形式,可以根據(jù)自己的需求選擇嘱丢。
data定義這里就不贅述了,這里說(shuō)一下vuex統(tǒng)一管理數(shù)據(jù)的做法祠饺。
///page頁(yè)面
<template>
<div class="container">
<p class="title">數(shù)據(jù)展示!</p>
<Table :columns="columns1" :data="data1"></Table>
</div>
</template>
<script>
import { mapState } from 'vuex'
import axios from 'axios'
export default {
middleware: 'auth', //定義頁(yè)面中間件
head () {
return {
title: '其他頁(yè)面'
}
},
data () {
return {}
},
async fetch ({ store, params }) {
let { data } = await axios.get('http://106.14.205.222/article/list?page=1&limit=10&isActive=1')
console.log( data )
store.commit('SET_LIST', data.list)
},
computed: {
...mapState([
// 映射 this.xxx 為 store.state.xxx
'columns1',
'data1'
])
},
}
</script>
//store index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = () => new Vuex.Store({
state: {
columns1: [
{
title: '標(biāo)題',
key: 'title'
},
{
title: '介紹',
key: 'intro'
},
{
title: '日期',
key: 'time'
}
],
data1: [],
user: 'xu' //如果為空越驻,則會(huì)中間件控制跳轉(zhuǎn)404
},
mutations: {
SET_LIST: (state, data) => {
state.data1 = data
},
}
})
export default store
這里通過(guò)fetch刷新了vuex的數(shù)據(jù),頁(yè)面映射了store的數(shù)據(jù)道偷,這種寫法我們可以通過(guò)this.xxx 處理vuex的數(shù)據(jù)缀旁。demo為了快捷只用了index演示,常規(guī)項(xiàng)目我們應(yīng)該采用模塊寫法勺鸦。
權(quán)限配置(高級(jí)-路由鑒權(quán))
還是關(guān)于session 和 登錄相關(guān)的一些權(quán)限問(wèn)題并巍,官方高級(jí)文檔有非常詳細(xì)的例子。這里就不在demo里再現(xiàn)了换途。路由鑒權(quán)
對(duì)vuex管理數(shù)據(jù)有興趣的同學(xué)懊渡, 可以多看看vuex狀態(tài)樹 和權(quán)限相關(guān)的文章或者應(yīng)用,當(dāng)然官方文檔是要爛熟于心的军拟。
后臺(tái)開發(fā)以及項(xiàng)目部署
后臺(tái)開發(fā)一般就是在項(xiàng)目下在建立一個(gè)server文件夾剃执,做到同時(shí)輸出API和頁(yè)面,我們可以選擇自己喜歡的服務(wù)框架 懈息,比如express活著koa肾档,將nuxt 介入到服務(wù)框架來(lái),就可以完成所謂的同構(gòu)開發(fā)辫继∨可以看看一個(gè)koa例子:
import Koa from 'koa'
import Nuxt from 'nuxt'
import nuxtConf from '../nuxt.config'
const app = new Koa()
const start = async () => {
let config = require('../nuxt.config.js')
config.dev = !(app.env === 'production')
const nuxt = await new Nuxt(config)
if (conf.env !== 'production') {
try {
await nuxt.build()
} catch (e) {
console.error(e)
process.exit(1)
}
}
app.use(async (ctx, next) => {
ctx.status = 200
await nuxt.render(ctx.req, ctx.res)
})
app.listen(conf.port, conf.host)
console.log('Server listening on ' + conf.host + ':' + conf.port) // eslint-disable-line no-console
}
start()
nuxt自身提供了一個(gè)部署命令,可以通過(guò) npm run start 來(lái)運(yùn)行姑宽,nuxt還能生成靜態(tài)頁(yè)遣耍,你可以在在別的地方托管你的網(wǎng)站,比如Githubpage和cdn低千。喜歡同一管理上線的項(xiàng)目的同學(xué)配阵,推薦用pm2 來(lái)進(jìn)行部署馏颂。
一臺(tái)機(jī)器,好幾個(gè)項(xiàng)目棋傍,就可以用nginx來(lái)進(jìn)行反向代理端口救拉。nginx也算是上線必不可少的一步,有空我也會(huì)寫一篇實(shí)踐文章瘫拣。
官方也有提供服務(wù)框架版本亿絮,比如express https://github.com/nuxt-community/express-template ,還有其他的可以自行Github??
后記
nuxt的學(xué)習(xí)曲線非常小麸拄,就像vue框架一樣派昧,已經(jīng)是一個(gè)開箱即用的狀態(tài),我們可以直接跨過(guò)配置直接開發(fā)拢切。對(duì)配置有興趣的可以在vue官方文檔找到ssr渲染文檔蒂萎。
本來(lái)是想寫nuxt + koa + mongodb 的全棧式應(yīng)用文章的,但是最近比較忙淮椰,這個(gè)計(jì)劃只能擱置了五慈。有些方法和好用的東西我我也是最近才學(xué)習(xí),覺(jué)得不錯(cuò)在文章里做一個(gè)分享和記錄主穗。來(lái)源的話是慕課網(wǎng)Scott老師的《開發(fā)微信全家桶項(xiàng)目 Vue/Node/MongoDB高級(jí)技術(shù)棧全覆蓋》視頻教程泻拦,課程級(jí)別為高級(jí),有些地方我自己也是云里霧里忽媒,比如API分層争拐,控制器。晦雨。不過(guò)最讓人頭疼的還是微信那一堆認(rèn)證架曹。。金赦。音瓷。
整個(gè)nuxt的簡(jiǎn)單demo我都放在了Github ,對(duì)上面的scott老師的視頻教程有興趣的同學(xué)夹抗,也可以在Github找到源碼绳慎。demo多實(shí)踐,工作少踩坑漠烧,小公司現(xiàn)在最讓我開心的估計(jì)是自主開發(fā)了杏愤,公司項(xiàng)目我可以自己選擇使用什么技術(shù)。想怎么寫怎么寫已脓,可以申請(qǐng)整個(gè)開發(fā)項(xiàng)目珊楼,自己開發(fā)頁(yè)面,服務(wù)器度液,數(shù)據(jù)庫(kù)厕宗,心大的可以用rn開發(fā)app画舌。。已慢。相應(yīng)的這鍋也要背好曲聂,有壓力有動(dòng)力嘛,寫代碼這么愉快的事對(duì)吧~
傳送門: Nuxt示例代碼
如果覺(jué)得本文對(duì)你有所幫助佑惠,就star一下吧~大傳送之術(shù)朋腋! 我的博客Github