uni-app项目使用Vuex

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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值