【Vue全家桶+SSR+Koa2全栈开发】项目搭建过程 整合 学习目录(持续更新中)
寫在開頭
大家好,這里是lionLoveVue,基礎(chǔ)知識決定了編程思維,學如逆水行舟,不進則退。金三銀四,為了面試也還在慢慢積累知識,Github上面可以直接查看所有前端知識點梳理,github傳送門,覺得不錯,點個Star★,好運連連,Offer終究鼠于你,持續(xù)更新中。另外,也可以關(guān)注微信公眾號:小獅子前端Vue,源碼以及資料今后都會放在里面。Vue基礎(chǔ)
全局安裝vue/cli腳手架
管理員身份運行cmd,執(zhí)行如下代碼:
npm install -g @vue/cli或
yarn global add @vue/cli命令行輸入vue ui 打開可視化界面
使用默認default配置
用vscode打開項目,執(zhí)行如下命令
npm/cnpm run serve訪問:http://localhost:8080/ 查看是否配置成功
自定義指令
推薦閱讀:官方文檔-自定義指令
除了核心功能默認內(nèi)置的指令 (v-model 和 v-show),Vue 也允許注冊自定義指令。注意,在 Vue2.0 中,代碼復(fù)用和抽象的主要形式是組件。然而,有的情況下,你仍然需要對普通 DOM 元素進行底層操作,這時候就會用到自定義指令。
組件
父子組件的通信方式
父組件傳子組件,是在子組件使用props,然后再父組件,通過:=綁定變量
子組件傳父組件,是在子組件使用自定義事件,例如:
//子組件配置 @click="$emit('patch(xxx)')" //父組件配置 @patch="func"如果是跨組件,不是父子組件關(guān)系,就使用 Vuex。
slot
插槽在組件抽象設(shè)計中的應(yīng)用:
原本組件不能嵌入html內(nèi)容,但通過父子組件傳遞插槽即可實現(xiàn)
//父組件 slot="a" //子組件 <slot name="a"></slot>Vuex基礎(chǔ)
Vuex簡單來說就是多個組件共享數(shù)據(jù),但是組件是不能直接操縱數(shù)據(jù)的,如下圖所示,我們的數(shù)據(jù)放在紫色部分state里面(沒有放在data里),操作數(shù)據(jù)源由紅色部分Mutations完成,什么時候操控數(shù)據(jù)有黃色部分Actions來控制,這里就是由用戶來操縱組件來觸發(fā) Actions ,最后,由 Actons 提交 Commit 通知改變數(shù)據(jù)源,來完成組件視圖的更新渲染。
安裝Vuex
npm/cnpm i vuexKoa2基礎(chǔ)
koa-generator
管理員身份打開cmd,運行如下代碼,全局安裝
npm install -g koa-generator使用git bash,在文件夾內(nèi)創(chuàng)建項目
koa2 -e project_name-e 表示使用ejs,不加和 node 一樣
接下來,執(zhí)行安裝命令
安裝&更新 fsevents 包
npm install --update-binaryrun app命令:
DEBUG=koa2_learn:* npm start執(zhí)行后輸出 node bin/www 說明服務(wù)端已經(jīng)跑起來了
訪問 http://localhost:3000/ 查看頁面效果
我們查看 package.json ,發(fā)現(xiàn)啟動腳本是通過 npm scripts ,如果你想要自啟動的話,執(zhí)行如下命令:
對于上述執(zhí)行指令,dev 和 prd 必須使用 npm run xxx
與此同時,我們在 index.js 全局打印一下,加入如下代碼:
在 git bash 中執(zhí)行如下命令
npm run dev說明我們改變服務(wù)端腳本,服務(wù)能夠自啟動了
Koa2中間件
圖片來自Koa2官方,大致意思就是服務(wù)端接受客戶端的 Request,經(jīng)過服務(wù)端一些流程,然后 Response 返回給瀏覽器,其中每一個環(huán),都是一個中間件。進來的時候會經(jīng)過某個中間件,出去的時候也會經(jīng)過,這樣的機制就可以讓中間件引用順序和代碼執(zhí)行順序不一致。
mongoose基礎(chǔ)
mongodb概念&安裝
mongodb屬于非關(guān)系型數(shù)據(jù)庫,與mysql相對的(mysql是關(guān)系型數(shù)據(jù)庫)
mongodb里面沒有 table表,只有 Collections
原本mysql一行叫做 row,而在mongodb中叫做 document,原本一列叫做 cloumn,而現(xiàn)在叫做 fields
windows 10 安裝教程:
推薦閱讀:Windows 平臺安裝 MongoDB
注意
安裝Install MongoDB Compass 不勾選,否則可能要很長時間都一直在執(zhí)行安裝,MongoDB Compass是一個圖形界面管理工具,后面會去下載一個圖形界面管理工具Robo3T。
其它選項就默認選擇 next 即可
找到下面位置下的兩個 .exe 都點擊運行一下好了… (啟動服務(wù)應(yīng)該是下面那一個)
檢測是否安裝成功
訪問:http://127.0.0.1:27017/ 是否出現(xiàn)如下界面:
圖形界面管理工具 Robo3T 安裝與使用
官網(wǎng)地址
Studio windows下載地址
Robo 3T下載
進入安裝頁面后選擇 easy 版本 ,然后選擇你喜歡的主題風格,是明亮還是黑暗風格
進入圖形化界面后,新建一個 connection,選擇默認端口 27017,保存
mongoose 中文文檔
參考:mongoose 4.5中文文檔
在之前配置好的 Koa2 文件夾內(nèi)(我的是koa2_learn文件夾) 打開 bash 界面,輸入如下命令,安裝 mongoose
npm i mongoose連接數(shù)據(jù)庫
接下來就是配置相關(guān)了
在項目根目錄下創(chuàng)建 名為 dbs 的文件夾
新建一個 config.js 文件,配置如下代碼
在 dbs 目錄下創(chuàng)建 名為 models 的文件夾
新建一個 person.js 文件,配置如下代碼(此時的文件名對應(yīng)著之后我們的“表名”,也就是 Collections)
然后在 app.js 中進行導(dǎo)入
const mongoose = require('mongoose') const dbConfig = require('./dbs/config')在 app.js 默認注釋 routes 后面,添加第三行連接代碼
// routes app.use(index.routes(), index.allowedMethods()) app.use(users.routes(), users.allowedMethods()) mongoose.connect(dbConfig.dbs,{useNewUrlParser:true })基本配置就結(jié)束了,現(xiàn)在最好是重啟一下koa服務(wù),ctrl+c 退出,然后輸入如下命令:
npm run dev出現(xiàn)如下界面,說明配置是沒有問題的,連接成功!
接下來就是嘗試寫一個api試試,在 users.js 文件內(nèi)配置如下代碼
頭部導(dǎo)入模型
//導(dǎo)入模型 const Person = require('../dbs/models/person')自定義api接口
router.post('/addPerson',async function(ctx){//新建一個模型的實例const person = new Person({name: ctx.request.body.name,age: ctx.request.body.age})let codetry {await person.save()code=0} catch (error) {code=-1}ctx.body={code} })調(diào)用接口。 curl 是一個shell 命令, -d命令表示是 post 請求 ,接下來是數(shù)據(jù)項,最后是api接口地址
curl -d 'name=chocolate&age=20' http://localhost:3000/users/addPerson
此時,打開Robo 3T,刷新一下我們的數(shù)據(jù)庫,就能發(fā)現(xiàn)多了一個 dbs
查看一下,是否有對應(yīng)寫入數(shù)據(jù):
上述過程,基本上把我們的后端服務(wù)和數(shù)據(jù)庫進行了打通,后續(xù)我們只需要套著之前的例子來就好了,接下來再展示寫一個api,因為上文是增加操作,也就是寫操作,下文我們再來個讀操作吧。
依舊是在 users.js 中加入如下代碼
//數(shù)據(jù)庫讀取api router.post('/getPerson',async function(ctx){const result = await Person.findOne({name:ctx.request.body.name})const results = await Person.find({name:ctx.request.body.name})ctx.body = {code: 0,result,results} })打開 bash ,執(zhí)行如下命令:
curl -d 'name=chocolate' http://localhost:3000/users/getPerson發(fā)現(xiàn),會返回給我們json數(shù)據(jù)包,證明api接口實現(xiàn)
最后,附上更新和刪除api,親測有效嗷
更多知識點請參考:mongoose 4.5中文文檔
Redis基礎(chǔ)
cookie 和 session 引入
這里就要扯到 cookie 和 session的相關(guān)知識點了,劃重點啦!
服務(wù)端的程序如何去識別客戶端的狀態(tài),大家知道,http是無狀態(tài)的,推薦閱讀:如何學好前端,白嫖知識
比如現(xiàn)在有個用戶A,它訪問了服務(wù)器程序,那服務(wù)器程序如何知道下一次再訪問的時候還是A呢?
因此,對于這一塊就要用到非常重要的概念,session,當然,這個session可不是瀏覽器的,而是服務(wù)器的,它是用來存儲用戶的信息的。
那么,服務(wù)器的 session是如何保持在客戶端呢?
這個時候呢,又要引出另一個非常重要的概念,瀏覽器中的 cookie 。
綜上所述,cookie 和 session 的關(guān)系是:服務(wù)端用 session 來保存用戶的狀態(tài),然后客戶端用 cookie 來保存 session ,服務(wù)器端把 session 種植到 cookie 中,然后下次訪問時,cookie 會攜帶著 session ,進而達到一個身份認證的效果。
redis概念&安裝
上文我們知道了cookie 和 session 在瀏覽器和服務(wù)器端的作用,那么與我們redis 有什么關(guān)系呢?
想一想,既然是認證的功能,那我們服務(wù)端的session 應(yīng)該存在哪呢,也許你會想著放入服務(wù)器端存儲,放入內(nèi)存當中,這確實是一種方式,沒有問題,但當應(yīng)用程序很大的時候,session 容量特別大的時候呢?例如某寶這樣的呢?此時內(nèi)存肯定不夠用了,這個時候就需要一個容器來存儲大容量的 session 了,此時存儲數(shù)據(jù)庫 redis就發(fā)揮了它的作用了!
關(guān)于數(shù)據(jù)庫的話,上文也提到了mongodb,我們是不是也可以用這個呢?
這個的話,雖然也是一種方式,但我們要考慮讀寫性能問題,因為 redis是快速讀寫類型的數(shù)據(jù)庫,使用靈活方便,是 key-value 型的
為了更加了解redis,這里我就引用官方介紹了:
-
REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value存儲系統(tǒng)。
-
Redis是一個開源的使用ANSI C語言編寫、遵守BSD協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。
-
它通常被稱為數(shù)據(jù)結(jié)構(gòu)服務(wù)器,因為值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。
安裝教程
參考:redis安裝教程
參考:windows下Redis的安裝和配置–圖文教程
在 koa 的 bash界面,執(zhí)行如下命令,完成 koa 與 redis 的連接
npm i koa-generic-session koa-redis redis-server.exe redis.windows.conf啟動 redis 服務(wù)
一、[9980] 21 Apr 02:57:05.611 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
解決方法:在命令行中運行
redis-cli.exe 127.0.0.1:6379>shutdown二、Redis (error) NOAUTH Authentication required.解決方法
127.0.0.1:6379>auth "123456" 127.0.0.1:6379>shutdown not connected>exit然后重新運行 redis-server.exe redis.windows.conf ,啟動成功!
參考:Redis啟動報錯:Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
Nuxt.js基礎(chǔ)
Nuxt.js 是一個基于Vue.js的通用應(yīng)用框架,預(yù)設(shè)了利用Vue.js開發(fā)服務(wù)端渲染的應(yīng)用所需要的各種配置。
基于Vue 2做的,包括Vue-Router,支持Vuex、Vue Server Render、vue-meta
Nuxt.js工作流
下圖源自Nuxt官網(wǎng),簡單介紹一下它的工作流程
更多內(nèi)容,請參考:nuxtjs 英文官方文檔
參考:nuxtjs 中文文檔
從瀏覽器發(fā)出一個請求,到最終服務(wù)端渲染完成,關(guān)于Nuxt的生命周期如下:
- Incoming Request 瀏覽器發(fā)送一個請求
- 服務(wù)端檢查是否有 nuxtServerInit 配置項,有的話就會執(zhí)行這個函數(shù),其中包含一個標注: Store action 用來操作 vuex
- 下一個環(huán)節(jié)就是中間件 middleware ,與路由相關(guān),做任何你想要的功能
- 預(yù)驗證 validate() 可以配合高級動態(tài)路由,做一些驗證,比如是否允許跳轉(zhuǎn)某個頁面
- asyncData() & fetch() 獲取數(shù)據(jù),前一個是用來渲染vue component,即 vue組件的,后一個通常用來修改 vuex,即 Store的
- 有了數(shù)據(jù),模板后,最后一步就是 Render 渲染了,方式是 SSR
Nuxt.js 安裝
如果沒有安裝vue cli的話,先全局安裝一下
npm/cnpm install -g @vue/cli-init vue init nuxt-community/koa-template nuxt_learn(這里填入你自己的文件名)安裝完成后,依次執(zhí)行如下命令
cd nuxt_learn npm install # Or yarn npm install --update-binary npm install ajv@^6(可選項,如果有報warn,就裝一下) npm run dev如果安裝過程網(wǎng)絡(luò)有問題,報錯了,可以試試用 cnpm或者
nrm use cnpmeslint版本問題: 需要更新eslint版本
解決:執(zhí)行如下代碼:
執(zhí)行完如下步驟后,最后一步,打開服務(wù):
npm run devbabel編譯版本有問題: 解決辦法是升級backpack-core@0.3.0到backpack-core@0.7.0
npm install backpack-core@0.7.0 --save-dev解決上述問題后,編譯能成功,但是客戶端依舊運行報錯
解決辦法是:在nuxt.config.js里找到eslint-loader將ctx.isClient改成ctx.Client就可以運行了
參考:解決vue init nuxt-community/koa-template項目,安裝報錯問題
解決完上述問題后,執(zhí)行如下指令:
npm run dev
訪問:http://localhost:3000/ 出現(xiàn)如下界面,代表配置成功 ??ヽ(°▽°)ノ?
附:微信公眾號:【小獅子前端】 回復(fù)【nuxt-learn】即可獲取本節(jié)源碼
知識拓展
當使用 SSR 時, mounted 只在瀏覽器端渲染,而在服務(wù)器端不會渲染 :瀏覽器通過axios請求的數(shù)據(jù),只有 created 在開啟SSR時會執(zhí)行。
SSR原理:① 服務(wù)器端將編譯好的內(nèi)容(模板)下發(fā)(包括樣式、內(nèi)容、數(shù)據(jù)) ② 把異步獲取的數(shù)據(jù)響應(yīng)給瀏覽器端(把交互交給瀏覽器來完成)
SSR原理深入
我們打開頁面源代碼,查看一下:
服務(wù)器端渲染完頁面后給瀏覽器端的html分了幾個部分,第一個是樣式 style ,第二個是模板內(nèi)容,例如上圖中圈中的藍色部分,第三個是服務(wù)端拿到的數(shù)據(jù)結(jié)果,例如上圖中圈中的紅色部分,為什么服務(wù)端拿到的數(shù)據(jù)給到瀏覽器端呢?
這里我們得思考一個SSR的工作原理 了
如果不給數(shù)據(jù)的話,就是一個靜態(tài)html模板,一個靜態(tài)的內(nèi)容,沒有任何交互,那交互是在哪完成的呢?
交互是在瀏覽器端完成的,也就是說瀏覽器端會有一個入口,進行預(yù)編譯,但不會再渲染頁面了,因為服務(wù)器端已經(jīng)在頁面渲染過一次了。它要做的是創(chuàng)建一個虛擬的編譯結(jié)果(可以理解為虛擬dom), 和服務(wù)器端傳過來的結(jié)果進行對比,如果有區(qū)別,它會重新請求數(shù)據(jù)。在nuxt項目中都是一套文件,沒有特別指定是在瀏覽器端運行還是服務(wù)端運行,也就是SSR常說的同構(gòu),瀏覽器端編譯虛擬dom,也依賴于 vue 文件,因此模板是有的,而編譯這個dom,需要的是額外的數(shù)據(jù),此數(shù)據(jù)是服務(wù)器端渲染之前請求而來的數(shù)據(jù),如果數(shù)據(jù)不同步在瀏覽器端,編譯出來的結(jié)果必然和服務(wù)器端編譯結(jié)果不一致。
綜上,服務(wù)器端異步獲取的數(shù)據(jù)會同步在瀏覽器端,作對比,如果對比一致的話,瀏覽器端就會對對應(yīng)的dom結(jié)點注冊事件,達到交互作用。
更多內(nèi)容,請參考:nuxtjs 英文官方文檔
參考:nuxtjs 中文文檔
以上,就是我們項目搭建所需的基礎(chǔ)知識啦,已經(jīng)整理完結(jié)啦,當然還有許多地方?jīng)]有提及,讀者可以去查閱一些官方文檔來補充更多知識,下文我們將逐步深入全棧開發(fā)過程記錄,制作不易,點贊收藏評論,一鍵三連一波~
項目搭建開始
配置環(huán)境
- node
- vue
- npm
- webpack
- nuxt
創(chuàng)建項目
npm install -g npx npx create-nuxt-app loveVueApp使用 npx 可以幫助我們更快速的搭建項目環(huán)境,在你需要創(chuàng)建項目文件夾的地方 shift+鼠標右鍵 打開 powershell 窗口,執(zhí)行上述命令,然后按照下列圖片選擇對應(yīng)的模塊:
安裝完成后,會提示你執(zhí)行如下命令:
這里我們就執(zhí)行開發(fā)環(huán)境的指令就好了
cd loveVueApp npm run dev另附上,生產(chǎn)環(huán)境的指令:
cd loveVueApp npm run build npm run start訪問:http://localhost:3000/ 會有一個nuxtjs的圖標出現(xiàn),代表環(huán)境搭配成功 ??ヽ(°▽°)ノ?
此時,再 ctrl+c 退出當前服務(wù)
執(zhí)行如下命令,重新安裝一下,防止版本問題等
npm install --update-binary重裝之后,再跑一次服務(wù),看能不能打開界面
npm run dev增加 babel-node 處理(使用ES6的import指令問題)
創(chuàng)建好我們的基本項目后,我們還需要對我們所需要的模塊進行更改。
例如,對應(yīng)目標文件的第一行代碼:
改為如下代碼
于是,就會出現(xiàn)報錯,無法識別
在上文講解 nuxtjs基礎(chǔ) 我們是可以直接用 import 操作的,但當我們使用官方腳手架時,是沒有處理這個 bug 的。下面來解釋一下為什么會出現(xiàn)這個問題:
當我們使用命令 npm run dev 的時候,其實是用了 npm 的 script 的方法,如下圖所示:
可見使用了 node,并且不支持 import 操作,上文是因為使用了 babel 進行了處理,在這里官方腳手架時使用 node 來啟動服務(wù),沒有經(jīng)過 babel 處理,因此就不會識別 import 指令了。
解決上述問題
上文提到了是因為沒有 babel處理,執(zhí)行服務(wù)程序,那就自己加上去咯,具體如下:
在 dev 和 start 后面添加 --exec babel-node
或者直接使用下面代碼覆蓋你的 scripts
"scripts": {"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server --exec babel-node","build": "nuxt build","start": "cross-env NODE_ENV=production node server/index.js --exec babel-node","generate": "nuxt generate"},然后,在根目錄下創(chuàng)建一個 .babelrc 的配置文件,然后給它指定一個指令集
{"presets":["es2015"] }有了代碼還不行,還要再安裝插件,執(zhí)行如下命令
npm install babel-preset-es2015 npm install babel-cli -S好了,有了 babel-node 后我們就能啟動服務(wù)程序了,改成了我們常用的 ES6語法了
npm run dev訪問:http://localhost:3000/ 會有一個nuxtjs的圖標出現(xiàn),代表環(huán)境搭配成功 ??ヽ(°▽°)ノ?
解決 sass 導(dǎo)致編譯出錯問題
這個問題也依舊是腳手架帶來的問題,解決方式就是安裝幾個插件,執(zhí)行命令如下:
npm install sass-loader node-sassPS:可能會有下述 warn
npm install eslint@^(版本號) //(注意,這里是當你出現(xiàn)對應(yīng)warn才執(zhí)行)我的是這種警告,因此依葫蘆畫瓢,執(zhí)行下述命令
輔助工具安裝
- MongoDB
- redis
- Robo 3T
(上文基礎(chǔ)部分有介紹安裝教程,可以往回看一看對應(yīng)模塊 ↑)
遠程倉庫常用指令(整理)
-
查看分支:git branch
-
查看項目的分支們(包括本地和遠程) git branch -a
-
創(chuàng)建分支:git branch <name>
-
切換分支:git checkout <name>
-
創(chuàng)建+切換分支:git checkout -b <name>
-
合并某分支到當前分支:git merge <name>
-
提交 git commit -m ‘簡介’
-
git push -u origin master
首頁開發(fā)
需求分析
- 模板設(shè)計(解決復(fù)用問題)
- 組件設(shè)計(如何拆分組件)
如何節(jié)省網(wǎng)絡(luò)請求?
上述流程圖共進行了兩次請求,另外,異步獲取數(shù)據(jù)時,還會有閃一下,影響用戶體驗,同時浪費一次網(wǎng)絡(luò)請求。解決辦法就是當瀏覽器去請求服務(wù)器的時候,當瀏覽器去請求文檔的時候,服務(wù)端 ip已經(jīng)知道了,那個時候就可以拿到對應(yīng)的城市,立即返回數(shù)據(jù)給瀏覽器。做法就是通過 vuex 來同步狀態(tài),然后通過 SSR 異步請求就能得到數(shù)據(jù)。
類似于上文流程圖,也是可以通過 vuex 來做
屬于靜態(tài)模塊,不需要我們異步獲取數(shù)據(jù),直接用 SSR 下發(fā)一下就ok。
- 數(shù)據(jù)結(jié)構(gòu)設(shè)計(依賴于數(shù)據(jù)和組件)
pois表 城市推薦數(shù)據(jù)庫
- 接口設(shè)計(與數(shù)據(jù)結(jié)構(gòu)相對應(yīng))
首頁開發(fā)Header-城市定位服務(wù)設(shè)計
根據(jù) Header 布局情況來看的話,我們在components文件夾下創(chuàng)建如下幾個文件夾和文件(水印遮住的是 README)
導(dǎo)入css,然后打開 nuxt.config.js 進行配置
項目開發(fā)可能遇到問題
重要提醒!
本篇文章能詳細概述的地方有限,所以下文將會以講重點部分為主,其余部分請參考本參考源碼,已經(jīng)開放,開發(fā)過程中按照分支進行開發(fā),然后合并到 master 分支
倉庫の傳送門(戳一戳)
收藏 star 一波,??ヽ(°▽°)ノ?
關(guān)于項目中SMTP服務(wù)功能配置問題
如下圖,所示,我們首先登陸自己的QQ,打開郵箱,然后去打開下面兩項服務(wù)
在 server/dbs/config.js 文件內(nèi)更改為你自己的授權(quán)密鑰和郵箱即可
引入 mongoose
npm install mongoose配置 users 接口
npm install koa-router koa-redis nodemailer配置 axios
npm install axios配置 passport
npm install koa-passport passport-local關(guān)于項目中登錄注冊接口問題
passport 包內(nèi)有 isAuthenticated()方法,因此在文檔源碼中沒有定義過。
passport會把用戶的信息對象放到 session 對象里面去,也就是 passport 會存儲在 session 中,例如如下,如果是登錄狀態(tài)的話,那么session會有 passport,而 passport 會有 user
//判斷是否是登錄狀態(tài)if (ctx.isAuthenticated()) {const {username, email} = ctx.session.passport.userctx.body={user:username,email}}- users.js
server文件夾 index.js文件中 加載相關(guān)包
import mongoose from 'mongoose' import bodyParser from 'koa-bodyparser' import session from 'koa-generic-session' import Redis from 'koa-redis' import json from 'koa-json' import dbConfig from './dbs/config' import passport from './interface/utils/passport' import users from './interface/users' import geo from './interface/geo' import search from './interface/search' import categroy from './interface/categroy' import cart from './interface/cart'加載指令:
npm install mongoose koa-bodyparser koa-generic-session koa-redis koa-jsonCannot read property ‘post’ of undefined 問題解決
注冊那一個模塊那里,我一點發(fā)送驗證碼,然后就報了這個錯誤,一開始以為接口寫錯了,還測試了一下,原來是因為 axios 沒有在 nuxt 腳手架中配置
Cannot read property 'name' of undefinednuxt.config.js 文件中配置如下:
module.exports = {modules: ['@nuxtjs/axios',],axios: {// proxyHeaders: false} }解決之后,發(fā)送驗證碼,如下結(jié)果,有郵件發(fā)送過來 ??ヽ(°▽°)ノ?
關(guān)于 win10 redis 報錯 Permission denied
同樣也是注冊頁面,當我們注冊后,點擊同意協(xié)議并注冊,發(fā)現(xiàn)無法跳轉(zhuǎn)到登錄界面,而提示 已注冊 ,看了半天,提示服務(wù)錯誤,于是一開打redis命令窗,報了這個錯誤,原來是默認設(shè)置了只可讀不可寫,按如下方式增加權(quán)限,解決了問題 ??ヽ(°▽°)ノ?
解決:去Redis的rdb文件查看文件屬性,增加寫入權(quán)限
參考:Redis在Windows下的坑
關(guān)于win10 mongodb 導(dǎo)入.bat文件問題
網(wǎng)上說用如下指令,但是我還是沒有導(dǎo)入成功,說是不存在這指令,但之前數(shù)據(jù)庫都導(dǎo)入了 users
mongoimport -d student -c areas areas.dat于是,我就打開了 Studio 3T 來試著導(dǎo)入,還算是成功了吧
我的做法是直接在左邊那個 Collections 文件夾直接右鍵 選擇 Add 操作,然后導(dǎo)入 .dat文件,不過導(dǎo)完之后會有后綴出現(xiàn),于是我就重命名了一下。雖然看起來有點傻傻的做法,但也算是解決了吧 ??ヽ(°▽°)ノ?
關(guān)于 geo服務(wù) 接口簽名
http://cp-tools.cn/sign
關(guān)于定位服務(wù)及切換城市 geo bug解決
在城市定位 geo 分支那里,報了如下兩個錯誤,可讓我焦頭爛額啊,終于,找到了解決辦法,特來寫此模塊,記錄一下 ??ヽ(°▽°)ノ?
① 報錯Classic mode for store/ is deprecated and will be removed in Nuxt 3.
② Error occurred when calling nuxtServerInit: socket hang up
對第一個問題出現(xiàn)這種錯誤的原因是:nuxt3版本中已經(jīng)移除了對原始vuex這種編程,出現(xiàn)這種錯誤的代碼如下:
解決的辦法如下: store 目錄下的每個 .js 文件會被轉(zhuǎn)換成為狀態(tài)樹指定命名的子模塊 (當然,index 是根模塊)。
(以下代碼親測有效,直接覆蓋你的代碼即可)
首先是目錄結(jié)構(gòu)修改,最新版的已經(jīng)不需要另外加一個 models 文件夾了。
index.js 文件:
export const actions = {async nuxtServerInit({commit},{req,app}) {const {status,data: {province,city}} = await app.$axios.get('/geo/getPosition')commit('geo/setPosition',status===200?{city,province}:{city:'',province:''}) const {status:status2, data: {menu}} = await app.$axios.get('/geo/menu')commit('home/setMenu',status2===200?menu:[])} }geo.js 文件無需修改
對第二個問題,多半是因為你寫好的 geo 相關(guān)接口沒有在serve/index.js中進行導(dǎo)入和配置使用(我就是因為這個)
import geo from './utils/geo' app.use(geo.routes()).use(geo.allowedMethods())具體導(dǎo)入位置如下:
參考:美團項目 — 定位服務(wù)及切換城市5
參考:nuxtjs中使用SSR開發(fā)關(guān)于前端vuex請求后臺的問題
關(guān)于搜索框請求次數(shù)問題
我們當然不能沒輸入一個字符,就請求一次接口,因此我們需要弄一個延時函數(shù)
npm install lodash引入庫
import _ from 'lodash'關(guān)于切換城市模塊優(yōu)化與實現(xiàn)
首先明確一載入切換城市界面,哪個是要進行請求的,那就是省份(第一級),此時可以使用ssr進行服務(wù)端渲染,頁面載入后也跟著進行載入,但這里就直接使用vue中的Mouted生命函數(shù)完成這里的axios請求 ↓
mounted: async function() {let self = this;let {status,data: { province }} = await self.$axios.get("/geo/province");if (status === 200) {self.province = province.map(item => {return {value: item.id,label: item.name};});}}聯(lián)動邏輯,使用watch監(jiān)聽用戶選擇了什么省份
//監(jiān)聽pvalue值,當省份發(fā)生改變的時候,可選城市也要跟著改變(聯(lián)動)watch:{pvalue:async function(newPvalue){let self=this;let {status,data:{city}}=await self.$axios.get(`/geo/province/${newPvalue}`)if(status===200){self.city=city.map(item=>{return {value:item.id,label:item.name}})self.cvalue=''}}},注意select下拉框的設(shè)計,如果你不設(shè)置 label 顯示的還是 value 的值,但是如果你設(shè)置了 label 那輸入框顯示的就是 label 的值,但是你 v-model 拿的還是你 value 的值,所以在省份中復(fù)制也是將 id 賦值給 value 的,所以參數(shù)正確!
會二級聯(lián)動,三級聯(lián)動還會難嗎?畢竟現(xiàn)在你只需要重點思考邏輯上的代碼,而 DOM 結(jié)構(gòu)E-UI已經(jīng)隨隨便便完成了,只剩下你關(guān)聯(lián)他們的代碼而已
參考:美團項目 — 切換城市 7
通過項目挖掘知識點(整理)
koa2中的ctx是什么?
為了試圖搞明白,用console.log將它輸出
{ request:{ method: 'GET',url: '/',header:{ host: 'localhost:3000',connection: 'keep-alive','cache-control': 'max-age=0','upgrade-insecure-requests': '1','user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','accept-encoding': 'gzip, deflate, sdch, br','accept-language': 'zh-CN,zh;q=0.8' } },response:{ status: 200,message: 'OK',header:{ 'content-type': 'text/plain; charset=utf-8','content-length': '25' } },app: { subdomainOffset: 2, proxy: false, env: 'development' },originalUrl: '/',req: '<original node req>',res: '<original node res>',socket: '<original node socket>' }可見它主要包括 request 和 response 兩部分。
ctx是context的縮寫中文一般叫成上下文,這個在所有語言里都有的名詞,可以理解為上(request)下(response)溝通的環(huán)境,所以koa中把他們兩都封裝進了ctx對象,koa官方文檔里的解釋是為了調(diào)用方便,ctx.req=ctx.request,ctx.res=ctx.response,類似linux系統(tǒng)中的軟連接?最終執(zhí)行還是request和response對象 body是http協(xié)議中的響應(yīng)體,header是指響應(yīng)頭ctx.body = ctx.res.body = ctx.response.bodyKoa 提供一個 Context 對象,表示一次對話的上下文(包括 HTTP 請求和 HTTP 回復(fù))。通過加工這個對象,就可以控制返回給用戶的內(nèi)容。
Context.response.body 屬性就是發(fā)送給用戶的內(nèi)容。
const Koa = require('koa'); const app = new Koa();const main = ctx => {ctx.response.body = 'Hello World'; };app.use(main); app.listen(3000);上面代碼中,main函數(shù)用來設(shè)置 ctx.response.body 。然后,使用 app.use 方法加載main函數(shù)。
你可能已經(jīng)猜到了,ctx.response代表 HTTP Response。同樣地,ctx.request代表 HTTP Request。
運行這個 demo,訪問 http://127.0.0.1:3000 ,現(xiàn)在就可以看到"Hello World"了。
參考:koa2中的ctx是什么?
koa2中 query 和 querystring
在 koa 中,GET請求獲取請求數(shù)據(jù)request對象中的 query 方法和 querystring 方法, query方法返回的是格式化好的參數(shù),querystring 方法返回的是請求字符串。
koa2如何獲取get方式的路由參數(shù),比如xxx?name=123 獲取name值
ctx.request.query // => {name: '123'} ctx.query // => {name: '123'}ctx.request 是 Koa 請求對象。可以通過 querystring 獲取請求路徑中的 query 字符串,通過 query 獲取格式化好的參數(shù)。
ctx.query 是 route.query 的別名。
閱讀過:nuxt - nuxtServerInit & 頁面渲染前的store處理 & context
koa2 使用passport權(quán)限認證中間件
參考:koa2 使用passport權(quán)限認證中間件
序列化和反序列化
更多內(nèi)容參考:了解護照序列化反序列化
故名思議就是將結(jié)構(gòu)化的對象轉(zhuǎn)換為字節(jié)序列,反之就叫做反序列化。
為什么要序列化和反序列化?
內(nèi)存當中的對象是結(jié)構(gòu)化的,當你需要將這個對象在網(wǎng)絡(luò)當中傳輸?shù)臅r候,或者要保存到文件或者數(shù)據(jù)庫當中的時候,你就需要將它序列化成字節(jié)流,便于處理。
而反過來,傳輸過去之后,或者從文件和數(shù)據(jù)庫里讀取出來的時候,又要重新構(gòu)建恢復(fù)出原來的對象。
類比就是,比如我們打電話,電線不能直接傳聲音,需要把聲音轉(zhuǎn)換為電流,過去再把電流轉(zhuǎn)換為聲音。
為什么utils/axios.js 要創(chuàng)建一個實例
以下內(nèi)容參考: nuxt.js 官方中文文檔
如果您的項目中直接使用了 node_modules 中的 axios ,并且使用 axios.interceptors 添加攔截器對請求或響應(yīng)數(shù)據(jù)進行了處理,確保使用 axios.create 創(chuàng)建實例后再使用。否則多次刷新頁面請求服務(wù)器,服務(wù)端渲染會重復(fù)添加攔截器,導(dǎo)致數(shù)據(jù)處理錯誤。
import axios from 'axios' const myaxios = axios.create({// ... }) myaxios.interceptors.response.use(function (response) {return response.data }, function (error) {// ... })結(jié)尾
如若本文有瑕疵需修改的地方,請?zhí)岢鰜?#xff0c;謝謝您的貢獻!
歡迎關(guān)注微信公眾號:小獅子前端Vue
謝謝您的支持!??ヽ(°▽°)ノ?
學如逆水行舟,不進則退總結(jié)
以上是生活随笔為你收集整理的【Vue全家桶+SSR+Koa2全栈开发】项目搭建过程 整合 学习目录(持续更新中)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑死机故障解决方法全面汇总
- 下一篇: html5倒计时秒杀怎么做,vue 设