vue实现主题切换的多种思路分享

 更新时间:2021年06月01日 14:25:45   作者:前端冒菜师  
最近一段时间,一直在做主题方面的工作。我们的主题,并不是简单切换一下颜色,或者排版变化这些,而是变化比较大的主题。比如说:主题1和主题2看起来完全不一样,功能甚至都不一样。这样,通过切换css就无法做到了,因此我思考良久,使用了如下2种方法

动态改变主题

首先需要解决的是如何知道你需要显示哪个主题,并且可以动态切换。我选择的方法是queryString。

我们打开url的时候,可以在后面缀上?theme=xx,读取这个xx储存起来即可。

第一种办法:动态组件

当主题的路由并没有发生变化,仅是组件内部的样式,功能发生了变化,我们可以将一个组件复制一遍,修改完后,通过懒加载和动态组件实现。

// 页面组件
<template>
    <div>
        <component :is="themeName" />
    </div>
</template>
<script>
    export default{
        name: 'Home',
        components:{
            theme1:()=>import('@/theme/theme1/a'),
            theme2:()=>import('@/theme/theme2/a'),
        },
        computed:{
            themeName(){
                retun `theme${this.$store.state.themeId}`
            }
        }
    }
</script>

在组件中,我将script部分抽离出来,因为大部分组件其实在逻辑上是相同。哪怕有一些不同,我们也可以直接在主题2的组件中更改,减少对主题1的影响。

//action.js
export default{
    name:'Theme1',
    ....
}
<template>
<div class="theme1"></div>
</template>
<script>
    import action from '../componentAction/action'
    action.name='Theme1'
    export default action
</script>
<style scoped>

</style>

这样实现的有点是可以通过子组件的style scoped实现样式隔离,同时功能数据上都会隔离,例如两个子组件中的swiper不会相互影响。 同时,懒加载也减小了首页的加载时体积。 后面再增加新增的主题也只是照猫画虎而已。

第二种办法,路由隔离

路由隔离其实就是简单的theme1写一个路由的数组,theme2写一套路由。

// router.js
{
    path:'/theme3',
    name:'theme3Index',
    component: () => import('../views/theme3/Index.vue'),
    children:[
      {
        path: '/theme3/entry',
        name: 'theme3Entry',
        component:  () => import('../views/theme3/entry.vue'),
      }
     ]
 }
      

这种办法其实是下下之策,我使用这个主要是因为路由变化了,比如之前是直接进入a.vue,但是现在前面多加了一层entry页面,所以只能改变路由。 这种办法也实现了比较好的隔离。

总结

以上两种思路是我针对于我们当前业务的思考,仅供参考。

其实这两种方法都有一个共同的问题,就是代码冗余。每个组件都避不可免的带有一部分之前主题的代码,虽然,大部分逻辑代码可以抽离出来,但是css和template却无法抽离。

如果每次一个主题增加一个dom,一个功能块,如果每次都用v-if,那么其实代码以后会更加难以维护。因此,我选择了按照主题去划分代码。

额外补充基于css的两种方法

方法一 多套css

<!-- 中心 -->
<template>
 动态获取父级class名称,进行一个父级class的多次定义
  <div :class="className">
    <div class="switch" v-on:click="chang()">
      {{ className == "box" ? "开灯" : "关灯" }}
    </div>
  </div>
</template>
<script>
export default {
  name: "Centre",
  data() {
    return {
      className: "box"
    };
  },
  methods: {
  // 改变class
    chang() {
      this.className === "box"
        ? (this.className = "boxs") 
        : (this.className = "box");
    }
  },
};
</script>
<style lang="scss">
当class为box 使用witch的css
@import "./style/witch.scss";
当class为boxs 使用black的css
@import "./style/black.scss";
.switch {
  position: fixed;
  top: 4px;
  right: 10px;
  z-index: 50;
  width: 60px;
  height: 60px;
  background: #fff;
  line-height: 60px;
  border-radius: 20%;
}
</style>

每个css文件样式大致相同,只是最外层的父级不一样,分别为.box 和.boxs

方法二 scss动态切换变量

我自己是分为了2个主要文件来做的

  • _variable.scss 变量管理文件
  • var()为css3中提出的声明样式变量的方法
  • var(属性名,属性值)注意属性值不能是字符串
// 主题切换
$bgColor:var(--backgroundColor,rgb(255,255,255));
$fontColor:var(--fonntColor,rgb(0,0,0));
$bgmColor:var(--backgroundMColor,rgb(238,238,238));
$tableColor:var(--tableColor,rgb(218,218,218));
$borderColor:var(--borderColor,rgb(238,238,238));
$tablesColor:var(--tablesColor,rgb(255,255,255));
$inputColor:var(--inputColor,rgb(255,255,255))

创建的_variable.scss 文件我在vue.config.js进行了一个全局的配置,没有在组件中引入

  css: {
    loaderOptions: {
      // 此文件为主题切换文件
      sass: {
        prependData: `@import "./src/styles/_variable.scss";`,
      },
    },
  },

publicStyle.js

这个方法可以去修改var定义的变量
document.getElementsByTagName("body")[0].style.setProperty("属性名", "替换的属性值f");

//  主题切换
const cut = (cutcheack) => {
    document.getElementsByTagName("body")[0].style.setProperty("--backgroundColor", cutcheack ? "#121212" : "#fff");
    document.getElementsByTagName("body")[0].style.setProperty("--fonntColor", cutcheack ? "#cecece" : "#333");
    document.getElementsByTagName("body")[0].style.setProperty("--backgroundMColor", cutcheack ? "#333" : "#eee");
    document.getElementsByTagName("body")[0].style.setProperty("--tableColor", cutcheack ? "#000" : "#d8d8d8");
    document.getElementsByTagName("body")[0].style.setProperty("--tablesColor", cutcheack ? "#222" : "#fff");
    document.getElementsByTagName("body")[0].style.setProperty("--inputColor", cutcheack ? "#666" : "#fff");
    document.getElementsByTagName("body")[0].style.setProperty("--borderColor", cutcheack ? "#666" : "#fff");
};
export default cut;

组件中使用

<!-- 首页 -->
<template>
<div class='home'>
      <el-switch v-model="cutcheack" active-color="#333" inactive-color="#13ce66"  active-text="主题" @change="switchs"></el-switch>
</div>
</template>
<script>
import cut from "../../utils/publicStyle.js";
export default {
  name: "Home",
  data() {
    return {
      cutcheack: false, //主题切换
    };
  },
  methods: {
    // 左侧导航隐藏或显示
    // 切换主题
    switchs() {
      cut(this.cutcheack);
    },
  },
};
</script>
<style lang='scss' scope>
.home {
    height: 100%;
    width: 100%;
	background:$bgColor;
    .el-container {
        height: 100%;
        color:$fontColor;
    }
}
</style>

以上就是vue实现主题切换的多种思路分享的详细内容,更多关于vue 主题切换的资料请关注脚本之家其它相关文章!

相关文章

  • Element-plus封装搜索组件的实现

    Element-plus封装搜索组件的实现

    在后台管理系统中,经常需要在多个页面中使用搜索功能,本文就来介绍一下Element-plus封装搜索组件的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用

    vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用

    在vuex中有四大金刚分别是State, Mutations,Actions,Getters,本文对这四大金刚做了详细介绍,本文重点是给大家介绍vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用,感兴趣的朋友一起看看吧
    2018-04-04
  • Vue中Mustache引擎插值语法使用详解

    Vue中Mustache引擎插值语法使用详解

    在Vue中通过Mustache模板引擎将data中的文本数据插入到HTML中,下面这篇文章主要给大家介绍了关于Vue中Mustache模板引擎插值语法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • vue使用echart自定义标签以及颜色

    vue使用echart自定义标签以及颜色

    这篇文章主要为大家详细介绍了vue使用echart自定义标签以及颜色,应用于echart 5.0以上版本,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 在 Vue 中使用 dhtmlxGantt 组件时遇到的问题汇总(推荐)

    在 Vue 中使用 dhtmlxGantt 组件时遇到的问题汇总(推荐)

    dhtmlxGantt一个功能丰富的甘特图插件,支持任务编辑,资源分配和多种视图模式,这篇文章主要介绍了在 Vue 中使用 dhtmlxGantt 组件时遇到的问题汇总,需要的朋友可以参考下
    2023-03-03
  • vue源码学习之Object.defineProperty对象属性监听

    vue源码学习之Object.defineProperty对象属性监听

    这篇文章主要介绍了vue源码学习之Object.defineProperty对象属性监听,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • vue 中 beforeRouteEnter 死循环的问题

    vue 中 beforeRouteEnter 死循环的问题

    这篇文章主要介绍了vue beforeRouteEnter 死循环的问题,在文章末尾给大家补充介绍了vue中beforeRouteEnter使用的误区,需要的朋友可以参考下
    2019-04-04
  • vue 地图可视化 maptalks 篇实例代码详解

    vue 地图可视化 maptalks 篇实例代码详解

    这篇文章主要介绍了vue 地图可视化 maptalks 篇,本文分步骤通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-05-05
  • vue devserver及其配置方法

    vue devserver及其配置方法

    这篇文章主要介绍了vue devserver及其配置方法,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • Vue3中Reactive的使用详解

    Vue3中Reactive的使用详解

    Vue 3 的 Composition API 带来了强大的 reactive 函数,它允许你在 Vue 应用程序中创建响应式数据,本文我们将深入探讨 Vue 3 的 reactive,并提供一些注意事项和解决方案,希望可以帮助打更好地使用它
    2023-11-11

最新评论