uni-app Vue2 引入 Vuex实现主题色

uni-app Vue2 引入 Vuex 完整步骤(适配你现有 main.js 代码)

1. 新建 store 目录

项目根目录新建 store/index.js

js 复制代码
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // 主题颜色,本地缓存持久化
    themeColor: uni.getStorageSync('themeColor') || '#409EFF'
  },
  mutations: {
    // 修改主题色
    SET_THEME_COLOR(state, color) {
      state.themeColor = color
      uni.setStorageSync('themeColor', color)
      // 如果你需要onfire通知可在这里 fire
      // this._vm.$fire.fire('colorChange', color)
    }
  },
  getters: {
    getThemeColor: state => state.themeColor
  }
})

2. 在 main.js 引入并挂载到 Vue 实例

修改你的 main.js,新增 store 导入,放到 new Vue 里:

js 复制代码
import Vue from 'vue'
import App from './App'
import directive from './common/directive.js'
import utils from './common/utils.js'
import config from './config.js'
import onfire from './common/onfire.js'
import { gotopage } from '@/common/gotopage.js'
// 引入vuex仓库
import store from './store'

import colorMixin from './common/colorMixin.js'

Vue.mixin(colorMixin)

// 公共组件
import headerBar from './components/header.vue'
Vue.component('header-bar', headerBar)

Vue.prototype.$fire = new onfire()

Vue.config.productionTip = false

App.mpType = 'app'

Vue.prototype.config = config

const app = new Vue({
	store, // 挂载store,全局可用 this.$store
	...App
})
app.$mount()

3. 页面 / 组件操作颜色(改色、取值)

① 修改颜色

js 复制代码
// 任意页面methods
this.$store.commit('SET_THEME_COLOR', '#ff4400')

② 获取颜色三种方式

方式1 模板直接用(简单)
vue 复制代码
<view :style="{ color: $store.getters.getThemeColor }">文字</view>
方式2 computed 计算属性(推荐多处使用)
vue 复制代码
<script>
export default {
  computed: {
    themeColor() {
      return this.$store.getters.getThemeColor
    }
  }
}
</script>
<template>
  <view :style="{ color: themeColor }">测试</view>
</template>
方式3 mapGetters 批量引入
vue 复制代码
<script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['getThemeColor'])
  }
}
</script>

4. 在全局 CSS / style 使用 Vuex 颜色(CSS变量方案)

修改 App.vue,注入全局 CSS 变量,所有页面样式直接 var(--theme-color)

vue 复制代码
<template>
  <!-- 注入css变量到全局 -->
  <view :style="cssVars">
    <uni-page-body />
  </view>
</template>

<script>
export default {
  computed: {
    cssVars() {
      return {
        '--theme-color': this.$store.getters.getThemeColor
      }
    }
  }
}
</script>

<style>
/* 全局样式直接使用变量 */
.title {
  color: var(--theme-color);
}
.btn {
  background: var(--theme-color);
}
</style>

子页面无需任何js,style 里直接写:

css 复制代码
.text {
  color: var(--theme-color);
}

5. 在你的 mixin 中直接使用 Vuex(colorMixin.js)

你全局注入了 colorMixin,可以在 mixin 封装统一取色逻辑:

js 复制代码
// common/colorMixin.js
export default {
  computed: {
    themeColor() {
      return this.$store.getters.getThemeColor
    }
  }
}

所有页面自动拥有 themeColor,模板直接 :style="{color:themeColor}"

6. 搭配你现有的 onfire 通知(可选)

如果需要跨页面、原生canvas、非Vue逻辑监听颜色变化:

store/index.js

js 复制代码
mutations: {
  SET_THEME_COLOR(state, color) {
    state.themeColor = color
    uni.setStorageSync('themeColor', color)
    // 全局onfire广播
    this._vm.$fire.fire('colorChange', color)
  }
}

页面监听:

js 复制代码
mounted() {
  this.colorHandler = (c) => {
    console.log('颜色更新', c)
  }
  this.$fire.on('colorChange', this.colorHandler)
},
onUnload() {
  this.$fire.un(this.colorHandler)
}

关键说明 uni-app 注意点

  1. uni-app 本地存储用 uni.getStorageSync / uni.setStorageSync,不要用 localStorage;
  2. 挂载 store 到 new Vue 实例后,所有页面、组件、mixin 都能访问 this.$store
  3. Vuex 自带响应式,修改后所有页面、子组件自动刷新,不需要刷新页面;
  4. style 标签内不能直接读取 JS 变量,必须通过 CSS 变量中转。