如何使用Vuex+Vue.js構(gòu)建單頁(yè)應(yīng)用
前言:在最近學(xué)習(xí) Vue.js 的時(shí)候,看到國(guó)外一篇講述了如何使用 Vue.js 和 Vuex 來(lái)構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁(yè)應(yīng)用的文章。感覺(jué)收獲挺多,自己在它的例子的基礎(chǔ)上進(jìn)行了一些優(yōu)化和自定義功能,在這里和大家分享下學(xué)習(xí)心得。
在這篇教程中我們將通過(guò)構(gòu)建一個(gè)筆記應(yīng)用來(lái)學(xué)習(xí)如何在我們的 Vue 項(xiàng)目中使用 Vuex。我們將大概的過(guò)一遍什么是 Vuex.js,在項(xiàng)目中什么時(shí)候使用它,和如何構(gòu)建我們的 Vue 應(yīng)用。
這里放一張我們項(xiàng)目的預(yù)覽圖片:

項(xiàng)目源碼:vuex-notes-app;有需要的同學(xué)可以直接下載源碼查看。
主要知識(shí)點(diǎn)
Vuex 狀態(tài)管理機(jī)制的使用
Vue.js 的基礎(chǔ) api
Vue-cli 腳手架的安裝及使用
vur-router 的使用
ES6 的語(yǔ)法,這里推薦看下阮一峰的入門(mén)教程
Vuex 概述
在我們迫不及待的開(kāi)始項(xiàng)目之前,我們最好先花幾分鐘來(lái)了解下 Vuex 的核心概念。
Vuex 是一個(gè)專(zhuān)門(mén)為 Vue.js 應(yīng)用所設(shè)計(jì)的集中式狀態(tài)管理架構(gòu)。它借鑒了 Flux 和 Redux 的設(shè)計(jì)思想,但簡(jiǎn)化了概念,并且采用了一種為能更好發(fā)揮 Vue.js 數(shù)據(jù)響應(yīng)機(jī)制而專(zhuān)門(mén)設(shè)計(jì)的實(shí)現(xiàn)。
state 這樣概念初次接觸的時(shí)候可能會(huì)感覺(jué)到有點(diǎn)模糊,簡(jiǎn)單來(lái)說(shuō)就是將 state 看成我們項(xiàng)目中使用的數(shù)據(jù)的集合。然后,Vuex 使得 組件本地狀態(tài)(component local state)和 應(yīng)用層級(jí)狀態(tài)(application state) 有了一定的差異。
component local state:該狀態(tài)表示僅僅在組件內(nèi)部使用的狀態(tài),有點(diǎn)類(lèi)似通過(guò)配置選項(xiàng)傳入 Vue 組件內(nèi)部的意思。
application level state:應(yīng)用層級(jí)狀態(tài),表示同時(shí)被多個(gè)組件共享的狀態(tài)層級(jí)。
假設(shè)有這樣一個(gè)場(chǎng)景:我們有一個(gè)父組件,同時(shí)包含兩個(gè)子組件。父組件可以很容易的通過(guò)使用 props 屬性來(lái)向子組件傳遞數(shù)據(jù)。
但是問(wèn)題來(lái)了,當(dāng)我們的兩個(gè)子組件如何和對(duì)方互相通信的? 或者子組件如何傳遞數(shù)據(jù)給他父組件的?在我們的項(xiàng)目很小的時(shí)候,這個(gè)兩個(gè)問(wèn)題都不會(huì)太難,因?yàn)槲覀兛梢酝ㄟ^(guò)事件派發(fā)和監(jiān)聽(tīng)來(lái)完成父組件和子組件的通信。
然而,隨著我們項(xiàng)目的增長(zhǎng):
1、保持對(duì)所有的事件追蹤將變得很困難。到底哪個(gè)事件是哪個(gè)組件派發(fā)的,哪個(gè)組件該監(jiān)聽(tīng)哪個(gè)事件?
2、項(xiàng)目邏輯分散在各個(gè)組件當(dāng)中,很容易導(dǎo)致邏輯的混亂,不利于我們項(xiàng)目的維護(hù)。
3、父組件將變得和子組件耦合越來(lái)越嚴(yán)重,因?yàn)樗枰鞔_的派發(fā)和監(jiān)聽(tīng)子組件的某些事件。
這就是 Vuex 用來(lái)解決的問(wèn)題。 Vuex 的四個(gè)核心概念分別是:
The state tree:Vuex 使用單一狀態(tài)樹(shù),用一個(gè)對(duì)象就包含了全部的應(yīng)用層級(jí)狀態(tài)。至此它便作為一個(gè)『唯一數(shù)據(jù)源(SSOT)』而存在。這也意味著,每個(gè)應(yīng)用將僅僅包含一個(gè) store 實(shí)例。單狀態(tài)樹(shù)讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過(guò)程中也能輕易地取得整個(gè)當(dāng)前應(yīng)用狀態(tài)的快照。
Getters:用來(lái)從 store 獲取 Vue 組件數(shù)據(jù)。
Mutators:事件處理器用來(lái)驅(qū)動(dòng)狀態(tài)的變化。
Actions:可以給組件使用的函數(shù),以此用來(lái)驅(qū)動(dòng)事件處理器 mutations
如何你暫時(shí)還不太理解這個(gè)四個(gè)概念,不用著急,我們將在后面的項(xiàng)目實(shí)戰(zhàn)中詳細(xì)的解釋。
下面這張圖詳細(xì)的解釋了 Vuex 應(yīng)用中數(shù)據(jù)的流向(Vuex 官方圖)

簡(jiǎn)單解釋下:
Vuex 規(guī)定,屬于應(yīng)用層級(jí)的狀態(tài)只能通過(guò) Mutation 中的方法來(lái)修改,而派發(fā) Mutation 中的事件只能通過(guò) action。
從左到又,從組件出發(fā),組件中調(diào)用 action,在 action 這一層級(jí)我們可以和后臺(tái)數(shù)據(jù)交互,比如獲取初始化的數(shù)據(jù)源,或者中間數(shù)據(jù)的過(guò)濾等。然后在 action 中去派發(fā) Mutation。Mutation 去觸發(fā)狀態(tài)的改變,狀態(tài)的改變,將觸發(fā)視圖的更新。
注意事項(xiàng)
數(shù)據(jù)流都是單向的
組件能夠調(diào)用 action
action 用來(lái)派發(fā) Mutation
只有 mutation 可以改變狀態(tài)
store 是響應(yīng)式的,無(wú)論 state 什么時(shí)候更新,組件都將同步更新
環(huán)境安裝
這個(gè)應(yīng)用將使用 webpack 來(lái)做模塊打包,處理和熱重啟。使用 Vue 官方提供的腳手架 vue-cli。
安裝 vue-cli
npm install -g vue-cli
注:Node.js >= 4.x, 5.x 最好
初始化應(yīng)用
vue init webpack vue-notes-app cd vue-notes-app npm install // 安裝依賴(lài)包 npm run dev // 啟動(dòng)服務(wù)
初始化一個(gè)項(xiàng)目名為vue-notes-app的應(yīng)用,并選擇使用 webpack 打包方式。在命令行中按照提示選擇初始化配置項(xiàng)。其中在選擇 JSLint 校驗(yàn)的時(shí)候,推薦選擇 AirBNB 規(guī)范。
使用你最喜歡的編輯器打開(kāi)我們剛剛新建的項(xiàng)目,項(xiàng)目的結(jié)構(gòu)大概如下圖:

components/ 文件夾用來(lái)存放我們的 Vue 組件
vuex/ 文件夾存放的是和 Vuex store 相關(guān)的東西(state object,actions,mutators)
build/ 文件是 webpack 的打包編譯配置文件
config/ 文件夾存放的是一些配置項(xiàng),比如我們服務(wù)器訪問(wèn)的端口配置等
dist/ 該文件夾一開(kāi)始是不存在,在我們的項(xiàng)目經(jīng)過(guò) build 之后才會(huì)產(chǎn)出
App.vue 根組件,所有的子組件都將在這里被引用
index.html 整個(gè)項(xiàng)目的入口文件,將會(huì)引用我們的根組件 App.vue
main.js 入口文件的 js 邏輯,在 webpack 打包之后將被注入到 index.html 中
功能模塊
新增筆記,新增一篇筆記,編輯區(qū)顯示空的筆記內(nèi)容
刪除筆記,刪除一篇筆記之后,編輯區(qū)域顯示當(dāng)前筆記類(lèi)別的第一項(xiàng)
筆記列表切換,分為全部筆記和收藏筆記兩種,在切換之后,編輯區(qū)域顯示當(dāng)前列表的第一條筆記
收藏筆記,給當(dāng)前激活的筆記打上收藏的標(biāo)簽
項(xiàng)目組件劃分
在這個(gè)項(xiàng)目中,我們將總共使用四個(gè)組件:根組件 App.vue,操作欄組件 Toolbar.vue,別表組件 NotesList.vue,筆記編輯組件 Editor.vue。

創(chuàng)建 Vuex Store
按照上面我們列出來(lái)的功能模塊,我們?cè)?Vuex/ 下面建立一個(gè) store.js 文件。
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
// 需要維護(hù)的狀態(tài)
const state = {
notes: [],
activeNote: {},
show: ''
};
const mutations = {
// 初始化 state
INIT_STORE(state, data) {
state.notes = data.notes,
state.show = data.show;
state.activeNote = data.activeNote;
},
// 新增筆記
NEW_NOTE(state) {
var newNote = {
id: +new Date(),
title: '',
content: '',
favorite: false
};
state.notes.push(newNote);
state.activeNote = newNote;
},
// 修改筆記
EDIT_NOTE(state, note) {
state.activeNote = note;
// 修改原始數(shù)據(jù)
for (var i = 0; i < state.notes.length; i++) {
if(state.notes[i].id === note.id){
state.notes[i] = note;
break;
}
};
},
// 刪除筆記
DELETE_NOTE(state) {
state.notes.$remove(state.activeNote);
state.activeNote = state.notes[0] || {};
},
// 切換筆記的收藏與取消收藏
TOGGLE_FAVORITE(state) {
state.activeNote.favorite = !state.activeNote.favorite;
},
// 切換顯示數(shù)據(jù)列表類(lèi)型:全部 or 收藏
SET_SHOW_ALL(state, show){
state.show = show;
// 切換數(shù)據(jù)展示,需要同步更新 activeNote
if(show === 'favorite'){
state.activeNote = state.notes.filter(note => note.favorite)[0] || {};
}else{
state.activeNote = state.notes[0] || {};
}
},
// 設(shè)置當(dāng)前激活的筆記
SET_ACTIVE_NOTE(state, note) {
state.activeNote = note;
}
};
export default new Vuex.Store({
state,
mutations
});
創(chuàng)建 Vuex Actions
在 Vuex/ 下面建立一個(gè) action.js,用來(lái)給組件使用的函數(shù)。
function makeAction(type) {
return ({ dispatch }, ...args) => dispatch(type, ...args);
};
const initNote = {
id: +new Date(),
title: '我的筆記',
content: '第一篇筆記內(nèi)容',
favorite: false
};
// 模擬初始化數(shù)據(jù)
const initData = {
show: 'all',
notes: [initNote],
activeNote: initNote
};
export const initStore = ({ dispatch }) => {
dispatch('INIT_STORE', initData);
};
// 更新當(dāng)前activeNote對(duì)象
export const updateActiveNote = makeAction('SET_ACTIVE_NOTE');
// 添加一個(gè)note對(duì)象
export const newNote = makeAction('NEW_NOTE');
// 刪除一個(gè)note對(duì)象
export const deleteNote = makeAction('DELETE_NOTE');
export const toggleFavorite = makeAction('TOGGLE_FAVORITE');
export const editNote = makeAction('EDIT_NOTE');
// 更新列表展示
export const updateShow = makeAction('SET_SHOW_ALL');
創(chuàng)建 Vuex Getters
在 vuex/ 下面建立一個(gè) getter.js 文件,用來(lái)從 store 獲取數(shù)據(jù)。
// 獲取 noteList,這里將會(huì)根據(jù) state.show 的狀態(tài)做數(shù)據(jù)過(guò)濾
export const filteredNotes = (state) => {
if(state.show === 'all'){
return state.notes || {};
}else if(state.show === 'favorite'){
return state.notes.filter(note => note.favorite) || {};
}
};
// 獲取列表展示狀態(tài) : all or favorite
export const show = (state) => {
return state.show;
};
// 獲取當(dāng)前激活 note
export const activeNote = (state) => {
return state.activeNote;
};
以上就是我們 Vuex 的所有邏輯了,在定下了我們需要完成的功能之后,接下來(lái)就是只需要在組件中去調(diào)用 action 來(lái)實(shí)現(xiàn)對(duì)應(yīng)的功能了。
路由配置
在這里我們將使用 vue-router 來(lái)做路由,引用 bootstrap 樣式。
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vuex-notes-app</title> <link rel="stylesheet" > </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
所有的入口邏輯我們都將在 main.js 中編寫(xiě)
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import VueResource from 'vue-resource';
// 路由模塊和HTTP模塊
Vue.use(VueResource);
Vue.use(VueRouter);
const router = new VueRouter();
router.map({
'/index': {
component: App
}
});
router.redirect({
'*': '/index'
});
router.start(App, '#app');
根組件 App.vue
<template>
<div id="app" class="app">
<toolbar></toolbar>
<notes-list></notes-list>
<editor></editor>
</div>
</template>
<style>
html, #app {
height: 100%;
}
body {
margin: 0;
padding: 0;
border: 0;
height: 100%;
max-height: 100%;
position: relative;
}
</style>
<script>
import Toolbar from './components/Toolbar';
import NotesList from './components/NotesList';
import Editor from './components/Editor';
import store from './vuex/store';
import { initStore } from './vuex/actions';
export default {
components: {
Toolbar,
NotesList,
Editor
},
store,
vuex: {
actions: {
initStore
}
},
ready() {
this.initStore()
}
}
</script>
在根組件中引用了三個(gè)子組件:Toolbar.vue, NotesList.vue, Editor.vue。
注意:我們?cè)谂渲美锩婕尤肓?vuex 這么一個(gè)選項(xiàng),這里用來(lái)將我們 action 里面定義的方法給暴露出來(lái),我們?cè)诟M件中只做了一件事情,那就是初始化模擬數(shù)據(jù),因此我們?cè)诮M件生命周期的 ready 階段調(diào)用了 actions 里面的 initStore 來(lái)初始化我們的 store 里面的 state
Toolbar.vue
<template>
<div id="toolbar">
<i class="glyphicon logo"><img src="../assets/logo.png" width="30" height="30"></i>
<i @click="newNote" class="glyphicon glyphicon-plus"></i>
<i @click="toggleFavorite" class="glyphicon glyphicon-star" :class="{starred: activeNote.favorite}"></i>
<i @click="deleteNote" class="glyphicon glyphicon-remove"></i>
</div>
</template>
<script>
import { newNote, deleteNote, toggleFavorite } from '../vuex/actions';
import { activeNote } from '../vuex/getters';
export default {
vuex: {
getters: {
activeNote
},
actions: {
newNote,
deleteNote,
toggleFavorite
}
}
}
</script>
<style lang="scss" scoped>
#toolbar{
float: left;
width: 80px;
height: 100%;
background-color: #30414D;
color: #767676;
padding: 35px 25px 25px 25px;
.starred {
color: #F7AE4F;
}
i{
font-size: 30px;
margin-bottom: 35px;
cursor: pointer;
opacity: 0.8;
transition: opacity 0.5s ease;
&:hover{
opacity: 1;
}
}
}
</style>
在這里,我們用到了 Vuex 的一個(gè)案例就是我們需要知道當(dāng)前的激活的筆記是否是收藏類(lèi)別的,如果是,我們需要高亮收藏按鈕,那么如何知道呢?那就是通過(guò) vuex 里面的 getters 獲取當(dāng)前激活的筆記對(duì)象,判斷它的 favorite 是否為 true。
始終牢記一個(gè)概念,vuex 中數(shù)據(jù)是單向的,只能從 store 獲取,而我們這個(gè)例子中的 activeNote 也是始終都在 store.js 中維護(hù)的,這樣子就可以給其他組件公用了
// 需要維護(hù)的狀態(tài)
const state = {
notes: [],
activeNote: {},
show: ''
};
NotesList.vue
<template>
<div id="notes-list">
<div id="list-header">
<h2>Notes | heavenru.com</h2>
<div class="btn-group btn-group-justified" role="group">
<!-- all -->
<div class="btn-group" role="group">
<button type="button" class="btn btn-default"
@click="toggleShow('all')"
:class="{active: show === 'all'}">All Notes</button>
</div>
<!-- favorites -->
<div class="btn-group" role="group">
<button type="button" class="btn btn-default"
@click="toggleShow('favorite')"
:class="{active: show === 'favorite'}">Favorites</button>
</div>
</div>
</div>
<!-- 渲染筆記列表 -->
<div class="container">
<div class="list-group">
<a v-for="note in filteredNotes"
class="list-group-item" href="#"
:class="{active: activeNote === note}"
@click="updateActiveNote(note)">
<h4 class="list-group-item-heading">
{{note.title.trim().substring(0,30)}}
</h4>
</a>
</div>
</div>
</div>
</template>
<script>
import { updateActiveNote, updateShow } from '../vuex/actions';
import { show, filteredNotes, activeNote } from '../vuex/getters';
export default {
vuex: {
getters: {
show,
filteredNotes,
activeNote
},
actions: {
updateActiveNote,
updateShow
}
},
methods: {
toggleShow(show) {
this.updateShow(show);
}
}
}
</script>
筆記列表組件,主要有三個(gè)操作
渲染筆記
切換渲染筆記
點(diǎn)擊列表 title,切換 activeNote
我們通過(guò) getters 中的 filteredNotes 方法獲取筆記列表
// 獲取 noteList,這里將會(huì)根據(jù) state.show 的狀態(tài)做數(shù)據(jù)過(guò)濾
export const filteredNotes = (state) => {
if(state.show === 'all'){
return state.notes || {};
}else if(state.show === 'favorite'){
return state.notes.filter(note => note.favorite) || {};
}
};
可以看到,我們獲取的列表是依賴(lài)于 state.show 這個(gè)狀態(tài)的。而我們的切換列表操作恰好就是調(diào)用 actions 里面的方法來(lái)更新 state.show,這樣一來(lái),實(shí)現(xiàn)了數(shù)據(jù)列表的動(dòng)態(tài)刷新,而且我們對(duì)樹(shù)的操作都是通過(guò)調(diào)用 actions 的方法來(lái)實(shí)現(xiàn)的。
我們?cè)倏?,在切換列表的時(shí)候,我們還需要?jiǎng)討B(tài)的更新 activeNote??纯次覀?cè)?store.js 中是如何做的:
// 切換顯示數(shù)據(jù)列表類(lèi)型:全部 or 收藏
SET_SHOW_ALL(state, show){
state.show = show;
// 切換數(shù)據(jù)展示,需要同步更新 activeNote
if(show === 'favorite'){
state.activeNote = state.notes.filter(note => note.favorite)[0] || {};
}else{
state.activeNote = state.notes[0] || {};
}
}
觸發(fā)這些操作的是我們給兩個(gè)按鈕分別綁定了我們自定義的函數(shù),通過(guò)給函數(shù)傳入不同的參數(shù),然后調(diào)用 actions 里面的方法,來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)的過(guò)濾,更新。
Editor.vue
<template>
<div id="note-editor">
<div class="form-group">
<input type="text" name="title"
class="title form-control"
placeholder="請(qǐng)輸入標(biāo)題"
@input="updateNote"
v-model="currentNote.title">
<textarea
v-model="currentNote.content" name="content"
class="form-control" row="3" placeholder="請(qǐng)輸入正文"
@input="updateNote"></textarea>
</div>
</div>
</template>
<script>
import { editNote } from '../vuex/actions';
import { activeNote } from '../vuex/getters';
export default {
vuex: {
getters: {
activeNote
},
actions: {
editNote
}
},
computed: {
// 通過(guò)計(jì)算屬性得到的一個(gè)對(duì)象,這樣子我們就能愉快的使用 v-model 了
currentNote: activeNote
},
methods: {
// 為什么這么做? 因?yàn)樵趪?yán)格模式中不允許直接在模板層面去修改 state 中的值
updateNote() {
this.editNote(this.currentNote);
}
}
}
</script>
在 Editor.vue 組件中,我們需要能夠?qū)崟r(shí)的更新當(dāng)前的 activeNote 組件和列表中對(duì)應(yīng)的我們正在修改的筆記對(duì)象的內(nèi)容。
由于我們前面提到過(guò),在組件中是不允許直接修改 store.js在里面的狀態(tài)值的,所以在這里的時(shí)候,我們通過(guò)一個(gè)計(jì)算屬性,將 store 里面的狀態(tài)值賦值給一個(gè)對(duì)象,然后在自定義的 updateNotes() 方法中,去調(diào)用 action,同時(shí)傳入 currentNote 對(duì)象。
在 store.js 中,我們是這么做的,找到對(duì)應(yīng)的 id 的對(duì)象,重新賦值,因?yàn)榍懊嫣岬竭^(guò),我們的數(shù)據(jù)是響應(yīng)式的,在這里進(jìn)行了改變,對(duì)應(yīng)的視圖也將刷新改變,這樣一來(lái)就實(shí)現(xiàn)了實(shí)時(shí)編輯,實(shí)時(shí)渲染的功能了。
// 修改筆記
EDIT_NOTE(state, note) {
state.activeNote = note;
// 修改原始數(shù)據(jù)
for (var i = 0; i < state.notes.length; i++) {
if(state.notes[i].id === note.id){
state.notes[i] = note;
break;
}
};
},
Q&A
在這個(gè)項(xiàng)目中,我們并沒(méi)有引入 vue-resource 插件,只是自己模擬了部分的數(shù)據(jù),有興趣的同學(xué)可以自己去試試。
由于我們的例子相對(duì)簡(jiǎn)單,沒(méi)有涉及到很深入的東西,更深層次的研究需要大家花更多的時(shí)間去實(shí)踐了。
最后,再說(shuō)一句,在 action 里面,我們其實(shí)可以做的還有更多,比如根據(jù) id 動(dòng)態(tài)的異步獲取筆記內(nèi)容等等,這些有興趣的同學(xué)可以自己去嘗試,一點(diǎn)點(diǎn)的豐富這個(gè)例子。
原文地址:https://coligo.io/learn-vuex-by-building-notes-app/
本文已被整理到了《Vue.js前端組件學(xué)習(xí)教程》,歡迎大家學(xué)習(xí)閱讀。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
VUE子組件的watch不被觸發(fā)問(wèn)題及解決
這篇文章主要介紹了VUE子組件的watch不被觸發(fā)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Vue.js devtool插件安裝后無(wú)法使用的解決辦法
Vue.js devtool插件最近在開(kāi)發(fā)人員中很火,這篇文章主要為大家詳細(xì)介紹了Vue.js devtool插件安裝后無(wú)法使用,出現(xiàn)提示“vue.js not detected”的解決辦法2017-11-11
在vue中使用express-mock搭建mock服務(wù)的方法
這篇文章主要介紹了在vue中使用express-mock搭建mock服務(wù)的方法,文中給大家提到了在vue-test-utils 中 mock 全局對(duì)象的相關(guān)知識(shí) ,需要的朋友可以參考下2018-11-11
vue3使用reactive包裹數(shù)組正確賦值問(wèn)題
這篇文章主要介紹了vue3使用reactive包裹數(shù)組正確賦值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
vue項(xiàng)目啟動(dòng)出現(xiàn)cannot GET /服務(wù)錯(cuò)誤的解決方法
這篇文章主要介紹了vue項(xiàng)目啟動(dòng)出現(xiàn)cannot GET /服務(wù)錯(cuò)誤的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
在項(xiàng)目中封裝axios的實(shí)戰(zhàn)過(guò)程
這篇文章主要給大家介紹了關(guān)于如何在項(xiàng)目中封裝axios的相關(guān)資料,axios 請(qǐng)求的封裝,無(wú)非是為了方便代碼管理,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
vue如何修改el-form-item中的label樣式修改問(wèn)題
這篇文章主要介紹了vue如何修改el-form-item中的label樣式修改問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10

