首页 > 解决方案 > Vue.js/NuxtJS - 如何创建具有可通过 JSON 配置文件自定义的默认设计的组件

问题描述

我正在开发一个 NuxtJS 网站,默认情况下页面/组件可以具有通用设计,或者可以由客户端自定义,并且将在 url 中指定。

仅此而已:

http://localhost:3000/registration- 对于通用页面

http://localhost:3000/client-name/registration- 客户特定页面

为了实现这个目标,我为每个客户端(比如说client-name.json)有一个 JSON 配置文件,它具有这种结构。

{
  "some_configuration_property": {},
  "another_configuration_property": {},
  "design": {
    "logoUrl": "/assets/client-name/logo.png",
    "backgroundColor": "#000000",
    "primaryColor": "#ffffff",
    "secondaryColor": "#ffff00"
  },
}

首先,我实现了路由系统,并且可以<script>在 setup 方法中(我使用@nuxt/composition-api)根据当前路由(在该路由的 Vue 文件的标签内)成功读取每个客户端的配置。

我现在面临的问题是弄清楚如何将这些“设计变量”传递到<style>我使用 SCSS 的 Vue 文件的标签中。我想要实现的行为是为特定组件/页面提供默认设计,但这可能会被每个客户端特定的这些“设计变量”覆盖。

例子:

// From the customizable component
.my-button {
   color: (--button-color, teal);
}

// Styling from a parent component/view
// Had to create a selector with a style like <div> for superior specificity though, not so clean
v::deep {
  div {
    &.my-button {
      --button-color: purple;
    }
  }
}

像这样:

<template>
  <my-button :class="classArray"></my-button>
</template>

<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api'

export default defineComponent({
  name: 'MyPage',
  setup() {
    const clientName = 'someClientName';
    const classArray = [clientName]
    return { classArray };
  },
})
</script>

<style lang="scss" scoped>
.someClientName {
  // some custom styles
}
</style>

在这种情况下你会采取什么方法?

感谢帮助!

标签: javascriptcssjsonvue.jsnuxt.js

解决方案


如果需要在运行时加载自定义主题配置,则需要使用 CSS 变量(属性)。它们可以包装在 SCSS 函数中并具有默认主题回退:

// theme.scss
$primaryColor: #abc;
// $buttonColor: $primaryColor

@function primaryColor() {
  @return #{var(--primary-color, $primaryColor)}
}

@function buttonColor() {
  @return #{var(--button-color, primaryColor())}
}

然后primaryColor(), etc 被使用而不是直接使用$primaryColor, etc 就像在常规 SCSS 主题中所做的那样:

// From the customizable component
.my-button {
   color: buttonColor();
}

自定义主题可以在加载到整个文档或它的一部分(组件的层次结构)时应用,这些文档应该受自定义主题的影响:

const config = await loadClientConfig();
document.documentElement.style.setProperty(--primary-color, config.design.primaryColor)

推荐阅读