feat:用shadow dom隔离html样式
This commit is contained in:
1
apps/web-antd/src/components/shadow-container/index.ts
Normal file
1
apps/web-antd/src/components/shadow-container/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as ShadowContainer } from './shadow-container.vue';
|
||||
@@ -0,0 +1,47 @@
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
// 可以传递样式字符串来自定义内部样式
|
||||
styles: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const shadowHost = ref(null);
|
||||
|
||||
const initShadow = () => {
|
||||
if (shadowHost.value && !shadowHost.value.shadowRoot) {
|
||||
const shadowRoot = shadowHost.value.attachShadow({ mode: 'open' });
|
||||
|
||||
shadowRoot.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
all: initial;
|
||||
display: block;
|
||||
contain: content;
|
||||
|
||||
${props.styles}
|
||||
}
|
||||
|
||||
</style>
|
||||
<div class="shadow-content">${props.content}</div>
|
||||
`;
|
||||
} else if (shadowHost.value && shadowHost.value.shadowRoot) {
|
||||
shadowHost.value.shadowRoot.querySelector('.shadow-content').innerHTML =
|
||||
props.content;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(initShadow);
|
||||
watch(() => props.content, initShadow);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="shadowHost"></div>
|
||||
</template>
|
||||
@@ -10,6 +10,7 @@ import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
|
||||
import { deleteComment } from '#/api/license/comment';
|
||||
import { ShadowContainer } from '#/components/shadow-container';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import CreateComment from './create-comment.vue';
|
||||
@@ -104,7 +105,11 @@ const formatContent = computed(() => {
|
||||
<template #content>
|
||||
<div>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<span class="rich-text-comment-content" v-html="formatContent"></span>
|
||||
<!-- <span class="rich-text-comment-content" v-html="formatContent"></span> -->
|
||||
<ShadowContainer
|
||||
:content="formatContent"
|
||||
styles="font-family: Helvetica,Arial,sans-serif; font-size:16px;"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
@@ -194,6 +199,11 @@ const formatContent = computed(() => {
|
||||
</template>
|
||||
<style>
|
||||
:where(.css-dev-only-do-not-override-14589v).ant-comment .ant-comment-actions {
|
||||
margin-top: 16px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
:where(.css-dev-only-do-not-override-14589v).ant-comment
|
||||
.ant-comment-content-author {
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -149,12 +149,13 @@ export function useProjectGridColumns(): VxeTableGridOptions<ProgressApi.Progres
|
||||
{
|
||||
field: 'content',
|
||||
title: '进展记录',
|
||||
type: 'html',
|
||||
className: 'rich-text-comment-content-table',
|
||||
// type: 'html',
|
||||
// className: 'rich-text-comment-content-table',
|
||||
showOverflow: false,
|
||||
align: 'left',
|
||||
// headerAlign: 'center',
|
||||
minWidth: 600,
|
||||
slots: { default: 'contentDefault' },
|
||||
},
|
||||
{
|
||||
field: 'updateTime',
|
||||
|
||||
@@ -7,6 +7,7 @@ import dayjs from 'dayjs';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { exportProject, getProgressByProjectPage } from '#/api/report/progress';
|
||||
import { ShadowContainer } from '#/components/shadow-container';
|
||||
|
||||
import { useProjectGridColumns, useProjectGridFormSchema } from '../data';
|
||||
|
||||
@@ -149,5 +150,15 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Grid table-title="项目进展" />
|
||||
<Grid table-title="项目进展">
|
||||
<template #contentDefault="{ row }">
|
||||
<!-- <div v-html="row.content" style="white-space: pre-wrap"></div> -->
|
||||
<ShadowContainer
|
||||
:content="row.content"
|
||||
styles="font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, 'Helvetica Neue',
|
||||
arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol', 'Noto Color Emoji';"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user