日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

【Vue全家桶+SSR+Koa2全栈开发】项目搭建过程 整合 学习目录(持续更新中)

發(fā)布時間:2023/12/8 vue 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Vue全家桶+SSR+Koa2全栈开发】项目搭建过程 整合 学习目录(持续更新中) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

寫在開頭

大家好,這里是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 vuex

Koa2基礎(chǔ)


koa-generator

管理員身份打開cmd,運行如下代碼,全局安裝

npm install -g koa-generator

使用git bash,在文件夾內(nèi)創(chuàng)建項目

koa2 -e project_name

-e 表示使用ejs,不加和 node 一樣


接下來,執(zhí)行安裝命令

cd koa2_learn npm install

安裝&更新 fsevents 包

npm install --update-binary

run app命令:

DEBUG=koa2_learn:* npm start

執(zhí)行后輸出 node bin/www 說明服務(wù)端已經(jīng)跑起來了

訪問 http://localhost:3000/ 查看頁面效果


我們查看 package.json ,發(fā)現(xiàn)啟動腳本是通過 npm scripts ,如果你想要自啟動的話,執(zhí)行如下命令:

npm run dev


對于上述執(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 文件,配置如下代碼

module.exports = {dbs: 'mongodb://127.0.0.1:27017/dbs' }

在 dbs 目錄下創(chuàng)建 名為 models 的文件夾

新建一個 person.js 文件,配置如下代碼(此時的文件名對應(yīng)著之后我們的“表名”,也就是 Collections)

const mongoose = require('mongoose')//創(chuàng)建模式 let personSchema = new mongoose.Schema({name: String,age: Number })//創(chuàng)建模型 module.exports = mongoose.model('Person',personSchema)

然后在 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,親測有效嗷

//更新api router.post('/updatePerson',async function(ctx){const result = await Person.where({name:ctx.request.body.name}).update({age: ctx.request.body.age})ctx.body = {code: 0,} }) //刪除api router.post('/removePerson',async function(ctx){const result = await Person.where({name:ctx.request.body.name}).remove()ctx.body = {code: 0,} })

更多知識點請參考: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 cnpm

eslint版本問題: 需要更新eslint版本

解決:執(zhí)行如下代碼:

npm install eslint-plugin-html@^3

執(zhí)行完如下步驟后,最后一步,打開服務(wù):

npm run dev

babel編譯版本有問題: 解決辦法是升級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)目標文件的第一行代碼:

改為如下代碼

import Koa from 'koa'

于是,就會出現(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-sass

PS:可能會有下述 warn

npm install eslint@^(版本號) //(注意,這里是當你出現(xiàn)對應(yīng)warn才執(zhí)行)

我的是這種警告,因此依葫蘆畫瓢,執(zhí)行下述命令

npm install sass@^1.3.0 fibers@>= 3.1.0

輔助工具安裝

  • 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-json

Cannot read property ‘post’ of undefined 問題解決

注冊那一個模塊那里,我一點發(fā)送驗證碼,然后就報了這個錯誤,一開始以為接口寫錯了,還測試了一下,原來是因為 axios 沒有在 nuxt 腳手架中配置

Cannot read property 'name' of undefined

nuxt.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.body

Koa 提供一個 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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。