日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

vue 请求多个api_Vue 创建多人共享博客

發(fā)布時間:2025/3/21 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue 请求多个api_Vue 创建多人共享博客 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多人共享博客

上一個項(xiàng)目:仿 CNODE 社區(qū) 剛完成,感覺有點(diǎn)意猶未盡,對于 登錄 這一塊老師并沒有展開,我先是用了 localStorage 自己瞎搞,跑通之后想了下,vuex 不是專門做全局狀態(tài)管理的么?那么用 vuex 做登錄是最合適不過的呀。于是又搜了些別人用 vuex 做登錄狀態(tài)管理的案例,算是搞明白了。

現(xiàn)在選擇了若愚老師的這個項(xiàng)目,主要是鞏固一下對 vue 的認(rèn)識,同時對 vuex 做個更詳細(xì)的了解。本項(xiàng)目做一款多人共享博客,包含首頁、用戶文章列表、登錄、注冊、個人管理、編輯、發(fā)布等功能。

測試賬號: hunger10086

測試密碼: 123456

實(shí)現(xiàn)功能:用戶的登錄、注冊、注銷

首頁多人博客展示

用戶博文展示

我的頁面博文展示及管理

博文的創(chuàng)建、編輯、刪除、發(fā)布

使用 Vue.js 技術(shù)棧:vue-cli / vue2 / axios / vue-router /vuex / es6 / webpack / element-ui

博客主要記錄項(xiàng)目完成過程中學(xué)習(xí)到的知識點(diǎn),其他的就一筆帶過了。

項(xiàng)目初始化

在 vue 項(xiàng)目中使用 less:

如果要在某個組件中引入 less 文件,則在 style 中寫入 @import '../assets/base.less'; 即可(記得 npm 裝上 less 和 less-loader 哦)

ElementUI 的使用

ElementUI 的有很詳細(xì)的安裝使用文檔

主要步驟:

1.安裝 cnpm i element-ui

2.引入

import ElementUI from 'element-ui';

import 'element-ui/lib/theme-chalk/index.css';

3.掛載到 Vue Vue.use(ElementUI)

然后就可以在組件中使用 element-ui 了。

數(shù)據(jù)請求接口封裝

另外,若愚老師前期還對 axios 底層請求做了進(jìn)一步的定制和封裝,其中一些技巧很值得學(xué)習(xí)。

1.先把 axios 請求封裝成了輸入?yún)?shù)更簡潔明了、報(bào)錯信息更「人性化」的 Promise 對象。

// /helpers/request.jsaxios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

axios.defaults.baseURL = 'http://blog-server.hunger-valley.com'

axios.defaults.withCredentials = true

export default function request(url, type = 'GET', data = {}) {

return new Promise((resolve, reject) => {

let option = {

url,

method: type

}

if(type.toLowerCase() === 'get') {

option.params = data

}else {

option.data = data

}

axios(option).then(res => {

console.log(res.data)

if(res.data.status === 'ok') {

resolve(res.data)

}else{

Message.error(res.data.msg)

reject(res.data)

}

}).catch(err => {

Message.error('網(wǎng)絡(luò)異常')

reject({ msg: '網(wǎng)絡(luò)異常' })

})

})

}

2.再把獲取數(shù)據(jù)的 API 進(jìn)行封裝,使其更易用:

import request from '@/helpers/request'

const URL = {

REGISTER: '/auth/register',

LOGIN: '/auth/login',

LOGOUT: '/auth/logout',

GET_INFO: '/auth'

}

export default {

// 注冊 register({username, password}) {

return request(URL.REGISTER, 'POST', { username, password })

},

// 登錄 login({username, password}) {

return request(URL.LOGIN, 'POST', { username, password })

},

// 登出 logout() {

return request(URL.LOGOUT)

},

// 獲取信息 getInfo() {

return request(URL.GET_INFO)

}

}

這樣子處理的話,登錄請求就可以不使用 axios('http://blog-server.hunger-valley.com/auth/login','POST',{username,password}) 那么繁瑣了,直接 auth.login({username,password}) 就完事了~

grid

使用 grid 進(jìn)行布局。

關(guān)于 grid 布局之前有了解過,grid 通過在頁面上劃分 columns 和 rows ,然后把內(nèi)容分別放進(jìn)不同區(qū)域來建立布局,也寫過 demo,但真正在項(xiàng)目中使用還是第一次。關(guān)于 grid 的教程可以參考這里

如在項(xiàng)目中的使用:

#app {

display: grid;

// 分成三列,左右列寬度分別是頁面的12%,中間內(nèi)容寬度自適應(yīng)

grid-template-columns: 12% auto 12%;

// 分成三行,上下行高度自適應(yīng),中間內(nèi)容占滿剩余寬度

grid-template-rows: auto 1fr auto;

// 劃分區(qū)域

grid-template-areas: "header header header"

". main . "

"footer footer footer";

#header{

grid-area: header;

padding-left: 12%;

padding-right: 12%;

}

#main{

grid-area: main;

}

#footer{

grid-area: footer;

padding-left: 12%;

padding-right: 12%;

}

}

async/await

在完成項(xiàng)目的過程中接觸到了 async/await :

async/await 是異步編程的一種解決方案。

async 聲明一個函數(shù)為異步函數(shù),這個函數(shù)返回的是一個 Promise 對象;

await 用于等待一個 async 函數(shù)的返回值(注意到 await 不僅僅用于等 Promise 對象,它可以等任意表達(dá)式的結(jié)果,所以,await 后面實(shí)際是可以接普通函數(shù)調(diào)用或者直接量的。)

以項(xiàng)目中用戶注冊為例:

// 聲明 register 為一個異步函數(shù),他會返回一個 Promise 對象async register({commit},{username,password}){

// 用戶注冊成功后后會返回的一個 Promise 對象,其中包含了用戶的信息,let res 就是異步 auth.register 獲取的結(jié)果 let res = await auth.register({username,password})

commit('setUser',{user:res.data})

commit('setLogin',{isLogin:true})

// 把 res.data 返回出去,使用 register() 后就可以用 then 來處理這個結(jié)果 return res.data

},

對于 async/await,我參考了 邊城 在 segmentfault 中的這邊文章。

Vuex

如何在項(xiàng)目中使用 vuex 管理狀態(tài)?(以登錄為例)1.創(chuàng)建store,定義 state/getters/mutations/actions由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會集中到一個比較大的對象。當(dāng)應(yīng)用變得非常復(fù)雜時,store 對象就有可能變得相當(dāng)臃腫。 為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割

在這里針對不同的內(nèi)容狀態(tài)管理劃分到不同的文件,保持可讀性:

store

|

│ index.js // 引入子模塊

└─modules

auth.js // 負(fù)責(zé)用戶注冊、登錄狀態(tài)

blog.js // 負(fù)責(zé)用戶獲取、發(fā)布、修改博客等

把負(fù)責(zé)用戶注冊登錄的 state 寫在了 auth.js:

// auth.jsimport auth from '@/api/auth'

const state = {

// 先定義一個默認(rèn)的用戶狀態(tài) user:null,

//登錄狀態(tài) isLogin:false

}

const getters = {

// 獲取 state 數(shù)據(jù) user:state => state.user,

isLogin:state => state.isLogin

}

const mutations = {

// 更新用戶數(shù)據(jù) setUser(state,payload){

state.user = payload.user

},

// 更新用戶登錄狀態(tài) setLogin(state,payload){

state.isLogin = payload.isLogin

}

}

const actions = {

...

// 檢測用戶是否登錄 async checkLogin({commit,state}){

// 先從本地store的state去看用戶是否登錄,如果登錄了 就返回true if(state.isLogin) return true

let res = await auth.getInfo()

commit('setLogin',{isLogin:res.isLogin})

// 如果本地沒有這個狀態(tài),就發(fā)ajax請求去服務(wù)器,服務(wù)器會返回一個isLogin的響應(yīng),根據(jù)這個值來確定是否登錄 if(!res.isLogin) return false

commit('setUser',{user:res.data})

// 最后的 return true 是為了在實(shí)例中then拿到這個true,方便做下一步處理 return true

},

// 用戶登錄 {commit} 是默認(rèn)參數(shù),相當(dāng)于 context.commit,使用了 ES6 的參數(shù)結(jié)構(gòu) login({commit},{username,password}){

// 調(diào)用底層接口,返回的是一個 Promise 對象 return auth.login({username,password})

.then(res => {

// 把通過 axios 獲取回來的用戶數(shù)據(jù)提交 mutation,更新到 state: commit -> setUser -> state commit('setUser',{user:res.data})

commit('setLogin',{isLogin:true})

})

},

...

}

export default {

state,

getters,

mutations,

actions

}2.在 /store/index.js 把模塊引入進(jìn)來:

// index.jsimport Vue from 'vue'

import Vuex from 'vuex'

import auth from './modules/auth'

Vue.use(Vuex)

export default new Vuex.Store({

modules:{

auth,

}

})3.在相關(guān)組件中映射屬性,commit 更新

在 Login.vue 中,我們要做的事情就是:點(diǎn)擊按鈕后,調(diào)用 auth.js 中的 login() 方法,完成登錄,更新 state 中的數(shù)據(jù),并給需要的組件更新狀態(tài)(如 header.vue)

首先映射 login 方法到此組件,這樣此組件就可以通過 this.login 來調(diào)用這個 auth.js 中的方法了:

//Login.vueimport {mapActions} from 'vuex'

export default {

name:'Login',

methods:{

...mapActions([

'login'

]),

},

}

接著設(shè)置點(diǎn)擊事件,點(diǎn)擊按鈕會執(zhí)行 onLogin,調(diào)用 this.login ,發(fā)送 axios 請求 auth.login({username,password}),成功注冊后 commit mutation,更新 state 數(shù)據(jù),跳轉(zhuǎn)到首頁:

立即登錄

//Login.vue

methods:{

...mapActions([

'login'

]),

onLogin(){

this.login({username:this.username,password:this.password})

.then(()=>{

console.log(`${this.username},${this.password}`)

this.$router.push({path:'/'})

})

}

},4.在相關(guān)組件中關(guān)聯(lián) state 數(shù)據(jù),實(shí)現(xiàn)狀態(tài)切換

在 Header 中,登錄和未登錄,他的樣式在兩種狀態(tài)下是不一樣的:

未登錄的時候,header 會顯示提示登錄和注冊的按鈕;登錄之后,header 會顯示用戶頭像及其他操作選項(xiàng)。

而這兩種狀態(tài)的切換,就要依靠我們的 state 了,首先引入映射 {mapGetters,mapActions},在頁面還未渲染的時候檢查 state 中用戶登錄狀態(tài),用戶已登錄,則返回 isLogin = true ,獲取用戶信息,渲染到頁面上;用戶未登錄,則返回 isLogin = false。

// Header.vue

import {mapGetters,mapActions} from 'vuex'

export default {

name:'Header',

// 把 store 中 getter 屬性映射到此組件

computed:{

...mapGetters([

'isLogin',

'user'

])

},

//在頁面沒有渲染之前檢查用戶是否登錄

created(){

this.checkLogin()

},

methods:{

// 把 auth.js 中的 checkLogin 方法映射到此組件

...mapActions([

'checkLogin'

]),

},

這就是 vuex 在在項(xiàng)目中管理登錄狀態(tài)了。

完善路由

項(xiàng)目中有一些頁面,比如添加文章、編輯文章等等,都需要先確認(rèn)用戶是否登錄才能操作,否則將會自動跳轉(zhuǎn)到登錄頁。

路由元信息做的就是這樣一件事情,我們給某段路由添加一個 meta 字段 meta:{ requiresAuth:true },這段路由路由匹配到的所有路由記錄會暴露為 $route 對象 (還有在導(dǎo)航守衛(wèi)中的路由對象) 的 $route.matched 數(shù)組。通過遍歷 $route.matched 來檢查路由記錄中的 meta 字段,對訪問的路徑做一個狀態(tài)檢查,從而確定是否允許訪問。

const router = new Router({

routes: [

...

{

path: '/Create',

component: () =>import ('@/pages/Create/Create'),

// 路由添加 meta 字段 meta:{ requiresAuth:true }

},

...

]

})

router.beforeEach((to, from, next) => {

if (to.matched.some(record => record.meta.requiresAuth)) {

// 如果 store.dispatch('checkLogin') 返回的結(jié)果 isLogin 為 false,則說明用戶沒有登錄,就會跳轉(zhuǎn)到 /login store.dispatch('checkLogin').then(isLogin=>{

if (!isLogin) {

next({

path: '/login',

query: { redirect: to.fullPath }

})

} else {

next()

}

})

} else {

next() // 確保一定要調(diào)用 next() }

})

懶加載

小技巧 - 按需加載,節(jié)約性能:按需加載的適用場景,比如說「訪問某個路由的時候再去加載對應(yīng)的組件」,用戶不一定會訪問所有的路由,所以沒必要把所有路由對應(yīng)的組件都先在開始的加載完;更典型的例子是「某些用戶他們的權(quán)限只能訪問某些頁面」,所以沒必要把他們沒權(quán)限訪問的頁面的代碼也加載。

// beforeimport Index from '@/pages/Index/Index'

const router = new Router({

routes: [

{

path: '/',

component: Index

},

...

]

})

// afterconst router = new Router({

routes: [

{

path: '/',

component: () =>import ('@/pages/Index/Index')

},

...

]

})

marked

使用 marked.js 對 markdown 內(nèi)容進(jìn)行轉(zhuǎn)換:

文章詳情頁(Detail)中,通過服務(wù)器返回的文章內(nèi)容是 markdown 格式的,先用 marked.js 庫處理一下,再使用 v-html 渲染到頁面中。

1.安裝 cnpm install marked

2.在組件中引入 import marked from 'marked'

3.把內(nèi)容進(jìn)行轉(zhuǎn)換:

computed:{

markdown(){

return marked(this.rawContent) //this.rawContent 是從服務(wù)器獲取的文章正文 }

},

4.在頁面中引入:

vue-devtools

最后介紹一款小插件,可以在使用 vue 開發(fā)的時候更好地調(diào)試和 debug。vue-devtools是一款基于chrome游覽器的插件,用于調(diào)試vue應(yīng)用,這可以極大地提高我們的調(diào)試效率。當(dāng)我們添加完vue-devtools擴(kuò)展程序之后,我們在調(diào)試vue應(yīng)用的時候,chrome開發(fā)者工具中會看一個vue的一欄,點(diǎn)擊之后就可以看見當(dāng)前頁面vue對象的一些信息。

總結(jié)

以上是生活随笔為你收集整理的vue 请求多个api_Vue 创建多人共享博客的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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