当前位置:编程学习 > > 正文

vue官网编辑器主题(vue实现主题切换的多种思路分享)

时间:2022-01-19 00:06:24类别:编程学习

vue官网编辑器主题

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

动态改变主题

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

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

第一种办法:动态组件

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

  • // 页面组件
    <template>
        <li>
            <component :is="themeName" />
        </li>
    </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>
    <li class="theme1"></li>
    </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的多次定义
      <li :class="className">
        <li class="switch" v-on:click="chang()">
          {{ className == "box" ? "开灯" : "关灯" }}
        </li>
      </li>
    </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个主要文件来做的

  • // 主题切换
    $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>
    <li class='home'>
          <el-switch v-model="cutcheack" active-color="#333" inactive-color="#13ce66"  active-text="主题" @change="switchs"></el-switch>
    </li>
    </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 主题切换的资料请关注开心学习网其它相关文章!

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐