完整原文地址見簡書
更多完整Vue筆記目錄敬請見《前端 Web 筆記 匯總目錄(Updating)》
本文內(nèi)容提要
VueCli部分
首先需要安裝nodejs
- 安裝完node會自動配套npm
- 使用
npm install nrm -g
用于調(diào)整 鏡像源年鸳,方便后續(xù)下載依賴- 這邊使用淘寶鏡像
npm uninstall vue-cli -g
檢查并清除 多余的舊版本- 使用
npm install -g @vue/cli[@版本號]
安裝 腳手架- 使用 腳手架 Vue Cli,從 創(chuàng)建項目 到 運(yùn)行項目 的過程
- 退出之后丸相,把剛剛創(chuàng)建的項目拉進(jìn)VSCode搔确,使用VSCode啟動項目
- 初始項目結(jié)構(gòu)解讀
- 源代碼在
src
下,main.js
是入口App.vue
文件 簡讀- 關(guān)于
HelloWorld.vue
文件- 單文件組件 的含義
- 基于工程實現(xiàn)TODOList案例 --- 單組件版[App.vue]
- 基于工程實現(xiàn)TODOList案例 --- 父子組件版[App.vue灭忠、ListItem.vue]
- Vue-Router部分
- 在代碼中使用Router
- Router的作用 及 簡述
- 首先看一下App.vue根組件怎么寫
- 解析一下這個多出來的
router/index.js
文件- view目錄下的文件
- 例程膳算,拓展一個Router頁面
- 補(bǔ)充:Router路由懶加載語法糖 簡述 與例程實戰(zhàn)
- VueX部分
- 首先需要創(chuàng)建項目
- --- 特性配置:
- package.json文件
- VueX簡述
- VueX 框架的引入、數(shù)據(jù)的定義 以及 在組件中的使用
- 在Home.vue中 使用這個 VueX提供的 全局?jǐn)?shù)據(jù)字段:
- 如何在任一組件中 修改 VueX的 數(shù)據(jù)
- VueX的異步操作 同步操作
- 帶參數(shù)地 修改VueX數(shù)據(jù)
- VueX修改數(shù)據(jù) 流程設(shè)計的理解
- 安裝弛作、使用axios發(fā)送ajax請求
- 把上例的axios請求 封裝到 actions中
VueCli部分
首先需要安裝nodejs
參考博客:
--- Install Node.js
--- Node.js 安裝配置
安裝完node會自動配套npm
使用npm install nrm -g
用于調(diào)整 鏡像源涕蜂,方便后續(xù)下載依賴
安裝完了注意,
如C:\Users\凌川江雪\AppData\Roaming\npm\nrm -> C:\Users\凌川江雪\AppData\Roaming\npm\node_modules\nrm\cli.js
乃是依賴的安裝代碼路徑映琳;
nrm ls
可以切換鏡像源:
安裝后使用時萨西,你可能遇到這個問題:
D:\OK\nodejsOther>nrm ls internal/validators.js:124 throw new ERR_INVALID_ARG_TYPE(name, 'string', value); ^ [TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type >string. Received undefined at validateString (internal/validators.js:124:11) at Object.join (path.js:375:7) at Object.<anonymous> (C:\Users\凌川江雪>\AppData\Roaming\npm\node_modules\nrm\cli.js:17:20) at Module._compile (internal/modules/cjs/loader.js:1063:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) at Module.load (internal/modules/cjs/loader.js:928:32) at Function.Module._load (internal/modules/cjs/loader.js:769:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) at internal/main/run_main_module.js:17:47 ] { code: 'ERR_INVALID_ARG_TYPE' }
這邊使用淘寶鏡像
npm uninstall vue-cli -g
檢查并清除 多余的舊版本
使用npm install -g @vue/cli[@版本號]
安裝 腳手架
腳手架沉淀了許多最佳實踐有鹿,
可以借助它快速生成Vue工程,包括 項目目錄組織谎脯、webpack打包配置等葱跋;
使用 腳手架 Vue Cli,從 創(chuàng)建項目 到 運(yùn)行項目 的過程
命令:vue create [項目名]
如vue create demo-pro
穿肄;
運(yùn)行創(chuàng)建命令之后年局,工具會詢問創(chuàng)建方式:
接著矢否,進(jìn)入選擇特性界面:
這里選擇以上三個特性即可僵朗,然后回車:
回車確定;
這里先選擇第一個悴了,回車確定;
config文件
违寿,放一個單獨的文件
里湃交,還是放一個package.json
里,這里先選第一個藤巢;
回車后工程開始創(chuàng)建:
工程創(chuàng)建完成:
使用
npm run serve
啟動工程:ctrl + c
兩次可以終止運(yùn)行:退出之后绍刮,把剛剛創(chuàng)建的項目拉進(jìn)VSCode温圆,使用VSCode啟動項目
因為我們無需每次都用cmd
去啟動項目;
【剛拉進(jìn)來可能啟動不了,報9009之類的錯澈圈,
這時候重啟一下VSCode就是了彬檀;
如果項目中沒有
node_modules
,則需先運(yùn)行
npm install
安裝node_modules
依賴K才窍帝!】初始項目結(jié)構(gòu)解讀
注意要在VS code中安裝
vetur
這個插件,
使得VS可以提供 語法高亮诽偷、提示 等效果:
源代碼在src
下坤学,main.js是入口
--- import { createApp } from 'vue'
指明createApp
的來源;
--- import App from './App.vue'
指明App
實例报慕,來自于當(dāng)前文件夾下的 App.vue
文件深浮;
--- createApp(App).mount('#app')
則
創(chuàng)建實例、掛載實例:
App.vue
文件 簡讀
--- <template>標(biāo)簽對的內(nèi)容眠冈,
其實就等價于之前在組件實例中寫的template:
鍵模板飞苇;
--- <script>和<style>標(biāo)簽對自然就是js和樣式的“根據(jù)地了”;
--- 其中<script>
中的 name
指定了根組件實例名,
component
這里引入了一個子組件
HelloWorld布卡,
子組件從import HelloWorld from './components/HelloWorld.vue'
雨让,
可以看出其定義的地方,即 components
文件夾目錄下的HelloWorld.vue
忿等;
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
關(guān)于HelloWorld.vue
文件
看了一下結(jié)構(gòu)栖忠,其實也沒什么特殊的了,
跟上面App.vue
的結(jié)構(gòu)大體都是一樣的:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a target="_blank" rel="noopener">babel</a></li>
<li><a target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a target="_blank" rel="noopener">Core Docs</a></li>
<li><a target="_blank" rel="noopener">Forum</a></li>
<li><a target="_blank" rel="noopener">Community Chat</a></li>
<li><a target="_blank" rel="noopener">Twitter</a></li>
<li><a target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a target="_blank" rel="noopener">vue-router</a></li>
<li><a target="_blank" rel="noopener">vuex</a></li>
<li><a target="_blank" rel="noopener">vue-devtools</a></li>
<li><a target="_blank" rel="noopener">vue-loader</a></li>
<li><a target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
單文件組件 的含義
顧名思義贸街,即一個組件就代表了一個組件庵寞,
如上的App.vue
、HelloWorld.vue
都是單文件組件匾浪;
單獨一個文件內(nèi)容皇帮,就是完整的 HTML(<template>) + CSS(<style>) + JS(<script>)
結(jié)構(gòu)了;
基于工程實現(xiàn)TODOList案例 --- 單組件版[App.vue]
<template>
<div>
<input v-model="inputValue" />
<button class="button" @click="handleAddItem">提交</button>
</div>
<ul>
<li v-for="(item, index) in list" :key="index">
{{ item }}
</li>
</ul>
</template>
<script>
import { reactive, ref
} from "vue";
export default {
name: "App",
setup() {
const inputValue = ref("");
const list = reactive([]);
const handleAddItem = () => {
list.push(inputValue.value);
inputValue.value = "";
};
return { list, inputValue, handleAddItem };
},
};
</script>
<style>
.button {
margin-left: 20px;
}
</style>
運(yùn)行效果:
基于工程實現(xiàn)TODOList案例 --- 父子組件版[App.vue蛋辈、ListItem.vue]
首先需要創(chuàng)建一個子組件單文件:
其代碼:
<template>
<div class="hello">
<li>{{ msg }}</li>
</div>
</template>
<script>
export default {
name: 'ListItem',
props: {
msg: String
}
}
</script>
<style>
</style>
App.vue:
與上例 主要區(qū)別就是在<script>中引入属拾,
在<template>中修改:
<template>
<div>
<input v-model="inputValue" />
<button class="button" @click="handleAddItem">提交</button>
</div>
<ul>
<list-item v-for="(item, index) in list" :key="index" :msg="item" />
</ul>
</template>
<script>
import { reactive, ref } from "vue";
import ListItem from "./components/ListItem.vue";
export default {
name: "App",
components: { ListItemListItem },
setup() {
const inputValue = ref("");
const list = reactive([]);
const handleAddItem = () => {
list.push(inputValue.value);
inputValue.value = "";
};
return { list, inputValue, handleAddItem };
},
};
</script>
<style>
.button {
margin-left: 20px;
}
</style>
運(yùn)行效果同上例;
Vue-Router部分
創(chuàng)建帶router的項目
選擇特性的時候要選上Router:
適配會簡單些:
在代碼中使用Router
創(chuàng)建好工程項目后,同樣把它拉到VScode里面逞频,
可以看到這里的目錄纯衍,
可以看到main.js中,多了一個.use(router)
Router的作用 及 簡述
作用:根據(jù)url的不同苗胀,展示不同的內(nèi)容襟诸;
如下,運(yùn)行項目基协,默認(rèn)urlhttp://localhost:8080/#/
歌亲,展示主頁(Home頁):
http://localhost:8080/#/about
訪問,則展示about頁:首先看一下App.vue根組件怎么寫
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</template>
<style>
</style>
---
router-link
是定義 跳轉(zhuǎn)路由的標(biāo)簽澜驮,
to屬性
可以配置url尾部參數(shù)
【前部 自動補(bǔ)上 網(wǎng)站根地址】陷揪,
標(biāo)簽內(nèi)容
配置顯示的內(nèi)容;
點擊標(biāo)簽內(nèi)容
杂穷,即跳轉(zhuǎn)到悍缠,to
補(bǔ)全url 指向的頁面!耐量!
如果有寫<router-view/>
飞蚓,則不跳轉(zhuǎn),乃顯示在<router-view/>
中拴鸵;
---<router-view/>
則是
根據(jù)router-link
以及網(wǎng)頁url
組成的url路由
玷坠,
在router/index.js
文件中的路由對象
(如下一節(jié)的routes
)里蜗搔,
找到對應(yīng)的組件路由屬性
,拿到對應(yīng)的組件文件路徑
八堡,
在view
目錄中找到 對應(yīng)的組件 去顯示樟凄!
解析一下這個多出來的 router/index.js
文件
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
--- createRouter是vue-router的一個函數(shù),用于創(chuàng)建和初始化Router兄渺;
同時這里第二個參數(shù) 使用了路由參數(shù)routes
缝龄;--- 注意 定義routes參數(shù)這里,
path
定義 路徑挂谍、name
定義 名稱叔壤、component
進(jìn)行 組件的引入;
routers
里的組件既稱之為component
口叙,
也稱之為view
炼绘,子組件的單文件都放在view
文件夾下;
view目錄下的文件
-- 可以看到Home.vue這里其實引用一個HelloWorld子組件:
例程妄田,拓展一個Router頁面
-
首先App.vue添加 router-link:
-
views目錄下創(chuàng)建 單文件組件:
-
router/index.js 的Object Array中俺亮,定義一個對應(yīng)的路由元素:
完事,運(yùn)行疟呐,點擊Heheda脚曾,效果:
補(bǔ)充:Router路由懶加載語法糖 簡述 與例程實戰(zhàn)
如上例程中,router/index.js
中的這個寫法启具,
component
這里使用了 import
的方式 引入了組件本讥,
這是一種懶加載、異步加載
(如模板注釋:lazy-loaded
)的方式鲁冯,
即當(dāng)網(wǎng)頁跳到這一頁的時候拷沸,才會加載對應(yīng)的資源文件,否則不加載薯演;
而如 Home頁的加載方式堵漱,
則是普通的常規(guī)加載:
所以,
--- 異步加載的方式:
首頁打開會快點涣仿,節(jié)省不必要的資源占用,
但是在切換到懶加載
頁面時示惊,則需要花費一定的額外加載時間好港;
--- 同步加載的默認(rèn)方式:
則可能 一開始打開首頁等頁面 會慢一些,
但是會把其他頁面一開始就加載好米罚,切換的時候會快一點钧汹;
--- 具體選擇哪種方式,就根據(jù)業(yè)務(wù)需要進(jìn)行選擇录择;
...
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/heheda',
name: 'Heheda',
component: () => import(/* webpackChunkName: "about" */ '../views/Heheda.vue')
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
...
試驗拔莱,運(yùn)行上個例程碗降,之后打開瀏覽器測試工具:
可以看到這個時候頁面才加載about的資源:
VueX部分
首先需要創(chuàng)建項目
--- 特性配置:
package.json文件
VueX簡述
VueX 其實就是一個
數(shù)據(jù)管理框架
,
它創(chuàng)建了一個全局的须误、唯一的數(shù)據(jù)倉庫
挨稿;
當(dāng)一個前端項目特別大的時候,
或者類似 幾十個頁面 同步共享 某部分?jǐn)?shù)據(jù) 的場景京痢,
我們不可能還是用props奶甘、provide、inject等語法去傳遞數(shù)據(jù)祭椰,
這個時候我們需要一個更加完善的數(shù)據(jù)管理方案臭家;
VueX 框架的引入、數(shù)據(jù)的定義 以及 在組件中的使用
main.js中use它:
這里在state中準(zhǔn)備了一個測試數(shù)據(jù):
在Home.vue中 使用這個 VueX提供的 全局?jǐn)?shù)據(jù)字段:
這里借助
computed
屬性侣监,通過
this.$store.state.myTestString
獲取到 數(shù)據(jù)字段:
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<h1>{{myTestString}}</h1>
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: 'Home',
computed: {
myTestString() {
return this.$store.state.myTestString;
}
}
}
</script>
運(yùn)行效果:
<template>
<div class="about">
<h1>This is an about page</h1>
<h1>{{myTestString}}</h1>
</div>
</template>
<script>
export default {
name: 'About',
computed: {
myTestString() {
return this.$store.state.myTestString;
}
}
}
</script>
運(yùn)行效果:如何在任一組件中 修改 VueX的 數(shù)據(jù)
流程總結(jié):
要修改數(shù)據(jù)的組件,
發(fā)起dispatch(事件)
--->
store/index.js
中actions
里
對dispatch
的事件 進(jìn)行 監(jiān)聽 和回調(diào)處理臣淤,
然后發(fā)起一個commit(事件)
--->
store/index.js
中mutations
里
對commit
的事件 進(jìn)行 監(jiān)聽 和回調(diào)處理橄霉,
處理邏輯中,完成對數(shù)據(jù)的修改邑蒋;
--- 首先姓蜂,需要在事件觸發(fā)的函數(shù)里,
派發(fā)一個action医吊,
改變數(shù)據(jù) 這里在About.vue中钱慢,
我們派testChange
【這玩意是可以自定義的】的action,
this.$store.dispatch("testChange");
<template>
<div class="about">
<h1 @click="handleClick">This is an about page</h1>
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
export default {
name: "About",
computed: {
myTestString() {
return this.$store.state.myTestString;
},
},
methods: {
handleClick() {
this.$store.dispatch("testChange");
},
},
};
</script>
--- 接著在store/index.js
中actions
里卿堂,即這個VueX全局?jǐn)?shù)據(jù)倉庫中束莫,
做dispatch
的 監(jiān)聽回調(diào)處理,
store/index.js
中的actions
會響應(yīng)任意組件的dispatch
草描;
--- 再接著览绿,
在actions
里 對應(yīng)的回調(diào)方法中,使用commit('自定義事件名')
穗慕,
觸發(fā)一個mutations
饿敲,
store/index.js
中的mutations
,
會響應(yīng)actions
的commit
逛绵;
--- 最后怀各,
在store/index.js
中的mutations
里倔韭,
做actions
的commit
的監(jiān)聽回調(diào),
在對應(yīng)commit
的 事件回調(diào)函數(shù)中(如testChange()
)瓢对,
修改數(shù)據(jù)(如this.state.myTestString = "lueluelue";
)即可寿酌;
import { createStore } from 'vuex'
export default createStore({
state: {
myTestString: "heheda",
},
mutations: {
testChange() {
console.log("mutations --- testChange");
this.state.myTestString = "lueluelue";
}
},
actions: {
testChange() {
console.log("actions --- testChange");
this.commit('testChange');
}
},
modules: {
}
})
運(yùn)行:
可見完成了數(shù)據(jù)的修改沥曹,效果:
可見這邊的數(shù)據(jù)也跟著改變了,
體現(xiàn)了VueX的
全局特性
:以上是比較完整的步驟妓美,而如果修改數(shù)據(jù)的時候不涉及異步操作僵腺,則可以簡化上述流程
即省略組件的dispatch
和store的actions
的步驟,
組件直接就commit壶栋,
然后回調(diào)到store的mutations辰如,
直接修改數(shù)據(jù):
VueX的異步操作 同步操作
VueX建議在
mutations
中只進(jìn)行立即執(zhí)行的同步操作
贵试,
如果要進(jìn)行異步操作
琉兜,必須要在actions
中進(jìn)行,
也就是要采用上上節(jié)的步驟 進(jìn)行VueX數(shù)據(jù)的修改毙玻;
例程豌蟋,首先需要組件發(fā)起dispatch:
接著在actions中進(jìn)行異步操作:
import { createStore } from 'vuex'
export default createStore({
state: {
myTestString: "heheda",
},
mutations: {
testChange() {
console.log("mutations --- testChange");
this.state.myTestString = "lueluelue";
}
},
actions: {
testChange() {
setTimeout(() => {
console.log("actions --- testChange");
this.commit('testChange');
}, 2000);
}
},
modules: {
}
})
運(yùn)行,點擊文本桑滩,兩秒后文本(即背后的數(shù)據(jù))自動改變:
帶參數(shù)地 修改VueX數(shù)據(jù)
--- About.vue
dispatch時梧疲,
傳遞的 第一個參數(shù)為action
,
第二個參數(shù)為意圖改動的目標(biāo)數(shù)據(jù)參數(shù)
:
<template>
<div class="about">
<h1 @click="handleClick">This is an about page</h1>
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
export default {
name: "About",
computed: {
myTestString() {
return this.$store.state.myTestString;
},
},
methods: {
handleClick() {
this.$store.dispatch("testChange", "xixixihehehe");
},
},
};
</script>
--- store/index.js:
--- actions中的 事件回調(diào)函數(shù)运准,自動生成兩個形參幌氮,
第一個為store實例,
第二個為 組件中dispatch 傳遞過來的 數(shù)據(jù)參數(shù)胁澳;
--- mutations的 事件回調(diào)函數(shù)该互,也自動生成兩個形參,
第一個為 state實例韭畸,
它的值是 以Proxy的結(jié)構(gòu)存儲著
回調(diào)當(dāng)前事件處理函數(shù)
的時刻 store 數(shù)據(jù)倉庫的 狀態(tài)【即 state屬性】宇智,
第二個為 actions中commit 【同步操作時,也可以是組件中的commit】
傳遞過來的 數(shù)據(jù)參數(shù)胰丁;
import { createStore } from 'vuex'
export default createStore({
state: {
myTestString: "heheda",
},
mutations: {
testChange(state, str) {
console.log("mutations --- testChange");
console.log("mutations --- testChange --- state", state);
state.myTestString = str;
}
},
actions: {
testChange(store, str) {
setTimeout(() => {
console.log("actions --- testChange");
console.log("actions --- testChange --- store", store);
// this.commit('testChange');
store.commit('testChange', str);
}, 2000);
}
},
modules: {
}
})
運(yùn)行普筹,點擊文本,
兩秒后字體改變隘马,效果:
VueX修改數(shù)據(jù) 流程設(shè)計的理解
這樣設(shè)計,
--- 可以把同步操作的邏輯封裝在mutations
中處理妻顶,
把異步操作的邏輯封裝在actions
中處理酸员;
--- 又可以通過對觸發(fā)事件名
的自定義
蜒车,
對特定的業(yè)務(wù)處理邏輯、修改數(shù)據(jù)代碼塊 做標(biāo)記幔嗦;
--- 如此使得項目可維護(hù)性高酿愧、可拓展性高、可讀性高邀泉,
出問題時容易排查嬉挡,拓展代碼時也比較方便;
在setup【compositionAPI】中使用VueX
--- Home.vue:
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
import { useStore } from "vuex";
export default {
name: "Home",
setup() {
const store = useStore();
const myTestString = store.state.myTestString;
return { myTestString };
},
};
</script>
運(yùn)行效果:使用toRefs整理上述代碼
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
import { toRefs } from "vue";
import { useStore } from "vuex";
export default {
name: "Home",
setup() {
const store = useStore();
const { myTestString } = toRefs(store.state);
return { myTestString };
},
};
</script>
運(yùn)行效果同上例汇恤;
在About頁中 試試 setup中修改數(shù)據(jù)
--- About.vue
<template>
<div class="about">
<h1 @click="handleClick">This is an about page</h1>
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
import { toRefs } from "vue";
import { useStore } from "vuex";
export default {
name: "About",
setup() {
const store = useStore();
const { myTestString } = toRefs(store.state);
const handleClick = () => {
store.commit("testChange", "xixixihehehe");
};
return { myTestString, handleClick };
}
};
</script>
--- store/index.js:
import { createStore } from 'vuex'
export default createStore({
state: {
myTestString: "heheda",
},
mutations: {
testChange(state, str) {
console.log("mutations --- testChange");
console.log("mutations --- testChange --- state", state);
state.myTestString = str;
}
},
modules: {
}
})
運(yùn)行庞钢,到About頁,
點擊文本:
試一下 setup異步處理
--- About.vue
<template>
<div class="about">
<h1 @click="handleClick">This is an about page</h1>
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
import { toRefs } from "vue";
import { useStore } from "vuex";
export default {
name: "About",
setup() {
const store = useStore();
const { myTestString } = toRefs(store.state);
const handleClick = () => {
store.dispatch("testChange", "xixixihehehe");
};
return { myTestString, handleClick };
}
};
</script>
--- store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
myTestString: "heheda",
},
mutations: {
testChange(state, str) {
console.log("mutations --- testChange");
console.log("mutations --- testChange --- state", state);
state.myTestString = str;
}
},
actions: {
testChange(store, str) {
setTimeout(() => {
console.log("actions --- testChange");
console.log("actions --- testChange --- store", store);
// this.commit('testChange');
store.commit('testChange', str);
}, 2000);
}
},
modules: {
}
})
使用axios發(fā)送ajax請求
-
首先需要安裝axios:
找到一個fastmock接口因谎,
https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/register基括;
其內(nèi)容:
在About.vue中請求數(shù)據(jù)并顯示:
--- 主要注意要
import
;--- get方法的參數(shù)為url财岔,訪問數(shù)據(jù)接口风皿;
--- then接收 接口回復(fù);
<template>
<div class="about">
<h1 @click="handleClick">This is an about page</h1>
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
import { toRefs } from "vue";
import { useStore } from "vuex";
import axios from "axios";
export default {
name: "About",
setup() {
axios
.get(
"https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/register"
)
.then((response) => {
console.log("response", response);
const msg = response.data.desc;
console.log("response.data.desc", msg);
});
const store = useStore();
const { myTestString } = toRefs(store.state);
const handleClick = () => {
store.dispatch("testChange", "xixixihehehe");
};
return { myTestString, handleClick };
},
};
</script>
運(yùn)行效果:
把上例的axios請求 封裝到 actions中
--- About.vue
<template>
<div class="about">
<h1 @click="handleClick">This is an about page</h1>
<h1>{{ myTestString }}</h1>
</div>
</template>
<script>
import { toRefs } from "vue";
import { useStore } from "vuex";
export default {
name: "About",
setup() {
const store = useStore();
const { myTestString } = toRefs(store.state);
const handleClick = () => {
store.dispatch("testChange", "xixixihehehe");
};
return { myTestString, handleClick };
},
};
</script>
--- store/index.js
import { createStore } from 'vuex'
import axios from "axios";
export default createStore({
state: {
myTestString: "heheda",
},
mutations: {
testChange(state, str) {
console.log("mutations --- testChange");
console.log("mutations --- testChange --- state", state);
state.myTestString = str;
}
},
actions: {
testChange(store) {
axios
.get(
"https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/register"
)
.then((response) => {
console.log("response", response);
const msg = response.data.desc;
console.log("response.data.desc", msg);
store.commit('testChange', msg);
});
}
},
modules: {
}
})
運(yùn)行: