当前位置:   article > 正文

vue 项目利用 vuex+mixins 实现全局换肤及多语言_换肤怎么实现全局更换

换肤怎么实现全局更换

项目中需要做一个全局换肤(主题色)以及多语言的需求,在通用页更改,全局生效。

我们都知道,vue是MVVM模式,即模型-视图-视图模型,视图更新,数据会跟着更新,反之也一样。但是仅仅在当前组件生效,那么:

如何在一处修改数据就能触发全局视图的更新呢

答案就是vuex状态管理。

有了状态管理,如何将主题色,语言数据等注入每一个组件呢?

我们可以用mixin(混入),单组件混入或全局混入都可,可以根据需要权衡是否使用全局混入,全局混入意味着每一个new出来的组件,都会拥有混入的方法和数据,并且优先级是组件内部所声明的数据或方法>混入的

 

下面我们就来进入正题,以uni-app为例

首先,在项目根路径下新建store文件夹,并在store目录下新建module文件夹,添加主题色theme.js和多语言lang.js的配置文件

lang.js

  1. let userLang , lang = {};
  2. try {
  3. // 1. 分析用户已经选择的语言
  4. userLang = uni.getStorageSync("userLang");
  5. // 2. 如果用户没有选择过则设置默认语言
  6. if(!userLang){
  7. userLang = 'zh'
  8. }
  9. switch(userLang.substring(0, 2)) {
  10. case 'zh':
  11. lang = require('../../lang/zh.js');
  12. break;
  13. case 'en':
  14. lang = require('../../lang/en.js');
  15. break;
  16. case 'ja':
  17. lang = require('../../lang/ja.js');
  18. break;
  19. default:
  20. lang = require('../../lang/zh.js');
  21. }
  22. } catch (e) {
  23. // error
  24. }
  25. const state = {
  26. lang : lang
  27. }
  28. const mutations={
  29. changeLang(state, lang) {
  30. state.lang = lang;
  31. }
  32. }
  33. const actions = {
  34. changeLang: function(context){
  35. let lang = {};
  36. uni.showActionSheet({
  37. itemList:['简体中文', 'English', '日本語'],
  38. success: function(e){
  39. try {
  40. if (e.tapIndex == 0) {
  41. uni.setStorageSync('userLang', 'zh');
  42. lang = require('../../lang/zh.js');
  43. } else if (e.tapIndex == 1){
  44. uni.setStorageSync('userLang', 'en');
  45. lang = require('../../lang/en.js');
  46. } else {
  47. uni.setStorageSync('userLang', 'ja');
  48. lang = require('../../lang/ja.js');
  49. }
  50. } catch (e) {
  51. // error
  52. }
  53. context.commit('changeLang', lang);
  54. }
  55. });
  56. }
  57. }
  58. export default {
  59. namespaced: true, // 当你需要在别的文件里面使用( mapGetters、mapActions)时
  60. state,
  61. actions,
  62. mutations
  63. }

theme.js

  1. let defaultColor;
  2. try {
  3. // 获取用户已设置的主题色
  4. defaultColor = uni.getStorageSync("themeColor");
  5. // 如果没有,设置默认色
  6. if(!defaultColor){
  7. defaultColor = '#40aee2';
  8. }
  9. } catch (e) {
  10. // error
  11. }
  12. const state = {
  13. themeColor: defaultColor, // 初始化为配置的主题色
  14. };
  15. const mutations = {
  16. setThemeColor(state, color) {
  17. state.themeColor = color;
  18. }
  19. };
  20. const actions = {
  21. setThemeColor(context, color) { // 触发mutations里面的setThemeColor ,传入数据形参color
  22. let themeColor = '';
  23. uni.showActionSheet({
  24. itemList: ['红色', '橙色'],
  25. success: function(e) {
  26. if (e.tapIndex == 0) {
  27. themeColor = '#f25762';
  28. } else {
  29. themeColor = '#ff6600';
  30. }
  31. uni.setStorageSync('themeColor', themeColor);
  32. context.commit('setThemeColor', themeColor);
  33. }
  34. });
  35. }
  36. };
  37. export default {
  38. namespaced: true, // 当你需要在别的文件里面使用( mapGetters、mapActions)时
  39. state,
  40. actions,
  41. mutations
  42. }

store/index.js

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. import themeColor from './modules/theme'
  4. import lang from './modules/lang'
  5. Vue.use(Vuex)
  6. const debug = process.env.NODE_ENV !== 'production'
  7. export default new Vuex.Store({
  8. modules: {
  9. themeColor,
  10. lang
  11. },
  12. //在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
  13. strict: debug
  14. })

然后在项目入口文件中引入并挂载

main.js

  1. import Vue from 'vue'
  2. import App from './App'
  3. import store from "./store"
  4. import { mapState } from 'vuex'
  5. // 全局混入主题色,多语言
  6. Vue.mixin({
  7. computed: {
  8. ...mapState('lang', {
  9. lang: 'lang'
  10. }),
  11. ...mapState('themeColor', {
  12. themeColor: 'themeColor'
  13. })
  14. }
  15. })
  16. Vue.config.productionTip = false
  17. Vue.prototype.$store = store
  18. App.mpType = 'app'
  19. const app = new Vue({
  20. store,
  21. ...App
  22. })
  23. app.$mount()

在index.vue中使用

  1. <template>
  2. <view class="content">
  3. <image class="logo" src="/static/logo.png"></image>
  4. <view class="text-area">
  5. <text class="title">{{lang.hello}}</text>
  6. </view>
  7. <navigator open-type="navigate" url="./test">
  8. <button class="button" :style="{background: themeColor}">去更换主题色和语言</button>
  9. </navigator>
  10. </view>
  11. </template>
  12. <script>
  13. export default {
  14. data() {
  15. return {}
  16. }
  17. }
  18. </script>

在test.js中设置

  1. <template>
  2. <view>
  3. <view class="list">
  4. <view class="items" @tap="changeLang">
  5. <view class="body">
  6. <view class="title">多语言<text>跟随系统</text></view>
  7. </view>
  8. </view>
  9. <view class="items" @tap="setThemeColor">
  10. <view class="body">
  11. <view class="title">使用默认皮肤<text>选择皮肤</text></view>
  12. </view>
  13. </view>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. import {mapActions} from 'vuex';
  19. export default {
  20. methods: {
  21. ...mapActions('lang', {
  22. 'changeLang': 'changeLang'
  23. }),
  24. ...mapActions('themeColor', {
  25. 'setThemeColor': 'setThemeColor'
  26. })
  27. }
  28. }
  29. </script>

以上只是提供一个简单的示例,具体的实现细节可以自己修改。

其他文件:

lang/zh.js

  1. module.exports = {
  2. hello: '你好'
  3. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/332209?site
推荐阅读
相关标签
  

闽ICP备14008679号