imzbf / md-editor-v3

Markdown editor for vue3, developed in jsx and typescript, dark theme、beautify content by prettier、render articles directly、paste or clip the picture and upload it...
https://imzbf.github.io/md-editor-v3
MIT License
1.63k stars 156 forks source link

黑暗模式下服务端渲染和客户端渲染不一致有办法解决吗? #598

Closed kingwrcy closed 4 months ago

kingwrcy commented 4 months ago

Describe the issue

黑暗模式下服务端渲染和客户端渲染不一致有办法解决吗?

这个暗色还是亮色服务端是不知道的,服务端一直都是亮色模式,只有客户端知道,现在一直报服务端和客户端渲染不一致.

有啥好办法吗?还是只能client-only?

Procedure version

"md-editor-v3": "^4.15.0"

Reproduction link

No response

imzbf commented 4 months ago

这个模式是通过css控制的,服务端跟它有什么关系?

kingwrcy commented 4 months ago

使用vueuse的 const color = useColorMode() 这个代码在服务端获取到的值是system,在客户端获取到的是dark/light,如果把这个获取到的值写入到mdpreview的组件里,就会得到在服务端和客户端渲染不一致的问题. 不知道我说清楚了没有.

kingwrcy commented 4 months ago

我弄了个demo

操作流程

  1. 点击下面的切换颜色按钮,变成黑色模式
  2. 刷新页面,控制台就会报错

因为服务端不知道客户端的模式是亮色还是暗色,所以默认是亮色,但是客户端其实已经是暗色了,所以2边渲染不一致.

imzbf commented 4 months ago

这看起是需要合适获取useColorMode的值的问题,建议搜索它相关的关键词

这里好像有一个小伙伴遇到过相同的问题,他记录了解决方案:https://juejin.cn/post/7102416107507548168

kingwrcy commented 4 months ago

感觉是否可以借鉴tailwindcss,unocss等css框架的做法,自动识别呢?不需要手动填写theme参数.

tailwindcss,unocss等css框架的做法是切换模式的时候会动态的在html根节点增加/删除dark class类,如果md-editor-v3也支持这个dark class的话,是不是更好,只是个建议.

imzbf commented 4 months ago

不会,首先这只是一个组件而非库,当使用ui库,别的规范是在html节点上修改data-theme属性,而组件又是修改class,无法统一。其次组件的原理和上面的原理是一致的,只是组件只负责组件不负责全局

kingwrcy commented 4 months ago

你上面贴的链接本质还是ClientOnly,这违背了SSR的本意.

这是那个文章里的 ColorScheme组件的源码,治标不治本

<script>
import { componentName } from "#color-mode-options";
export default {
  name: componentName,
  props: {
    placeholder: String,
    tag: {
      type: String,
      default: "span"
    }
  }
};
</script>

<template>
  <ClientOnly
    :placeholder="placeholder"
    :placeholder-tag="tag"
  >
    <slot />
  </ClientOnly>
</template>

如果md-editor-v3支持了tailwindcss的 dark class,那这个问题就不会这样. 另外如果官方不打算支持这个特性,那请问我有什么办法自己支持吗?覆盖class类吗? 貌似无解,现在问题是服务端不知道客户端的主题色,所以服务端和客户端永远没法保持一致.

tailwindcss类的css框架为了避免这个问题,选择不改动组件本身,而是要求组件本身通过css适配这种顶级的dark样式.

imzbf commented 4 months ago

是的,其实我也同意这种方式,但是不这样做的原因是,不能去限制用户使用同一套css方案,比如你提到的tailwindcss,是添加class,而arco-design又是通过设置arco-theme属性,这得秦始皇来管理一下才行

kingwrcy commented 4 months ago

那只能自己想办法解决了,不用md-editor-v3的theme属性,把那个default的暗黑模式css复制出来,自己在每个class前面加上个.dark,还有别的好办法吗?

imzbf commented 3 months ago

你可以强制覆盖编辑器的css变量,举例:如果你得暗夜主题是通过<html class="dark">实现的

那么通过下面的代码强制覆盖编辑器的暗夜主题

html .md-editor {
  --md-color: #222;
  --md-hover-color: #000;
  --md-bk-color: #fff;
  --md-bk-color-outstand: #f6f6f6;
  --md-bk-hover-color: #f5f7fa;
  --md-border-color: #e6e6e6;
  --md-border-hover-color: #b9b9b9;
  --md-border-active-color: #999;
  --md-modal-mask: #00000073;
  --md-modal-shadow: 0px 6px 24px 2px #00000019;
  --md-scrollbar-bg-color: #e2e2e2;
  --md-scrollbar-thumb-color: #0000004d;
  --md-scrollbar-thumb-hover-color: #00000059;
  --md-scrollbar-thumb-active-color: #00000061;
}
html.dark .md-editor {
  --md-color: #999;
  --md-hover-color: #bbb;
  --md-bk-color: #000;
  --md-bk-color-outstand: #111;
  --md-bk-hover-color: #1b1a1a;
  --md-border-color: #2d2d2d;
  --md-border-hover-color: #636262;
  --md-border-active-color: #777;
  --md-modal-mask: #00000073;
  --md-modal-shadow: 0px 6px 24px 2px #00000066;
  --md-scrollbar-bg-color: #0f0f0f;
  --md-scrollbar-thumb-color: #2d2d2d;
  --md-scrollbar-thumb-hover-color: #3a3a3a;
  --md-scrollbar-thumb-active-color: #3a3a3a;
}

根据你的实际再调整

imzbf commented 3 months ago

有一个无法实现的模块:mermaid,它需要知道具体是暗夜还是默认主题,来生成具体的内容,通过css无法控制到,你需要知道,如果项目没有用到它,建议把它禁用掉