基于element-ui的主题颜色修改器

本文档展示了如何创建一个基于Element-UI的主题颜色修改器。通过使用`el-color-picker`组件和Vue.js,实现了颜色选择后实时更新主题色的功能,包括将新颜色保存到本地存储,动态修改CSS样式以及处理颜色转换。此外,还包含了对颜色值合法性的检查方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于element-ui的主题颜色修改器

<template>
    <el-color-picker v-model="theme" class="theme-picker" 
        popper-class="theme-picker-dropdown">
    </el-color-picker>
</template>

<script>
    const version = require("element-ui/package.json").version; // 版本号
    const ORIGINAL_THEME = "#409EFF";

    export default {
        name: "colorPicker",
        data() {
            return {
                chalk: "",
                theme: "#409EFF",
            };
        },
        mounted() {
            // if (this.CheckIsColor(localStorage.getItem("colorPicker"))) {
            //  // this.theme = localStorage.getItem("colorPicker");
            // }
        },
        watch: {
            theme(val, oldVal) {
                this.$message.success("换肤成功");
                if (typeof val !== "string") return;
                localStorage.setItem("colorPicker", val);
                const themeCluster = this.getThemeCluster(val.replace("#", ""));
                const originalCluster = this.getThemeCluster(oldVal.replace("#", ""));
                const getHandler = (variable, id) => {
                    return () => {
                        const originalCluster = this.getThemeCluster(
                            ORIGINAL_THEME.replace("#", "")
                        );
                        const newStyle = this.updateStyle(
                            this[variable],
                            originalCluster,
                            themeCluster
                        );

                        let styleTag = document.getElementById(id);
                        if (!styleTag) {
                            styleTag = document.createElement("style");
                            styleTag.setAttribute("id", id);
                            document.head.appendChild(styleTag);
                        }
                        styleTag.innerText = newStyle;
                    };
                };

                const chalkHandler = getHandler("chalk", "chalk-style");

                if (!this.chalk) {
                    const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`;
                    this.getCSSString(url, chalkHandler, "chalk");
                } else {
                    chalkHandler();
                }

                const styles = [].slice
                    .call(document.querySelectorAll("style"))
                    .filter(style => {
                        const text = style.innerText;
                        return (
                            new RegExp(oldVal, "i").test(text) && !/Chalk Variables/.test(text)
                        );
                    });
                styles.forEach(style => {
                    const {
                        innerText
                    } = style;
                    if (typeof innerText !== "string") return;
                    style.innerText = this.updateStyle(
                        innerText,
                        originalCluster,
                        themeCluster
                    );
                });
                /* 当颜色改变时,使用vuex储存改变的颜色值 */
                
            }
        },

        methods: {
            CheckIsColor(bgVal) {
                var type = "^#[0-9a-fA-F]{6}$";
                var re = new RegExp(type);
                if (bgVal.match(re) == null) {
                    type =
                        // eslint-disable-next-line no-useless-escape
                        "^[rR][gG][Bb][\(]([\\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\\s]*,){2}[\\s]*(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)[\\s]*[\)]{1}$";
                    re = new RegExp(type);
                    if (bgVal.match(re) == null) {
                        return false;
                    } else {
                        return true;
                    }
                } else {
                    return true;
                }
            },
            updateStyle(style, oldCluster, newCluster) {
                let newStyle = style;
                oldCluster.forEach((color, index) => {
                    newStyle = newStyle.replace(new RegExp(color, "ig"), newCluster[index]);
                });
                return newStyle;
            },

            getCSSString(url, callback, variable) {
                const xhr = new XMLHttpRequest();
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, "");
                        callback();
                    }
                };
                xhr.open("GET", url);
                xhr.send();
            },

            getThemeCluster(theme) {
                const tintColor = (color, tint) => {
                    let red = parseInt(color.slice(0, 2), 16);
                    let green = parseInt(color.slice(2, 4), 16);
                    let blue = parseInt(color.slice(4, 6), 16);

                    if (tint === 0) {
                        // when primary color is in its rgb space
                        return [red, green, blue].join(",");
                    } else {
                        red += Math.round(tint * (255 - red));
                        green += Math.round(tint * (255 - green));
                        blue += Math.round(tint * (255 - blue));

                        red = red.toString(16);
                        green = green.toString(16);
                        blue = blue.toString(16);

                        return `#${red}${green}${blue}`;
                    }
                };

                const shadeColor = (color, shade) => {
                    let red = parseInt(color.slice(0, 2), 16);
                    let green = parseInt(color.slice(2, 4), 16);
                    let blue = parseInt(color.slice(4, 6), 16);

                    red = Math.round((1 - shade) * red);
                    green = Math.round((1 - shade) * green);
                    blue = Math.round((1 - shade) * blue);

                    red = red.toString(16);
                    green = green.toString(16);
                    blue = blue.toString(16);

                    return `#${red}${green}${blue}`;
                };

                const clusters = [theme];
                for (let i = 0; i <= 9; i++) {
                    clusters.push(tintColor(theme, Number((i / 10).toFixed(2))));
                }
                clusters.push(shadeColor(theme, 0.1));
                return clusters;
            }
        }
    };
</script>

<style>
    .theme-picker .el-color-picker__trigger {
        vertical-align: middle;
    }

    .theme-picker-dropdown .el-color-dropdown__link-btn {
        display: none;
    }
</style>
### 如何在 Vue 中通过 Element-UI 自定义文本编辑器组件的功能与样式 在 Vue 项目中,可以通过集成 `vue-quill-editor` 和 Element-UI 来实现富文本编辑器功能,并进一步自定义其配置和样式。以下是具体方法: #### 集成 vue-quill-editor 到 Vue 项目 为了使用 Quill 编辑器作为基础工具,在 Vue 项目中安装并引入 `vue-quill-editor` 是第一步操作[^1]。 ```bash npm install vue-quill-editor quill --save ``` 随后在项目的入口文件或者需要使用的组件中注册该插件: ```javascript import { QuillEditor } from '@quill/editor'; import '@quill/quill/dist/quill.core.css'; // 核心样式 import '@quill/quill/dist/quill.snow.css'; // 主题样式 (Snow) export default { components: { QuillEditor, }, }; ``` #### 使用 Element-UI 的封装方式调整外观 Element-UI 提供了一些内置的表单控件来增强用户体验,可以将其与 `QuillEditor` 结合起来形成更统一的设计风格。例如,利用 `<el-form-item>` 封装编辑器区域以便更好地融入到整个页面布局之中。 ```html <template> <div class="editor-container"> <el-form :model="form" label-width="80px"> <el-form-item label="文章内容"> <QuillEditor v-model:content="form.content" contentType="html" theme="snow"/> </el-form-item> </el-form> </div> </template> <script> export default { data() { return { form: { content: '', } }; } } </script> ``` #### 定制化设置选项 对于高级需求如上传图片等功能,则需扩展默认行为。这通常涉及重写某些模块的行为逻辑以及添加额外参数支持。 下面展示了一个简单的例子——允许用户从本地选择图像并将它们嵌入文档内: ```javascript methods: { onImageAdded(file, Editor, cursorLocation) { const formData = new FormData(); formData.append('image', file); this.$axios.post('/upload/image', formData).then((result) => { let url = result.data.url; // 获取服务器返回地址 Editor.insertEmbed(cursorLocation, 'image', url); // 插图至指定位置 }); } }, mounted(){ var toolbarOptions = [ ['bold', 'italic'], [{'list': 'ordered'}, {'list': 'bullet'}], [{header: [false, 1, 2]}], ['link','image'] ]; require('quill').register({ 'modules/imageUploader': function(quill){ this.quill=quill; } }); this.editor=new Quill('#editor',{ modules:{ imageUploader:{onImageAdded:this.onImageAdded},// 注册事件处理器 toolbar:toolbarOptions }, placeholder:'请输入...', theme:"snow" }) } ``` 以上代码片段展示了如何监听图片插入动作并通过 AJAX 请求完成实际的数据传输过程。 #### 修全局主题颜色或其他 CSS 属性 如果希望变整体配色方案或者其他视觉效果,可以直接覆盖原有类名下的规则即可达到目的。比如更按钮背景色为例: ```css /* 覆盖 snow 主题中的按钮激活状态 */ .ql-toolbar .ql-active{ background-color:#ffcccb !important ; color:black!important; border:none !important; } /* 设置字体大小下拉框宽度 */ .ql-sizes{ width:auto !important; max-width:unset !important; padding-right:.7em !important; } ``` 上述样式的应用可通过单独创建 SCSS 文件导入项目或是直接书写于 style scoped 块内部完成。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值