1.下载Vuex
npm install vuex --save
2.在项目目录下创建文件夹store,并创建index.js文件
vue2中配置Vuex:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
// 同vue3
...
})
export default store;
vue3中配置:
// store/index.js
import { createStore } from 'vuex';
const store = createStore({
state() {
return {
count: 0,
userInfo: null,
};
},
mutations: {
increment(state) {
state.count++;
},
setUserInfo(state, userInfo) {
state.userInfo = userInfo;
},
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
},
fetchUserInfo({ commit }) {
setTimeout(() => {
const userInfo = { name: 'Jane Doe', age: 26 };
commit('setUserInfo', userInfo);
}, 1500);
},
},
getters: {
count(state) {
return state.count;
},
userInfo(state) {
return state.userInfo;
},
},
});
export default store;
3.main.js中注册vuex
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
import store from './src/store' // vue2引入
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
store, // 将 Vuex store 注册到 Vue 实例中
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
import store from './src/store' // vue3引入
export function createApp() {
const app = createSSRApp(App)
app.use(store) // 注册 Vuex store
return {
app
}
}
// #endif
4.组件中使用
【注意】vue2与vue3使用方式不同:
vue2中,Vuex已经是全局实例的一部分,可以直接通过this.$store访问 [选项式API]
vue3中,使用Vuex 4.x,需要通过useStore()访问Vuex实例,再调用dispatch来触发actions [组合式API]
<!-- pages/index/index.vue VUE2-->
<template>
<view>
<text>当前计数:{
{ count }}</text>
<button @click="increment">增加</button>
<button @click="incrementAsync">延迟增加</button>
<button @click="fetchUserInfo">获取用户信息</button>
<view v-if="userInfo">
<text>用户信息:{
{ userInfo.name }},{
{ userInfo.age }}岁</text>
</view>
</view>
</template>
<script>
export default {
computed: {
// 通过 Vuex 的 getters 获取状态
count() {
return this.$store.getters.count;
},
userInfo() {
return this.$store.getters.userInfo;
},
},
methods: {
increment() {
this.$store.commit('increment'); // 提交 mutation
},
incrementAsync() {
this.$store.dispatch('incrementAsync'); // 调用 action
},
fetchUserInfo() {
this.$store.dispatch('fetchUserInfo'); // 获取用户信息
},
},
};
</script>
<style scoped>
/* 样式略 */
</style>
<!-- pages/index/index.vue VUE3-->
<template>
<view>
<text>当前计数:{
{ count }}</text>
<button @click="increment">增加</button>
<button @click="incrementAsync">延迟增加</button>
<button @click="fetchUserInfo">获取用户信息</button>
<view v-if="userInfo">
<text>用户信息:{
{ userInfo.name }},{
{ userInfo.age }}岁</text>
</view>
</view>
</template>
<script>
import { useStore } from 'vuex';
import { computed } from 'vue';
export default {
setup() {
const store = useStore(); // 获取 Vuex store
const count = computed(() => store.getters.count); // 获取 count
const userInfo = computed(() => store.getters.userInfo); // 获取用户信息
const increment = () => {
store.commit('increment'); // 提交 mutation
};
const incrementAsync = () => {
store.dispatch('incrementAsync'); // 调用 action
};
const fetchUserInfo = () => {
store.dispatch('fetchUserInfo'); // 获取用户信息
};
return {
count,
userInfo,
increment,
incrementAsync,
fetchUserInfo,
};
},
};
</script>
<style scoped>
/* 样式略 */
</style>
5.运行结果
运行到微信开发者工具如下图所示:
点击“增加”按钮,当前计数会立即加一;点击“延迟增加”,当前计数隔一段时间加一,延时长短取决于配置文件中incrementAsync的设置
6.从服务器获取数据
vue3
// store/index.js
import { createStore } from 'vuex';
const store = createStore({
state() {
return {
Data: {}, // 保存数据
};
},
mutations: {
setData(state, data) {
state.Data = data;
},
},
actions: {
async fetchData({ commit }) {
try {
const res = await new Promise((resolve, reject) => {
uni.request({
url: 'https://test.com', // 获取数据接口
method: 'POST',
data: { ... },
header: {
Authorization: `Bearer ${uni.getStorageSync('token')}`,
},
success: resolve,
fail: reject,
});
});
if (res.statusCode === 200) {
console.log(res.data.result);
commit('setData', res.data.result); // 提交数据到 mutations
} else {
commit('setError', '请求失败:' + res.data.message || '未知错误');
console.error('请求失败:', res.data);
}
} catch (error) {
commit('setError', error.message || '网络错误');
console.error('网络错误:', error);
}
},
},
});
export default store;
// 组件中使用 pages/index/index
<template>
<view>
<text>{
{ data }}</text>
<button @click="fetchData">获取数据</button>
</view>
</template>
<script>
import { useStore } from 'vuex';
import { computed } from 'vue';
export default {
setup() {
const store = useStore();
const Data = computed(() => store.state.Data);
const data = computed(() => Data.value.data);
const fetchData = () => {
store.dispatch('fetchData');
};
return {
Data,
fetchData,
data,
};
}
}
</script>
使用vue2获取多个属性时
1.将多个属性提取到data()中--修改
适用于需要在组件中频繁访问并可能在本地修改的属性
<template>
<view>
<text>当前 data: {
{ data }}</text>
<text>其他数据: {
{ otherData }}</text>
<button @click="fetchData">获取数据</button>
</view>
</template>
<script>
import { useStore } from 'vuex';
import { computed } from 'vue';
export default {
data() {
return {
data: null,
otherData: null,
};
},
computed: {
// 使用 computed 来监听 Vuex 中 Data 的变化,并同步到 data 中
Data() {
return this.$store.state.Data;
},
},
watch: {
// 当 Vuex 中的 Data 改变时,更新 data 中的属性
Data(newData) {
this.data= newData.data;
this.otherData = newData.otherData;
},
},
methods: {
fetchData() {
this.$store.dispatch('fetchData'); // 调用 Vuex action 获取数据
},
},
mounted() {
// 在组件挂载时同步 Vuex 中的数据到 data 中
this.data = this.Data.data;
this.otherData = this.Data.otherData;
},
};
</script>
2.直接从Vuex中访问多个属性--简洁
适用于只需要从Vuex中获取数据并在模板中渲染的情况,不需要修改数据,仅显示
<template>
<view>
<text>当前 data: {
{ Data.data}}</text>
<text>其他数据: {
{ Data.otherData }}</text>
<button @click="fetchData">获取数据</button>
</view>
</template>
<script>
import { useStore } from 'vuex';
import { computed } from 'vue';
export default {
computed: {
// 直接从 Vuex 获取 Data
Data() {
return this.$store.state.Data;
},
},
methods: {
fetchData() {
this.$store.dispatch('fetchData'); // 调用 Vuex action 获取数据
},
},
};
</script>