feat(components): 为 contenteditable组件添加错误消息显示

- 在 contenteditable.vue 中添加了 errorMessage属性和对应的样式
- 在多个组件中为 contenteditable 添加了 errorMessage 属性
- 优化了部分代码格式,如空格、换行等
This commit is contained in:
陈昱达
2025-03-20 18:28:39 +08:00
parent 289b865c51
commit bfa163925e
9 changed files with 109 additions and 50 deletions

View File

@@ -1,5 +1,6 @@
<template>
<div class="flex contenteditable align-center space-between" :class="className">
<div :class="className">
<div class="flex contenteditable align-center space-between">
<p
:id="'editor' + id"
ref="editor"
@@ -21,12 +22,16 @@
<slot name="right-icon"></slot>
</div>
</div>
<div v-if="showAction && active" ref="editorAction" class="editor-action">
<button v-for="item in actions" :key="item.name" @click="funEvent(item, $event)">
<van-icon class-prefix="mobilefont" :name="item.icon"></van-icon>
</button>
</div>
<div class="error-message">
{{ errorMessage }}
<!-- <slot name="error"></slot>-->
</div>
</div>
</template>
<script setup>
@@ -49,6 +54,10 @@ const modelValue = defineModel('modelValue', {
default: ''
});
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
const active = defineModel('active', {
type: Boolean,
default: false
@@ -169,10 +178,10 @@ const isEmptyContent = (html) => {
const trimmedHtml = html.trim();
// 检查是否为空字符串、仅包含 <br> 或仅包含 <p><br></p>
return (
trimmedHtml === ''
|| trimmedHtml === '<br>'
|| trimmedHtml === '<p><br></p>'
|| trimmedHtml === '<p></p>'
trimmedHtml === '' ||
trimmedHtml === '<br>' ||
trimmedHtml === '<p><br></p>' ||
trimmedHtml === '<p></p>'
);
};
@@ -299,7 +308,11 @@ const insertImageAtCaret = (html) => {
.right-icon {
color: #c4c9d4;
}
.error-message {
color: red;
flex: none;
font-size: 12px;
}
.editor-action {
position: fixed;
bottom: 0;

View File

@@ -15,6 +15,7 @@
className="contenteditable-label"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
>
</contenteditable>
</template>
@@ -108,7 +109,7 @@ import { defineAsyncComponent } from 'vue';
const isPreview = defineModel('isPreview', { default: false, type: Boolean });
const choiceValue = defineModel('answer', { default: '1', type: String });
const value = defineModel('checkboxAnswer', { default: [1, 2], type: Array });
const errorMessage = defineModel('errorMessage', { default: '', type: String });
const Contenteditable = defineAsyncComponent(() => import('@/components/contenteditable.vue'));
defineProps({
active: {

View File

@@ -15,6 +15,7 @@
v-model="element.stem"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
></contenteditable>
</template>
<template #input>
@@ -50,6 +51,10 @@ const props = defineProps({
},
questionType: { type: [String, Number], default: 4 }
});
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
// 创建一个本地副本以保存更改
const emit = defineEmits(['update:element']);
const { element } = toRefs(props);

View File

@@ -51,6 +51,11 @@ const { element } = toRefs(props);
// }
// }
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
const emit = defineEmits(['update:element']);
const emitValue = () => {
emit('update:element', element.value);
@@ -76,6 +81,7 @@ const emitValue = () => {
v-model="element.stem"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
></contenteditable>
</template>

View File

@@ -49,6 +49,10 @@ const emitValue = () => {
// console.log(question.value);
emit('update:element', question.value);
};
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
</script>
<template>
@@ -64,7 +68,12 @@ const emitValue = () => {
</template>
<!-- 使用 title 插槽来自定义标题 -->
<template #label>
<contenteditable v-model="question.stem" :active="active" @blur="emitValue" />
<contenteditable
v-model="question.stem"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
/>
</template>
<template #input>

View File

@@ -11,7 +11,12 @@
{{ index + 1 }}
</template>
<template #label>
<contenteditable v-model="element.stem" :active="active" @blur="saveStem"></contenteditable>
<contenteditable
v-model="element.stem"
:active="active"
@blur="saveStem"
:errorMessage="errorMessage"
></contenteditable>
</template>
<template #input>
<div
@@ -43,7 +48,7 @@
</template>
<script setup>
import { ref } from 'vue';
import { defineModel, ref } from 'vue';
import RateCharacter from './RateCharacter.vue';
const value = defineModel('value', { default: -1, type: Number });
@@ -60,7 +65,10 @@ const isPreview = defineModel('isPreview', { default: false, type: Boolean });
sn: { type: String, default: '' },
questionType: { type: [String, Number], default: 4 }
});
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
/**
* element === question
* @type {ModelRef<Object, string, Object, Object>}

View File

@@ -15,6 +15,7 @@
v-model="element.stem"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
></contenteditable>
</template>
<template #input>
@@ -49,7 +50,7 @@
</template>
<script setup>
import { ref } from 'vue';
import { defineModel, ref } from 'vue';
import RateCharacter from './RateCharacter.vue';
const isPreview = defineModel('isPreview', { default: false, type: Boolean });
@@ -65,7 +66,10 @@ defineProps({
sn: { type: String, default: '' },
questionType: { type: [String, Number], default: 4 }
});
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
const emit = defineEmits(['update:element']);
const chooseId = ref('');

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, onMounted, ref, useTemplateRef, toRefs } from 'vue';
import { defineModel } from 'vue/dist/vue';
const props = defineProps<{
element: any;
@@ -55,7 +56,10 @@ const togglePen = () => {
isEraser.value = !isEraser.value;
setPenStyle();
};
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
onMounted(() => {
if (!signatureCanvas.value) return;
// 将 canvas 宽度和窗口的宽度保持一致
@@ -181,7 +185,12 @@ const emitValue = () => {
{{ index + 1 }}
</template>
<template #label>
<contenteditable v-model="element.stem" :active="active" @blur="emitValue"></contenteditable>
<contenteditable
v-model="element.stem"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
></contenteditable>
</template>
<template #input>
<div class="sign-question">

View File

@@ -15,6 +15,7 @@
v-model="element.stem"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
></contenteditable>
</template>
</van-field>
@@ -22,7 +23,7 @@
</template>
<script setup>
import contenteditable from '@/components/contenteditable.vue';
import { toRefs } from 'vue';
import { defineModel, toRefs } from 'vue';
const props = defineProps({
element: {
type: Object,
@@ -41,7 +42,10 @@ const props = defineProps({
default: 0
}
});
const errorMessage = defineModel('errorMessage', {
type: String,
default: ''
});
const { element } = toRefs(props);
const emit = defineEmits(['update:element']);