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