Nuxt爬坑
第一節(jié):nuxt.js相關(guān)概述
nuxt.js簡單的說是Vue.js的通用框架浇垦,最常用的就是用來作SSR(服務(wù)器端渲染).Vue.js是開發(fā)SPA(單頁應(yīng)用)的,Nuxt.js這個(gè)框架肮蛹,用Vue開發(fā)多頁應(yīng)用条舔,并在服務(wù)端完成渲染,可以直接用命令把我們制作的vue項(xiàng)目生成為靜態(tài)html。
1.那服務(wù)器端渲染到底有什么好處呢?
主要的原因時(shí)SPA(單頁應(yīng)用)不利于搜索引擎的SEO操作,Nuxt.js適合作新聞挨稿、博客、電影京痢、咨詢這樣的需要搜索引擎提供流量的項(xiàng)目叶组。如果你要作移動(dòng)端的項(xiàng)目,就沒必要使用這個(gè)框架了历造。
2.什么是SSR甩十?
在認(rèn)識(shí)SSR之前,首先對(duì)CSR與SSR之間做個(gè)對(duì)比吭产。
首先看一下傳統(tǒng)的web開發(fā)侣监,傳統(tǒng)的web開發(fā)是,客戶端向服務(wù)端發(fā)送請(qǐng)求臣淤,服務(wù)端查詢數(shù)據(jù)庫橄霉,拼接HTML字符串(模板),通過一系列的數(shù)據(jù)處理之后邑蒋,把整理好的HTML返回給客戶端,瀏覽器相當(dāng)于打開了一個(gè)頁面姓蜂。這種比如我們經(jīng)常聽說過的jsp,PHP,aspx也就是傳統(tǒng)的MVC的開發(fā)。
SPA應(yīng)用医吊,到了Vue钱慢、React,單頁面應(yīng)用優(yōu)秀的用戶體驗(yàn)卿堂,逐漸成為了主流束莫,頁面整體式j(luò)avaScript渲染出來的懒棉,稱之為客戶端渲染CSR。SPA渲染過程览绿。由客戶端訪問URL發(fā)送請(qǐng)求到服務(wù)端策严,返回HTML結(jié)構(gòu)(但是SPA的返回的HTML結(jié)構(gòu)是非常的小的,只有一個(gè)基本的結(jié)構(gòu)饿敲,如第一段代碼所示)妻导。客戶端接收到返回結(jié)果之后怀各,在客戶端開始渲染HTML栗竖,渲染時(shí)執(zhí)行對(duì)應(yīng)javaScript,最后渲染template渠啤,渲染完成之后,再次向服務(wù)端發(fā)送數(shù)據(jù)請(qǐng)求添吗,注意這里時(shí)數(shù)據(jù)請(qǐng)求沥曹,服務(wù)端返回json格式數(shù)據(jù)〉客戶端接收數(shù)據(jù)妓美,然后完成最終渲染。
SPA雖然給服務(wù)器減輕了壓力鲤孵,但是也是有缺點(diǎn)的:
首屏渲染時(shí)間比較長:必須等待JavaScript加載完畢壶栋,并且執(zhí)行完畢,才能渲染出首屏普监。
SEO不友好:爬蟲只能拿到一個(gè)div元素贵试,認(rèn)為頁面是空的,不利于SEO凯正。
為了解決如上兩個(gè)問題毙玻,出現(xiàn)了SSR解決方案,后端渲染出首屏的DOM結(jié)構(gòu)返回廊散,前端拿到內(nèi)容帶上首屏桑滩,后續(xù)的頁面操作,再用單頁面路由和渲染允睹,稱之為服務(wù)端渲染(SSR)运准。
SSR渲染流程是這樣的,客戶端發(fā)送URL請(qǐng)求到服務(wù)端缭受,服務(wù)端讀取對(duì)應(yīng)的url的模板信息胁澳,在服務(wù)端做出html和數(shù)據(jù)的渲染,渲染完成之后返回html結(jié)構(gòu)米者,客戶端這時(shí)拿到的之后首屏頁面的html結(jié)構(gòu)听哭。所以用戶在瀏覽首屏的時(shí)候速度會(huì)很快,因?yàn)榭蛻舳瞬恍枰俅伟l(fā)送ajax請(qǐng)求。并不是做了SSR我們的頁面就不屬于SPA應(yīng)用了陆盘,它仍然是一個(gè)獨(dú)立的spa應(yīng)用普筹。
SSR是處于CSR與SPA應(yīng)用之間的一個(gè)折中的方案,在渲染首屏的時(shí)候在服務(wù)端做出了渲染隘马,注意僅僅是首屏太防,其他頁面還是需要在客戶端渲染的陈肛,在服務(wù)端接收到請(qǐng)求之后并且渲染出首屏頁面营曼,會(huì)攜帶著剩余的路由信息預(yù)留給客戶端去渲染其他路由的頁面涧黄。
Nuxt.js是特點(diǎn)(優(yōu)點(diǎn)):
基于Vue
自動(dòng)代碼分層
服務(wù)端渲染
強(qiáng)大的路由功能遇八,支持異步數(shù)據(jù)
靜態(tài)文件服務(wù)
EcmaScript6和EcmaScript7的語法支持
打包和壓縮JavaScript和Css
HTML頭部標(biāo)簽管理
本地開發(fā)支持熱加載
集成ESLint
支持各種樣式預(yù)編譯器SASS宰睡、LESS等等
支持HTTP/2推送
第二節(jié):Nuxt環(huán)境搭建
1.nuxt.js安裝
在使用npm前你需要安裝Node到系統(tǒng)中锋恬。若沒有安裝參考此鏈接?www.cnblogs.com/zhouyu2017/…
(1)用npm來安裝vue-cli這個(gè)框架挺狰。
npm install vue-cli -g復(fù)制代碼
安裝完成后可以使用vue -V 來測試是否安裝成功政敢。(注意:這里要使用大寫的V邀泉,小寫無效)嬉挡。
(2)使用vue安裝 nuxt
安裝好vue-cli后,就可以使用init命令來初始化Nuxt.js項(xiàng)目汇恤。
vue init nuxt/starter復(fù)制代碼
這時(shí)候他會(huì)在github上下載模版庞钢,然后會(huì)詢問你項(xiàng)目的名稱叫什么,作者什么的因谎,這些完全可以根據(jù)自己的愛好填寫基括。
(3)使用npm install安裝依賴包
npm install復(fù)制代碼
這個(gè)過程是要等一會(huì)的,如果你這個(gè)過程安裝失敗财岔,可以直接誒刪除項(xiàng)目中的node_modules文件夾后风皿,重新npm install進(jìn)行安裝。
(4)使用npm run dev 啟動(dòng)服務(wù)
(5)在瀏覽器輸入 localhost:3000,可以看到結(jié)果,如下:
2.第一個(gè)Nuxt應(yīng)用程序安裝
npm i create-nuxt-app -gcreate-nuxt-app my-nuxt-democdmy-nuxt-demonpm run dev復(fù)制代碼
安裝向?qū)В?/p>
Project name? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //? 項(xiàng)目名稱Project description? ? ? ? ? ? ? ? ? ? ? ? //? 項(xiàng)目描述Use a custom server framework? ? ? ? ? ? ? //? 選擇服務(wù)器框架Choose features to install? ? ? ? ? ? ? ? ? //? 選擇安裝的特性Use a custom UI framework? ? ? ? ? ? ? ? ? //? 選擇UI框架Use a customtestframework? ? ? ? ? ? ? ? //? 測試框架Choose rendering mode? ? ? ? ? ? ? ? ? ? ? //? 渲染模式Universal? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //? 渲染所有連接頁面Single Page App? ? ? ? ? ? ? ? ? ? ? ? ? ? //? 只渲染當(dāng)前頁面復(fù)制代碼
3.Nuxt 渲染流程
一個(gè)完整的服務(wù)器請(qǐng)求到渲染的流程
通過上面的流程圖可以看出匠璧,當(dāng)一個(gè)客戶端請(qǐng)求進(jìn)入的時(shí)候揪阶,服務(wù)端有通過nuxtServerInit這個(gè)命令執(zhí)行在Store的action中,在這里接收到客戶端請(qǐng)求的時(shí)候患朱,可以將一些客戶端信息存儲(chǔ)到Store中鲁僚,也就是說可以把在服務(wù)端存儲(chǔ)的一些客戶端的一些登錄信息存儲(chǔ)到Store中。之后使用了中間件機(jī)制裁厅,中間件其實(shí)就是一個(gè)函數(shù)冰沙,會(huì)在每個(gè)路由執(zhí)行之前去執(zhí)行,在這里可以做很多事情执虹,或者說可以理解為是路由器的攔截器的作用拓挥。然后再validate執(zhí)行的時(shí)候?qū)蛻舳藬y帶的參數(shù)進(jìn)行校驗(yàn),在asyncData與fetch進(jìn)入正式的渲染周期袋励,asyncData向服務(wù)端獲取數(shù)據(jù)侥啤,把請(qǐng)求到的數(shù)據(jù)合并到Vue中的data中当叭,
第三節(jié) :Nuxt目錄結(jié)構(gòu)
# 目錄結(jié)構(gòu)介紹
└─my-nuxt-demo? ├─.nuxt? ? ? ? ? ? ? // Nuxt自動(dòng)生成,臨時(shí)的用于編輯的文件盖灸,build? ├─assets? ? ? ? ? ? ? // 用于組織未編譯的靜態(tài)資源如LESS蚁鳖、SASS或JavaScript,對(duì)于不需要通過 Webpack 處理的靜態(tài)資源文件,可以放置在 static 目錄中? ├─components? ? ? ? ? // 用于自己編寫的Vue組件赁炎,比如日歷組件醉箕、分頁組件? ├─layouts? ? ? ? ? ? // 布局目錄,用于組織應(yīng)用的布局組件徙垫,不可更改?? ├─middleware? ? ? ? ? // 用于存放中間件? ├─node_modules? ├─pages? ? ? ? ? ? ? // 用于組織應(yīng)用的路由及視圖,Nuxt.js根據(jù)該目錄結(jié)構(gòu)自動(dòng)生成對(duì)應(yīng)的路由配置讥裤,文件名不可更改?? ├─plugins? ? ? ? ? ? // 用于組織那些需要在 根vue.js應(yīng)用 實(shí)例化之前需要運(yùn)行的 Javascript 插件。? ├─static? ? ? ? ? ? ? // 用于存放應(yīng)用的靜態(tài)文件姻报,此類文件不會(huì)被 Nuxt.js 調(diào)用 Webpack 進(jìn)行構(gòu)建編譯處理己英。 服務(wù)器啟動(dòng)的時(shí)候,該目錄下的文件會(huì)映射至應(yīng)用的根路徑 / 下吴旋。文件夾名不可更改损肛。?? └─store? ? ? ? ? ? ? // 用于組織應(yīng)用的Vuex 狀態(tài)管理。文件夾名不可更改邮府。?? ├─.editorconfig? ? ? // 開發(fā)工具格式配置? ├─.eslintrc.js? ? ? ? // ESLint的配置文件,用于檢查代碼格式? ├─.gitignore? ? ? ? ? // 配置git忽略文件? ├─nuxt.config.js? ? ? // 用于組織Nuxt.js 應(yīng)用的個(gè)性化配置溉奕,以便覆蓋默認(rèn)配置褂傀。文件名不可更改。?? ├─package-lock.json? // npm自動(dòng)生成加勤,用于幫助package的統(tǒng)一設(shè)置的仙辟,yarn也有相同的操作? ├─package.json? ? ? ? // npm 包管理配置文件? ├─README.md復(fù)制代碼
# 配置文件
const pkg = require('./package')module.exports = {? mode:'universal',? ? //? 當(dāng)前渲染使用模式? head: {? ? ? //? 頁面head配置信息? ? title: pkg.name,? ? ? ? //? title? ? meta: [? ? ? ? //? meat? ? ? { charset:'utf-8'},? ? ? { name:'viewport', content:'width=device-width, initial-scale=1'},? ? ? { hid:'description', name:'description', content: pkg.description }? ? ],? ? link: [? ? //? favicon,若引用css不會(huì)進(jìn)行打包處理? ? ? { rel:'icon',type:'image/x-icon', href:'/favicon.ico'}? ? ]? },? loading: { color:'#fff'},? //? 頁面進(jìn)度條? css: [? ? //? 全局css(會(huì)進(jìn)行webpack打包處理)'element-ui/lib/theme-chalk/index.css'],? plugins: [? ? ? ? //? 插件'@/plugins/element-ui'],? modules: [? ? ? ? //? 模塊'@nuxtjs/axios',? ],? axios: {},? build: {? ? ? //? 打包? ? transpile: [/^element-ui/],? ? extend(config, ctx) {? ? ? //? webpack自定義配置? ? }? }}復(fù)制代碼
# Nuxt運(yùn)行命令
{"scripts": {? ? //? 開發(fā)環(huán)境"dev":"cross-env NODE_ENV=development nodemon server/index.js --watch server",? ? //? 打包"build":"nuxt build",? ? //? 在服務(wù)端運(yùn)行"start":"cross-env NODE_ENV=production node server/index.js",? ? //? 生成靜態(tài)頁面"generate":"nuxt generate"}}復(fù)制代碼
第四節(jié):Nuxt常用配置項(xiàng)
1.配置IP和端口
開發(fā)中經(jīng)常會(huì)遇到端口被占用或者指定IP的情況鳄梅。我們需要在根目錄下的package.json里對(duì)config項(xiàng)進(jìn)行配置叠国。比如現(xiàn)在我們想把IP配置成127.0.0.1,端口設(shè)置1000戴尸。
/package.json
"config":{? ? "nuxt":{? ? ? "host":"127.0.0.1",? ? ? "port":"1000"? ? }? },復(fù)制代碼
配置好后粟焊,我們在終端中輸入npm run dev,然后你會(huì)看到服務(wù)地址改為了127.0.0.1:1000.
2.配置全局CSS
在開發(fā)多頁項(xiàng)目時(shí)孙蒙,都會(huì)定義一個(gè)全局的CSS來初始化我們的頁面渲染项棠,比如把padding和margin設(shè)置成0,網(wǎng)上也有非常出名的開源css文件normailze.css挎峦。要定義這些配置香追,需要在nuxt.config.js里進(jìn)行操作。
比如現(xiàn)在我們要把頁面字體設(shè)置為紅色坦胶,就可以在assets/css/common.css文件透典,然后把字體設(shè)置為紅色晴楔。
/assets/css/common.css
html{? ? color:red;}復(fù)制代碼
/nuxt.config.js
css:['~assets/css/normailze.css'],復(fù)制代碼
設(shè)置好后,在終端輸入npm run dev 峭咒。然后你會(huì)發(fā)現(xiàn)字體已經(jīng)變成了紅色税弃。
3.配置webpack的loader
在nuxt.config.js里是可以對(duì)webpack的基本配置進(jìn)行覆蓋的,比如現(xiàn)在我們要配置一個(gè)url-loader來進(jìn)行小圖片的64位打包讹语。就可以在nuxt.config.js的build選項(xiàng)里進(jìn)行配置,相關(guān)可參照此鏈接www.cnblogs.com/ssh-007/p/7…
build: {? ? loaders:[? ? ? {? ? ? ? test:/\.(png|jpe?g|gif|svg)$/,? ? ? ? loader:"url-loader",? ? ? ? query:{? ? ? ? ? limit:10000,? ? ? ? ? name:'img/[name].[hash].[ext]'? ? ? ? }? ? ? }? ? ],? ? /*? ? ** Run ESLint on save? ? */? ? extend (config, { isDev, isClient }) {? ? ? if (isDev && isClient) {? ? ? ? config.module.rules.push({? ? ? ? ? enforce: 'pre',? ? ? ? ? test: /\.(js|vue)$/,? ? ? ? ? loader: 'eslint-loader',? ? ? ? ? exclude: /(node_modules)/? ? ? ? })? ? ? }? ? }? }復(fù)制代碼
4.全局修改seo的head信息
nuxt.config.js文件中,修改title為wfaceboss:
head: {? ? title: 'wfaceboss',? ? meta: [? ? ? { charset: 'utf-8' },? ? ? { name: 'viewport', content: 'width=device-width, initial-scale=1' },? ? ? { hid: 'description', name: 'description', content: 'Nuxt.js project' }? ? ],? ? link: [? ? ? { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }? ? ]? },復(fù)制代碼
修改后重啟服務(wù)钙皮,即運(yùn)行 npm run dev,效果如下
第五節(jié):Nuxt的路由配置和參數(shù)傳遞
Nuxt.js的路由并不復(fù)雜,它給我們進(jìn)行了封裝顽决,讓我們節(jié)省了很多配置環(huán)節(jié)短条。
1.基本路由
Nuxt.js 依據(jù)?pages?目錄結(jié)構(gòu)自動(dòng)生成 vue-router 模塊的路由配置。
假設(shè)?pages?的目錄結(jié)構(gòu)如下
└─pages? ? ├─index.vue? ? └─user? ? ? ├─index.vue? ? ? ├─one.vue復(fù)制代碼
那么才菠,Nuxt.js 自動(dòng)生成的路由配置如下:
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'}? ]}復(fù)制代碼
2.頁面跳轉(zhuǎn)
不要寫成a標(biāo)簽茸时,因?yàn)槭侵匦芦@取一個(gè)新的頁面,并不是SPA
<nuxt-link to="/users"></nuxt-link>
this.$router.push('/users')
3.動(dòng)態(tài)路由
在 Nuxt.js 里面定義帶參數(shù)的動(dòng)態(tài)路由赋访,需要?jiǎng)?chuàng)建對(duì)應(yīng)的以下劃線作為前綴的 Vue 文件 或 目錄可都。
獲取動(dòng)態(tài)參數(shù){{$route.params.id}}
4.跳轉(zhuǎn)路由傳遞參數(shù)并且取值
路由經(jīng)常需要傳遞參數(shù),我們可以簡單的使用params來進(jìn)行傳遞參數(shù)蚓耽,我們現(xiàn)在向新聞頁面(news)傳遞個(gè)參數(shù)渠牲,然后在新聞頁面進(jìn)行簡單的接收。
(1)使用nuxt傳遞參數(shù)
注意:name其實(shí)指向的是路由(文件夾或文件名)步悠,而路由死活區(qū)分大小寫的 签杈, 所以to后面區(qū)分大小寫!6κ蕖答姥!建議文件夾都寫成小寫的。
(2)使用nuxt接收參數(shù)
async asyncData(context) {letnewsCode = context.route.params.code.split('-')[0]letnewsType = context.route.params.code.split('-')[1]},復(fù)制代碼
(3)使用this.$router.push的params傳遞參數(shù)
傳遞參數(shù)? -- this.$router.push({path: ' 路由 ', query: {key: value}})參數(shù)取值? -- this.$route.query.key注: 使用這種方式谚咬,傳遞參數(shù)會(huì)拼接在路由后面鹦付,出現(xiàn)在地址欄復(fù)制代碼
(4)使用this.$router.push的params傳遞參數(shù)
傳遞參數(shù)? -- this.$router.push({name:' 路由的name ', params: {key: value}})參數(shù)取值? -- this.$route.params.key注: 使用這種方式,參數(shù)不會(huì)拼接在路由后面择卦,地址欄上看不到參數(shù)注意: 由于動(dòng)態(tài)路由也是傳遞params的敲长,所以在 this.$router.push() 方法中 path不能和params一起使用,否則params將無效秉继。需要用name來指定頁面潘明。復(fù)制代碼
4.項(xiàng)目需求url優(yōu)化
this.$route.query.key的方式參數(shù)顯示在地址欄上, 但是并不是我們想要的, :id?id=``?
所以建議還是盡量使用router-link來實(shí)現(xiàn)跳轉(zhuǎn)來解決地址欄的變化,更方便網(wǎng)站的優(yōu)化
5.路由參數(shù)校驗(yàn)
Nuxt.js 可以讓你在動(dòng)態(tài)路由對(duì)應(yīng)的頁面組件中配置一個(gè)validate方法用于校驗(yàn)動(dòng)態(tài)路由參數(shù)的有效性。該函數(shù)有一個(gè)布爾類型的返回值秕噪,如果返回true則表示校驗(yàn)通過钳降,如果返回false則表示校驗(yàn)未通過。
exportdefault{// nuxt中使用validate方法進(jìn)行路由參數(shù)校驗(yàn)腌巾,這個(gè)方法必須返回一個(gè)布爾值遂填,為true表示校驗(yàn)通過铲觉,為false表示校驗(yàn)失敗。注意validate不能寫到methods屬性中吓坚。validate(obj) {// console.log(obj);// return truereturn/^\d+$/.test(obj.params.id)? }}復(fù)制代碼
6.嵌套路由
添加一個(gè)Vue文件撵幽,作為父組件
添加一個(gè)與父組件同名的文件夾來存放子視圖組件
在父文件中,添加組件礁击,用于展示匹配到的子視圖
第六節(jié):Nuxt的路由動(dòng)畫效果
路由的動(dòng)畫效果盐杂,也叫作頁面的更換效果。Nuxt.js提供兩種方法為路由提供動(dòng)畫效果哆窿,一種是全局的链烈,一種是針對(duì)單獨(dú)頁面制作。
1.全局路由動(dòng)畫
全局動(dòng)畫默認(rèn)使用page來進(jìn)行設(shè)置挚躯,例如現(xiàn)在我們?yōu)槊總€(gè)頁面都設(shè)置一個(gè)進(jìn)入和退出時(shí)的漸隱漸現(xiàn)的效果强衡。我們可以先在根目錄的assets/css下建立一個(gè)normailze.css文件。
(1)添加樣式文件
/assets/css/normailze.css(沒有請(qǐng)自行建立)
.page-enter-active, .page-leave-active {? ? transition: opacity 2s;}.page-enter, .page-leave-active {? ? opacity: 0;}復(fù)制代碼
(2)文件配置
然后在nuxt.config.js里加入一個(gè)全局的css文件就可以了码荔。
css:['assets/css/main.css'],復(fù)制代碼
這時(shí)候在頁面切換的時(shí)候就會(huì)有2秒鐘的動(dòng)畫切換效果了漩勤,但是你會(huì)發(fā)現(xiàn)一些頁面是沒有效果的,這是因?yàn)槟銢]有是<nuxt-link>組件來制作跳轉(zhuǎn)鏈接缩搅。你需要進(jìn)行更改越败。
比如我們上節(jié)課作的動(dòng)態(tài)路由新聞頁,你就需要改成下面的鏈接硼瓣。
改過之后你就會(huì)看到動(dòng)畫效果了究飞。
2.單獨(dú)設(shè)置頁面動(dòng)效
想給一個(gè)頁面單獨(dú)設(shè)置特殊的效果時(shí),我們只要在css里改變默認(rèn)的page巨双,然后在頁面組件的配置中加入transition字段即可噪猾。例如霉祸,我們想給about頁面加入一個(gè)字體放大然后縮小的效果筑累,其他頁面沒有這個(gè)效果。
(1)在全局樣式assets/main.css 中添加以下內(nèi)容
.test-enter-active, .test-leave-active {? ? transition: all 2s;? ? font-size:12px;}.test-enter, .test-leave-active {? ? opacity: 0;? ? font-size:40px;}復(fù)制代碼
(2)然后在about/index.vue組件中設(shè)置
export default {? transition:'test'}復(fù)制代碼
這時(shí)候就有了頁面的切換獨(dú)特動(dòng)效了丝蹭。
總結(jié):在需要使用的頁面導(dǎo)入即可慢宗。
第七節(jié):Nuxt的默認(rèn)模版和默認(rèn)布局
在開發(fā)應(yīng)用時(shí),經(jīng)常會(huì)用到一些公用的元素奔穿,比如網(wǎng)頁的標(biāo)題是一樣的镜沽,每個(gè)頁面都是一模一樣的標(biāo)題。這時(shí)候我們有兩種方法贱田,第一種方法是作一個(gè)公用的組件出來缅茉,第二種方法是修改默認(rèn)模版。這兩種方法各有利弊男摧,比如公用組件更加靈活蔬墩,但是每次都需要自己手動(dòng)引入译打;模版比較方便,但是只能每個(gè)頁面都引入拇颅。
1.默認(rèn)模板
Nuxt為我們提供了超簡單的默認(rèn)模版訂制方法奏司,只要在根目錄下創(chuàng)建一個(gè)app.html就可以實(shí)現(xiàn)了∶剑現(xiàn)在我們希望每個(gè)頁面的最上邊都加入“ 學(xué)習(xí)nuxt.js” 這幾個(gè)字庸汗,我們就可以使用默認(rèn)模版來完成。
app.html中:
<!DOCTYPE html>{{ HEAD }}
學(xué)習(xí)nuxt.js
{{ APP }}復(fù)制代碼這里的{{ HEAD }}讀取的是nuxt.config.js里的信息景图,{{APP}} 就是我們寫的pages文件夾下的主體頁面了黄锤。需要注意的是HEAD和APP都需要大寫搪缨,如果小寫會(huì)報(bào)錯(cuò)的。
注意:如果你建立了默認(rèn)模板后猜扮,記得要重啟服務(wù)器勉吻,否則顯示不會(huì)成功;但是默認(rèn)布局是不用重啟服務(wù)器的旅赢。
2.默認(rèn)布局
默認(rèn)模板類似的功能還有默認(rèn)布局齿桃,但是從名字上你就可以看出來,默認(rèn)布局主要針對(duì)于頁面的統(tǒng)一布局使用煮盼。它在位置根目錄下的layouts/default.vue短纵。需要注意的是在默認(rèn)布局里不要加入頭部信息,只是關(guān)于<template>標(biāo)簽下的內(nèi)容統(tǒng)一訂制僵控。
需求:我們在每個(gè)頁面的最頂部放入“學(xué)習(xí)nuxt.js” 這幾個(gè)字香到,看一下在默認(rèn)布局里的實(shí)現(xiàn)。
學(xué)習(xí)nuxt.js
這里的<nuxt/>就相當(dāng)于我們每個(gè)頁面的內(nèi)容报破,你也可以把一些通用樣式放入這個(gè)默認(rèn)布局里悠就,但會(huì)增加頁面的復(fù)雜程度。
總結(jié):要區(qū)分默認(rèn)模版和默認(rèn)布局的區(qū)別充易,模版可以訂制很多頭部信息梗脾,包括IE版本的判斷;模版只能定制<template>里的內(nèi)容盹靴,跟布局有關(guān)系炸茧。在工作中修改時(shí)要看情況來編寫代碼。
第八節(jié):Nuxt插件的使用
1.ElementUI使用
下載npm i element-ui -S
在plugins文件夾下面稿静,創(chuàng)建ElementUI.js文件
importVuefrom'vue'importElementUIfrom'element-ui'Vue.use(ElementUI)復(fù)制代碼
在nuxt.config.js中添加配置
css: [? 'element-ui/lib/theme-chalk/index.css'],plugins: [? {src: '~/plugins/ElementUI', ssr: true }],build: {? vendor: ['element-ui']}復(fù)制代碼
2.axios的使用
安裝npm install --save axios
使用
importaxiosfrom'axios'asyncData(context, callback) {? axios.get('http://localhost:3301/in_theaters')? ? .then(res=>{console.log(res);? ? ? callback(null, {list: res.data})? ? })}復(fù)制代碼
為防止重復(fù)打包梭冠,在nuxt.config.js中配置
module.exports = {? build: {? ? vendor: ['axios']? }}復(fù)制代碼
第九節(jié):Nuxt的錯(cuò)誤頁面和個(gè)性meta設(shè)置
當(dāng)用戶輸入路由錯(cuò)誤的時(shí)候,我們需要給他一個(gè)明確的指引改备,所以說在應(yīng)用程序開發(fā)中404頁面是必不可少的控漠。Nuxt.js支持直接在默認(rèn)布局文件夾里建立錯(cuò)誤頁面。
1.建立錯(cuò)誤頁面
在根目錄下的layouts文件夾下建立一個(gè)error.vue文件悬钳,它相當(dāng)于一個(gè)顯示應(yīng)用錯(cuò)誤的組件盐捷。
- HOME
代碼用v-if進(jìn)行判斷錯(cuò)誤類型柬脸,需要注意的是這個(gè)錯(cuò)誤是你需要在<script>里進(jìn)行聲明的,如果不聲明程序是找不到error.statusCode的毙驯。
這里我也用了一個(gè)<nuxt-link>的簡單寫法直接跟上路徑就可以了倒堕。
2.個(gè)性meta設(shè)置
頁面的Meta對(duì)于SEO的設(shè)置非常重要,比如你現(xiàn)在要作個(gè)新聞頁面爆价,那為了搜索引擎對(duì)新聞的收錄垦巴,需要每個(gè)頁面對(duì)新聞都有不同的title和meta設(shè)置。直接使用head方法來設(shè)置當(dāng)前頁面的頭部信息就可以了铭段。我們現(xiàn)在要把New-1這個(gè)頁面設(shè)置成個(gè)性的meta和title骤宣。
1.我們先把pages/news/index.vue頁面的鏈接進(jìn)行修改一下,傳入一個(gè)title序愚,目的是為了在新聞具體頁面進(jìn)行接收title憔披,形成文章的標(biāo)題。
/pages/news/index.vue
2.第一步完成后爸吮,我們修改/pages/news/_id.vue芬膝,讓它根據(jù)傳遞值變成獨(dú)特的meta和title標(biāo)簽。
News-Content [{{$route.params.id}}]
- Home
注意:為了避免子組件中的meta標(biāo)簽不能正確覆蓋父組件中相同的標(biāo)簽而產(chǎn)生重復(fù)的現(xiàn)象形娇,建議利用 hid 鍵為meta標(biāo)簽配一個(gè)唯一的標(biāo)識(shí)編號(hào)锰霜。
第十節(jié):asyncData方法獲取數(shù)據(jù)
Nuxt.js貼心的為我們擴(kuò)展了Vue.js的方法,增加了anyncData桐早,異步請(qǐng)求數(shù)據(jù)癣缅。
1.造假數(shù)據(jù)
(1)創(chuàng)建遠(yuǎn)程數(shù)據(jù)
在這里制作一些假的遠(yuǎn)程數(shù)據(jù),我選擇的網(wǎng)站是myjson.com哄酝,它是一個(gè)json的簡單倉庫友存,學(xué)習(xí)使用是非常適合的。 我們打開網(wǎng)站陶衅,在對(duì)話空中輸入JSON代碼屡立,這個(gè)代碼可以隨意輸入,key和value均采用字符串格式創(chuàng)建万哪。
{? "name": "Nuxt",? "age": 18,? "interest": "I love coding!"}復(fù)制代碼
輸入后保存侠驯,網(wǎng)站會(huì)給你一個(gè)地址抡秆,這就是你這個(gè)JSON倉庫的地址了奕巍。api.myjson.com/bins/1ctwlm
(2)安裝Axios
Vue.js官方推薦使用的遠(yuǎn)程數(shù)據(jù)獲取方式就Axios,所以我們安裝官方推薦儒士,來使用Axios的止。這里我們使用npm 來安裝 axios。 直接在終端中輸入下面的命令:
npm install axios --save復(fù)制代碼
2.ansycData的promise方法
我們在pages下面新建一個(gè)文件着撩,叫做ansyData.vue诅福。然后寫入下面的代碼:
importaxiosfrom'axios'exportdefault{? data(){return{name:'hello World',? ? }? },? asyncData(){returnaxios.get('https://api.myjson.com/bins/1ctwlm')? ? ? .then((res)=>{console.log(res)return{info:res.data}? ? ? })? }}復(fù)制代碼
這時(shí)候我們可以看到匾委,瀏覽器中已經(jīng)能輸出結(jié)果了。asyncData的方法會(huì)把值返回到data中氓润。是組件創(chuàng)建(頁面渲染)之前的動(dòng)作赂乐,所以不能使用this.info,
# return的重要性
一定要return出去獲取到的對(duì)象,這樣就可以在組件中使用咖气,這里返回的數(shù)據(jù)會(huì)和組件中的data合并挨措。這個(gè)函數(shù)不光在服務(wù)端會(huì)執(zhí)行,在客戶端同樣也會(huì)執(zhí)行崩溪。復(fù)制代碼
3.ansycData的promise并發(fā)應(yīng)用
async asyncData(context) {let[newDetailRes, hotInformationRes, correlationRes] = await Promise.all([? ? axios.post('http://www.huanjingwuyou.com/eia/news/detail', {? ? ? newsCode: newsCode? ? }),? ? axios.post('http://www.huanjingwuyou.com/eia/news/select', {? ? ? newsType: newsType, // 資訊類型: 3環(huán)評(píng)資訊 4環(huán)評(píng)知識(shí)? ? ? start: 0, // 從第0條開始? ? ? pageSize: 10,? ? ? newsRecommend:true}),? ? axios.post('http://www.huanjingwuyou.com/eia/news/select', {? ? ? newsType: newsType, // 資訊類型: 3環(huán)評(píng)資訊 4環(huán)評(píng)知識(shí)? ? ? start: 0, // 從第0條開始? ? ? pageSize: 3,? ? ? newsRecommend:false})? ])return{? ? newDetailList: newDetailRes.data.result,? ? hotNewList: hotInformationRes.data.result.data,? ? newsList: correlationRes.data.result.data,? ? newsCode: newsCode,? ? newsType: newsType? }},復(fù)制代碼
4.ansycData的await方法
當(dāng)然上面的方法稍顯過時(shí)浅役,現(xiàn)在都在用ansyc…await來解決異步,改寫上面的代碼。
importaxiosfrom'axios'exportdefault{? data(){return{name:'hello World',? ? }? },asyncasyncData(){let{data}=awaitaxios.get('https://api.myjson.com/bins/8gdmr')return{info: data}? }}復(fù)制代碼
5.注意事項(xiàng)+生命周期:
asyncData 方法會(huì)在組件(限于頁面組件)每次加載之前被調(diào)用
asyncData 可以在服務(wù)端或路由更新之前被調(diào)用
第一個(gè)參數(shù)被設(shè)定為當(dāng)前頁面的上下文對(duì)象
Nuxt會(huì)將 asyncData 返回的數(shù)據(jù)融合到組件的data方法返回的數(shù)據(jù)一并返回給組件使用
對(duì)于 asyncData 方式實(shí)在組件初始化前被調(diào)用的伶唯,所以在方法內(nèi)飾沒辦法通過this來引用組件的實(shí)例對(duì)象
第十一節(jié):靜態(tài)資源和打包
1.靜態(tài)資源
(1)直接引入圖片在網(wǎng)上任意下載一個(gè)圖片觉既,放到項(xiàng)目中的static文件夾下面,然后可以使用下面的引入方法進(jìn)行引用
復(fù)制代碼“~”就相當(dāng)于定位到了項(xiàng)目根目錄乳幸,這時(shí)候圖片路徑就不會(huì)出現(xiàn)錯(cuò)誤瞪讼,就算打包也是正常的。
(2)CSS引入圖片如果在CSS中引入圖片粹断,方法和html中直接引入是一樣的尝艘,也是用“~”符號(hào)引入。復(fù)制代碼
.diss{width:300px;height:100px;background-image:url('~static/logo.png')? }復(fù)制代碼
這時(shí)候在npm run dev 下是完全正常的姿染。
2.打包
用Nuxt.js制作完成后背亥,你可以打包成靜態(tài)文件并放在服務(wù)器上,進(jìn)行運(yùn)行悬赏。
在終端中輸入:
npm run generate復(fù)制代碼
然后在dist文件夾下輸入live-server就可以了狡汉。
總結(jié):Nuxt.js框架非常簡單,因?yàn)榇蟛糠值氖虑樗紴槲覀冏龊昧嗣銎模覀冎灰惭b它的規(guī)則來編寫代碼盾戴。
第十二節(jié):nuxt的跨域解決+攔截器
安裝axios
npm install @nuxtjs/axios --save-dev復(fù)制代碼
安裝完成后更改配置信息:
nuxt.config.js
module.exports = {? ? modules: [? ? ? ? // Doc: https://axios.nuxtjs.org/usage'@nuxtjs/axios',? ? ],? ? axios: {? ? ? ? proxy:true//? 代理? ? },? ? axios: {? ? ? ? proxy:true,? ? ? ? prefix:'/api', // baseURL? ? ? ? credentials:true,? ? },? ? proxy: {"/eia/":"http://192.168.0.97:8181/",? ? //? key(路由前綴):value(代理地址)? ? ? ? changeOrigin:true, // 是否跨域? ? ? ? pathRewrite: {'^/api':''//路徑重寫? ? ? ? }? ? }}復(fù)制代碼
既然說到了axios,就不得不提到的一個(gè)東西就是攔截器兵多,很是有用在項(xiàng)目開發(fā)過程中必不可少的尖啡。
舉個(gè)例子:
安裝
npm install @nuxtjs/axios @nuxtjs/proxy --save復(fù)制代碼
module.expores{? plugins: [? ? {? ? ? src:"~/plugins/axios",? ? ? ssr:false},? ],? modules: [? ? // Doc: https://axios.nuxtjs.org/usage'@nuxtjs/axios',? ],}復(fù)制代碼
plugins/axios.js
exportdefault ({$axios, redirect }) => {$axios.onRequest(config => {? ? console.log('Making request to '+ config.url)? })$axios.onError(error => {? ? const code = parseInt(error.response && error.response.status)if(code === 400) {? ? ? redirect('/400')? ? }? })}exportdefaultfunction(app) {letaxios = app.$axios;? // 基本配置? axios.defaults.timeout = 10000? axios.defaults.headers.post['Content-Type'] ='application/x-www-form-urlencoded'// 請(qǐng)求回調(diào)? axios.onRequest(config => {})? // 返回回調(diào)? axios.onResponse(res => {})? // 錯(cuò)誤回調(diào)? axios.onError(error => {})}復(fù)制代碼
第十三節(jié):爬坑
1.NuxtServerError connect ECONNREFUSED 127.0.0.1:80
原因: asyncData方法異步請(qǐng)求數(shù)據(jù)時(shí),以為/api/${params.id}這個(gè)接口的網(wǎng)址是?127.0.0.1:80, 所以將請(qǐng)求發(fā)送給了127.0.0.1:80剩膘,而我的接口服務(wù)器并沒有跑在80端口上衅斩,所以報(bào)錯(cuò)。
解決方法:
將node服務(wù)器端口改成?127.0.0.1:80
將接口服務(wù)器端口改成?127.0.0.1:80
將asyncData方法使用的請(qǐng)求url加上域名+端口怠褐,如下所示畏梆、
exportdefault {? asyncData ({ params }) {returnaxios.get(`https://127.0.0.1:3000/api/${params.id}`)? ? .then((res) => {return{ title: res.data.title }? ? })? }}復(fù)制代碼
1. 如何在 head 里面引入js文件?
背景: 在<head>標(biāo)簽中,以inline的形式引入flexible.js文件。本項(xiàng)目主要為移動(dòng)端項(xiàng)目奠涌,引入flexible.js?實(shí)現(xiàn)移動(dòng)端適配問題宪巨。
Nuxt.js 通過?vue-meta?實(shí)現(xiàn)頭部標(biāo)簽管理,通過查看文檔發(fā)現(xiàn)溜畅,可以按照如下方式配置:
head: {? script: [{ innerHTML: require('./assets/js/flexible'),type:'text/javascript', charset:'utf-8'}],? __dangerouslyDisableSanitizers: ['script']}復(fù)制代碼
2.nuxt使用less,sass等預(yù)處理器
背景:在組件中的<template>捏卓,?<script>?或?<style>?上使用各種預(yù)處理器,加上處理器后慈格,控制臺(tái)報(bào)錯(cuò)天吓。
npm install --save-dev node-sass sass-loader復(fù)制代碼
但是解決過程并不是很順利的,在閱讀中文文檔時(shí)峦椰,忽略版本號(hào)龄寞,按照上面的提示進(jìn)行操作,發(fā)現(xiàn)不能成功汤功,后來各種debug物邑,最后發(fā)現(xiàn)了該解決方案。后知后覺的發(fā)現(xiàn)了中文文檔的版本號(hào)過低滔金,如果需要查看文檔色解,一定要看最新版本的英文文檔!
3. 如何使用px2rem
背景:在css中餐茵,寫入px科阎,通過px2rem loader,將px轉(zhuǎn)換成rem
在以前的項(xiàng)目中忿族,是通過?px2rem loader實(shí)現(xiàn)的锣笨,但是在Nuxt.js項(xiàng)目下,添加 css loader 還是很費(fèi)力的道批,因?yàn)樯婕暗絭ue-loader错英。
想到了一個(gè)其他方案,可以使用?postcss?處理隆豹⊥盅遥可以在?nuxt.config.js?文件中添加配置,也可以在postcss.conf.js文件中添加璃赡。
build: {? postcss: [? ? require('postcss-px2rem')({? ? ? remUnit: 75 // 轉(zhuǎn)換基本單位? ? })? ]},復(fù)制代碼
4. 如何拓展 webpack 配置
背景:給 utils 目錄添加別名
剛剛說到判哥,Nuxt.js內(nèi)置了?webpack?配置,如果想要拓展配置碉考,可以在?nuxt.config.js?文件中添加塌计。同時(shí)也可以在該文件中,將配置信息打印出來豆励。
extend (config, ctx) {? console.log('webpack config:', config)if(ctx.isClient) {? ? // 添加alias配置? ? Object.assign(config.resolve.alias, {'utils': path.resolve(__dirname,'utils')? ? })? }}復(fù)制代碼
5. 如何添加 vue plugin
背景:自己封裝了一個(gè) toast vue plugin夺荒,由于 vue 實(shí)例化的過程沒有暴露出來,不知道在哪個(gè)時(shí)機(jī)注入進(jìn)去良蒸。
可以在?nuxt.config.js?中添加 plugins 配置技扼,這樣插件就會(huì)在 Nuxt.js 應(yīng)用初始化之前被加載導(dǎo)入。
module.exports = {? plugins: ['~plugins/toast']}復(fù)制代碼
~plugins/toast.js 文件:
import Vue from'vue'import toast from'../utils/toast'import'../assets/css/toast.css'Vue.use(toast)復(fù)制代碼
6.如何修改環(huán)境變量 NODE_ENV
背景:在項(xiàng)目中嫩痰,設(shè)置 3個(gè)?NODE_ENV?的值剿吻,來對(duì)應(yīng)不同的版本。development串纺,本地開發(fā)丽旅;release,預(yù)發(fā)布版本纺棺;production榄笙,線上版本。其中祷蝌,預(yù)發(fā)布版本比production版本茅撞,多出vconsole。
// package.json"scripts": {"buildDev":"cross-env NODE_ENV=release nuxt build && backpack build","startDev":"cross-env NODE_ENV=release PORT=3000 node build/main.js"},復(fù)制代碼
打印?process.env.NODE_ENV?依舊是巨朦,production米丘。
在 backpack 的源碼中,找到了答案糊啡,在 執(zhí)行?backpack build?命令時(shí)拄查,會(huì)把?process.env.NODE_ENV?修改為?production,并且是寫死的不可配置的......
無奈下棚蓄,只能在?process.env?下堕扶,添加?__ENV?屬性,代表?NODE_ENV
這時(shí)梭依,在頁面中打印出來的信息?process.env.__ENV undefined挣柬,但是可以打印出?process.env.NODE_ENV。
可以通過配置?nuxt.config.js?中的睛挚,env屬性邪蛔,解決該問題。
env: {? __ENV: process.env.__ENV}復(fù)制代碼
7. Window 或 Document 對(duì)象未定義扎狱?
背景: 在引入第三方插件侧到,或者直接在代碼中寫?window?時(shí)黔宛,控制臺(tái)會(huì)給出警告般卑,window未定義。
發(fā)生在這個(gè)問題的原因時(shí)紊遵,node服務(wù)端并沒有window?或?document?對(duì)象污抬。解決方法汞贸,通過?process.browser?來區(qū)分環(huán)境绳军。
if(process.browser) {? // 引入第三方插件? require('***')? // 或者修改window對(duì)象下某一屬性? window.mbk = {}}復(fù)制代碼
8.按需引入(UI框架等等)
例如使用UI框架:element-ui
我找了很多相關(guān)文章,并沒有詳細(xì)說明該如何引入矢腻。所以我要拿出來將他說明:
先來看下门驾,如果不按需引入vendor.js的體積大小為:
第一步,下載依賴:
# 先下載element-uinpm install element-ui --save# 如果使用按需引入多柑,必須安裝babel-plugin-component(官網(wǎng)有需要下載說明奶是,此插件根據(jù)官網(wǎng)規(guī)則不同,安裝插件不同)npm install babel-plugin-component --save-dev復(fù)制代碼
安裝好以后竣灌,按照nuxt.js中的規(guī)則聂沙,你需要在?plugins/?目錄下創(chuàng)建相應(yīng)的插件文件
在文件根目錄創(chuàng)建(或已經(jīng)存在)plugins/目錄,創(chuàng)建名為:element-ui.js的文件初嘹,內(nèi)容如下:
import Vue from'vue'import { Button } from'element-ui'//引入Button按鈕exportdefault ()=>{? ? Vue.use(Button)}復(fù)制代碼
第二步及汉,引入插件
在nuxt.config.js中,添加配置為:plugins
css:['element-ui/lib/theme-chalk/index.css'],plugins:['~/plugins/element-ui']復(fù)制代碼
默認(rèn)為:開啟SSR,采用服務(wù)端渲染屯烦,也可以手動(dòng)配置關(guān)閉SSR豁生,配置為:
css:['element-ui/lib/theme-chalk/index.css'],plugins:[? ? {? ? ? ? src:'~/plugins/element-ui',? ? ? ? ssr:false//關(guān)閉ssr? ? }]復(fù)制代碼
第三步,配置babel選項(xiàng)
在nuxt.config.js中漫贞,配置在build選項(xiàng)中甸箱,規(guī)則為官網(wǎng)規(guī)則:
build: {? ? ? babel:{? ? ? ? //配置按需引入規(guī)則"plugins":[? ? ? ? ? ? ? ["component",? ? ? ? ? ? ? ? ? {"libraryName":"element-ui","styleLibraryName":"theme-chalk"}? ? ? ? ? ? ? ]? ? ? ? ? ]? ? ? },? ? /*? ? ** Run ESLINT on save? ? */? ? extend (config, ctx) {if(ctx.isClient) {? ? ? ? config.module.rules.push({? ? ? ? ? enforce:'pre',test: /\.(js|vue)$/,? ? ? ? ? loader:'eslint-loader',? ? ? ? ? exclude: /(node_modules)/? ? ? ? })? ? ? }? ? } }復(fù)制代碼
此時(shí),我們在觀察打包以后文件體積大小迅脐,如圖:
此時(shí)芍殖,我們成功完成了按需引入配置。
9.不想服務(wù)端渲染的地方
(1)插件或者組件(2)nuxt.config.js里ssr改為falseplugins: [? ? {src:'~/plugins/ElementUI', ssr:false}],復(fù)制代碼
10.nuxt必須在接口地址前加上訪問域名
解決: 可以使用axios的baseURL來代理
import Vue from'vue'import axios from'axios'// axios.defaults.baseURL ="http://www.huanjingwuyou.com/"axios.defaults.baseURL ="http://localhost:3000/"http:// axios.defaults.baseURL ="http://test.huanjingwuyou.com/"exportdefault axios復(fù)制代碼
第十四節(jié):Nuxt爬坑更新- 判斷設(shè)備進(jìn)行跳轉(zhuǎn)手機(jī)端
nuxt是沒有index.html頁面的, 咱們應(yīng)該在哪里寫js代碼來判斷設(shè)備呢, 下面請(qǐng)看我的代碼吧
1. 引入middleware中間件
在nuxt.config.js里通過router來引入middleware中間件
nuxt.config.js代碼如下
exportdefault {? ? router: {? ? ? ? middleware: ["device"],? ? },}復(fù)制代碼
2. 在根目錄新建utils文件并且新建文件deviceType.js
deviceType.js文件代碼如下
/** * * @param {*} UA ,就是userAgent * @returnstype: 設(shè)備類型 *? ? ? ? ?? env: 訪問環(huán)境(微信/微博/qq) *? ? ? ? ?? masklayer: 就是給外部拿到判斷是否顯示遮罩層的,一些特殊環(huán)境要引導(dǎo)用戶到外部去打開訪問 */functionisWechat(UA) {return/MicroMessenger/i.test(UA) ?true:false;}functionisWeibo(UA) {return/Weibo/i.test(UA) ?true:false;}functionisQQ(UA) {return/QQ/i.test(UA) ?true:false;}functionisMoible(UA) {return/(Android|webOS|iPhone|iPod|tablet|BlackBerry|Mobile)/i.test(UA) ?true:false;}functionisIOS(UA) {return/iPhone|iPad|iPod/i.test(UA) ?true:false;}functionisAndroid(UA) {return/Android/i.test(UA) ?true:false;}exportfunctiondeviceType(UA) {if(isMoible(UA)) {if(isIOS(UA)) {if(isWechat(UA)) {return{type:"ios",? ? ? ? ? ? ? ? ? ? env:"wechat",? ? ? ? ? ? ? ? ? ? masklayer:true,? ? ? ? ? ? ? ? };? ? ? ? ? ? }if(isWeibo(UA)) {return{type:"ios",? ? ? ? ? ? ? ? ? ? env:"weibo",? ? ? ? ? ? ? ? ? ? masklayer:true,? ? ? ? ? ? ? ? };? ? ? ? ? ? }if(isQQ(UA)) {return{type:"ios",? ? ? ? ? ? ? ? ? ? env:"qq",? ? ? ? ? ? ? ? ? ? masklayer:true,? ? ? ? ? ? ? ? };? ? ? ? ? ? }return{type:"ios",? ? ? ? ? ? };? ? ? ? }if(isAndroid(UA)) {if(isWechat(UA)) {return{type:"android",? ? ? ? ? ? ? ? ? ? env:"wechat",? ? ? ? ? ? ? ? ? ? masklayer:true,? ? ? ? ? ? ? ? };? ? ? ? ? ? }if(isWeibo(UA)) {return{type:"android",? ? ? ? ? ? ? ? ? ? env:"weibo",? ? ? ? ? ? ? ? ? ? masklayer:true,? ? ? ? ? ? ? ? };? ? ? ? ? ? }if(isQQ(UA)) {return{type:"android",? ? ? ? ? ? ? ? ? ? env:"qq",? ? ? ? ? ? ? ? ? ? masklayer:true,? ? ? ? ? ? ? ? };? ? ? ? ? ? }return{type:"android",? ? ? ? ? ? };? ? ? ? }return{type:"mobile",? ? ? ? };? ? }else{return{type:"pc",? ? ? ? };? ? }}復(fù)制代碼
3. 在middleware里添加device.js文件
device.js代碼如下
// @ts-nocheckimport { deviceType } from"~/utils/deviceType";exportdefaultfunction(context) {? ? // @ts-ignore? ? context.userAgent = process.server ?? ? ? ? context.req.headers["user-agent"] :? ? ? ? navigator.userAgent;? ? // 給全局上下文添加一個(gè)屬性來保存我們返回的匹配信息? ? context.deviceType = deviceType(context.userAgent);? ? // 這里注入到store,是因?yàn)槲也糠猪撁嫘枰袛鄼C(jī)型請(qǐng)求不同的數(shù)據(jù),? ? // 你們沒有用到的話可以移除? ? // context.store.commit("SetDeviceType", context.deviceType);? ? // 若是判斷UA非移動(dòng)端的,就在這里做處理了..? ? // context.redirect(status,url) 這個(gè)可以重定向到外部網(wǎng)站? ? // 若是內(nèi)部訪問可以直接用router對(duì)象pushif(context.deviceType.type ==="pc") {? ? ? ? // context.redirect(302,'www.huanjingwuyou.com')? ? //301是永久重定向谴蔑,如果你想隨著設(shè)備類型改變一直變豌骏,請(qǐng)改為302? ? }else{? ? ? ? context.redirect(302,'m.huanjingwuyou.com')? ? //301是永久重定向,如果你想隨著設(shè)備類型改變一直變隐锭,請(qǐng)改為302? ? }}復(fù)制代碼
心得:
0. nuxt渲染頁面分為兩個(gè)階段, 服務(wù)端渲染和瀏覽器渲染
1. nuxt可以用服務(wù)端渲染階段asyncData來提前獲取到數(shù)據(jù), 數(shù)據(jù)自動(dòng)存放到data中, 瀏覽器渲染時(shí)直接拿data數(shù)據(jù)
2.?asyncData方法會(huì)在組件(限于頁面組件)每次會(huì)在刷新加載頁面或者切換路由時(shí)被調(diào)用,順序比beforeCreate和created之前
3. nuxt服務(wù)端渲染時(shí)生命周期只有兩個(gè)鉤子函數(shù)created和beforeCreate兩個(gè)鉤子函數(shù),
4. async做并發(fā)請(qǐng)求
5. 設(shè)置head來提高SEO, 局部需要return {}
6. 每次調(diào)用接口的時(shí)候需要在接口前面加上訪問域名, 可以通過axios配置axios.defaults.baseURL
7. nuxt用proxy來代理
8. 跳到詳情頁用nuxt-link來跳轉(zhuǎn), 這樣url地址參數(shù)更有利于seo, 跳轉(zhuǎn)時(shí)域名都是自己拼接上去的
9. 寫一個(gè)錯(cuò)誤頁面, 路由調(diào)用失敗或者代碼出現(xiàn)bug, 會(huì)跳到錯(cuò)誤頁面去
10. 公共的靜態(tài)頁面可以寫在assets里, 然后nuxt.config.js里引入
11. 發(fā)布線上時(shí)需要將.nuxt,?assets,?package.json,?nuxt.config.js,?static放到Nginx里進(jìn)行代理
BUG
如何在組件中使用異步數(shù)據(jù)窃躲?
如果組件不是和路由綁定的頁面組件,原則上是不可以使用異步數(shù)據(jù)的钦睡。因?yàn)?Nuxt.js 僅僅擴(kuò)展增強(qiáng)了頁面組件的?data?方法蒂窒,使得其可以支持異步數(shù)據(jù)處理。
對(duì)于非頁面組件荞怒,有兩種方式可以實(shí)現(xiàn)數(shù)據(jù)的異步獲热髯痢:
在組件的?mounted?方法里面實(shí)現(xiàn)異步獲取數(shù)據(jù)的邏輯,之后設(shè)置組件的數(shù)據(jù)褐桌,限制是:不支持服務(wù)端渲染衰抑。
在頁面組件的asyncData或fetch方法中進(jìn)行API調(diào)用,并將數(shù)據(jù)作為props傳遞給子組件荧嵌。服務(wù)器渲染工作正常呛踊。缺點(diǎn):asyncData或頁面提取可能不太可讀砾淌,因?yàn)樗诩虞d其他組件的數(shù)據(jù)。 總之谭网,使用哪種方法取決于你的應(yīng)用是否需要支持子組件的服務(wù)端渲染汪厨。
為什么 Nuxt.js 應(yīng)用的頁面會(huì)出現(xiàn)閃爍?
這是因?yàn)樵?b>開發(fā)模式下蜻底,為了通過 Webpack 實(shí)現(xiàn)熱加載骄崩,CSS代碼是打包在 JavaScript 代碼中聘鳞,并動(dòng)態(tài)打到頁面中去薄辅,從而元素重繪引起了閃爍。
不用擔(dān)心抠璃,在生產(chǎn)模式下站楚,CSS代碼會(huì)單獨(dú)打包至獨(dú)立的文件并置于head標(biāo)簽內(nèi),不會(huì)出現(xiàn)頁面閃爍的現(xiàn)象搏嗡。
如何編輯主機(jī)和端口配置窿春?
作為命令參數(shù)直接傳遞
nuxt --hostname myhost --port 3333復(fù)制代碼
或
"scripts": {"dev":"nuxt --hostname myhost --port 3333"}復(fù)制代碼
在?nuxt.config.js?中配置:
在?nuxt.config.js?添加:
exportdefault {? server: {? ? port: 8000, // default: 3000? ? host:'0.0.0.0', // default: localhost? },? // other configs}復(fù)制代碼
使用 NUXT_HOST 和 NUXT_PORT env 變量
與 HOST 和 PORT 類似,但更具體采盒,以防您需要添加其他東西旧乞。
"scripts": {"dev":"NUXT_HOST=0.0.0.0 NUXT_PORT=3333 nuxt"}復(fù)制代碼
注意: 為了更好的跨平臺(tái)開發(fā)支持,您可以使用?cross-env?依賴包磅氨。
安裝依賴:
npm install --save-dev cross-env復(fù)制代碼
配置cross-env:
"scripts": {"dev":"cross-env NUXT_HOST=0.0.0.0 NUXT_PORT=3333 nuxt"}復(fù)制代碼
使用HOST和PORT env變量
"scripts": {"dev":"HOST=0.0.0.0 PORT=3333 nuxt"}復(fù)制代碼
在?package.json?中配置?nuxt?:
在您的?package.json?文件中添加:
"config": {"nuxt": {"host":"0.0.0.0","port":"3333"}},"scripts": {"dev":"nuxt"}