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

Posted

技术标签:

【中文标题】Vue.js/NuxtJS - 如何创建具有可通过 JSON 配置文件自定义的默认设计的组件【英文标题】:Vue.js/NuxtJS - how to create components with a default design customizable by a JSON configuration file 【发布时间】:2021-10-12 15:14:06 【问题描述】:

我正在开发一个 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"
  ,

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

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

我首先想到的是使用 CSS 变量,即 将允许我创建具有默认值的变量,但我 将能够覆盖样式内部。我为测试创建了一个示例组件,它与 CSS 属性和 v-deep 伪元素一起使用。但是,这意味着我必须在自定义组件中为每个客户端创建一个类,而这正是我想要避免的。我首先想到了这种方法,因为它可以让我更灵活地选择如何在样式中使用这些设计颜色。

例子:

// 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;
    
  

我见过/deep/ 选择器或::v-deep 伪选择器,但我认为这不是一个非常干净的解决方案,因为它会在代码库中大量使用。来自父母的样式组件会使代码难以维护。

另一种方法是在 setup 方法中传递一个变量,例如 classArray,以在 DOM 元素上动态绑定 CSS 类。不过,为每个客户端创建一个带有关联样式的 CSS 类太麻烦了。

像这样:

<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>

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

感谢您的帮助!

【问题讨论】:

我不确定我是否关注 CSS vars parent/child 的问题。但是您会以这种方式失去 SASS 功能(颜色处理等)。最省心的方法是***.com/questions/62370457/…。 我已经使用 nuxt-style-resources 来全局定义 Sass 变量!但这并不能解释我如何为每个客户端创建通用代码,我必须在每个页面或组件中创建特定的样式,对吧?还是您有其他想法? 是的,我的意思是这需要为每个客户端编译应用程序,这可能不是您所希望的,但可能是唯一不使用 CSS 变量的选项。你能澄清 CSS vars 的问题吗?您可以使用setProperty 在配置加载时动态定义它们,然后它们可以与 SASS 函数一起使用,例如primaryColor() 生成类似var(--primary-color, $defaultPrimaryColor) 的内容。 我让 CSS 属性与 v-deep 一起工作!但问题仍然是我必须在自定义组件中为每个客户端创建一个类,而这正是我想要避免的。你是在谈论这个 setProperty 吗? developer.mozilla.org/en-US/docs/Web/CSS/… 编辑了我的答案以添加 CSS vars 工作代码 【参考方案1】:

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

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

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


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

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

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

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

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

【讨论】:

我没有正确理解您的解决方案,现在我明白了,感谢您分享您的观点!

以上是关于Vue.js/NuxtJS - 如何创建具有可通过 JSON 配置文件自定义的默认设计的组件的主要内容,如果未能解决你的问题,请参考以下文章

动态对象,可持久保存到 Azure 并可通过 Dynamic Linq 查询

漏洞扫描设备检测出服务存在漏洞:可通过HTTPS获取远端WWW服务版信息,如何解决?

在注册表中具有特定的键,可通过AppliesTo字符串值应用于多个条件

如何查看“屏幕截图:可通过屏幕获取”?

如何使 UWP TextBlock 可通过手写进行编辑?

可通过代码绘制的圆角