Vue + Element-ui实现换肤

我的环境

@vue/cli 4.5.8
node - v10.15.0
npm - 6.4.1

思路:

vue项目实现换肤有两部分

一、自主样式换肤

这部分换肤,在网上趴了不少贴,实现方式也是多种多样,这里不多说,看到这里来的人,肯定也看过不少贴了

说一下我的思路

考虑网上实现思路都过于复杂
有加命名空间的,有更换css文件的,有用打包工具实现的
而我都看不懂

因为只需要更改主题颜色,点缀色什么的根据项目需求,不需要实现,而且大部分点缀色都是用element-ui配色

鉴于以上考虑,我只需要拥有一个全局变量,在每次点击颜色组件,获取到颜色值后同步到标签上

思考了一下vue框架,能全局获取数据并插入dom的方式

最好是有一个全局变量

灵光一闪,实现步骤就三步:

  1. mixin实现不用到处定义的变量;
  2. vuex赋值到这个变量;
  3. 点击颜色组件更新vuex;

但是怎么动态更改颜色呢,如果只是改变背景色,我直接动态绑定style

但是有时候可能是边框线颜色,有时候可能是文字颜色

于是我决定做个指令,根据指令动态渲染

思路有了,上代码:

新增一个mixin.js文件
export default {
    name: 'mixin',
    computed: {
        mTheme () {
          return this.$store.state.theme;
        }
    }
}

在main.js引入,并注入到Vue.mixin中

import mixin from '@/mixin.js'
Vue.mixin(mixin);

到vuex顶层新增一个state属性theme

const store = new Vuex.Store({
    state: {
        theme: '#5E72F4'
    }
})

新建一个组件theme.vue,并使用el-color-picker组件,封装成一个主题更换组件

<template>
    <div class="theme">
        <el-color-picker
            v-model="color" 
            @change="handleOnColor" 
            size="small"
        ></el-color-picker>
    </div>
</template>

<script>
export default {
    name: 'Theme',
    data () {
        return {
            color: ''
        };
    },
    created() {
        this.color = this.mTheme;
    },
    watch: {
        mTheme(val) {
            this.color = val;
        }
    },
    computed: {
        theme () {
            return this.$store.state.theme;
        }
    },
    methods: {
        handleOnColor(value) {
            this.$store.dispatch('UPDATE_THEME', value);
        }
    },
    destroyed () {
    }
}
</script>

<style lang="scss" scoped>
</style>

到man.js注册一个全局组件

import Theme from "@/components/theme.vue";
Vue.component("en-theme", Theme);

到store中添加一个 'UPDATE_THEME' 的 action

const store = new Vuex.Store({
    state: {
        theme: "#123456",
    },
    actions: {
        UPDATE_THEME({ commit }, val) {
            commit('updateTheme', val)
        }
    },
    mutations: {
        updateTheme(state, val) {
            state.theme = val;
        },
    }
})

创建一个theme.js文件,实现一个自定义指令

export const theme = {
    bind: function (el, binding, vnode) {
        setEleStyleColorAttribute(el, binding);
    },
    update: function (el, binding, vnode) {
        setEleStyleColorAttribute(el, binding);
    },
    componentUpdated: function (el, binding, vnode) {
        setEleStyleColorAttribute(el, binding);
    }
}

function setEleStyleColorAttribute(el, binding) {
    const {name, value, arg, expression, modifiers} = binding;
    const {background, font, border} = modifiers;
    if (background) el.style['background-color'] = value;
    if (font) el.style.color = value;
    if (border) el.style['border-color'] = value;
}

 补充说明:把指令全局注册一下

import { theme } from "@/directive/theme.js"

Vue.directive("theme", theme)

然后到你要绑定指令实现主题更换的地方绑定指令

<div v-theme.background="mTheme" class="img-logo" :id="'custom' + index">
  {{ name.slice(0, 1) }}
</div>

二、element-ui换肤

这部分我也是在网上抄的,实现方式给大家放的链接吧。思路一模一样

手摸手,带你用vue撸后台 系列三(实战篇)

最终效果

绿色箭头部分是element-ui实现换肤的地方;

紫色部分是还没有加入任何换肤处理的地方;

侧边栏和圆形图标是自定义样式实现换肤的地方

水平有限,不足之处请海涵

评论 2 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

z_blackbear

你的鼓励是我最大的动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值