actorref(src): 重构组件以提高代码可维护性

- 更新了多个组件的属性定义和事件处理逻辑
- 优化了部分代码结构,提高了代码的可读性和可维护性
-调整了部分样式,提升了用户体验
This commit is contained in:
陈昱达
2025-03-19 17:26:40 +08:00
parent 62cfc0986e
commit 1356c5e72c
11 changed files with 104 additions and 104 deletions

View File

@@ -1,6 +1,7 @@
<template> <template>
<div class="flex contenteditable align-center space-between" :class="className"> <div class="flex contenteditable align-center space-between" :class="className">
<p <p
v-if="active"
:id="'editor' + id" :id="'editor' + id"
ref="editor" ref="editor"
:contenteditable="active" :contenteditable="active"
@@ -8,6 +9,7 @@
@focus="onFocus" @focus="onFocus"
v-html="modelValue" v-html="modelValue"
></p> ></p>
<p v-else ref="editor" class="van-field contenteditable-content" v-html="modelValue"></p>
<div class="right-icon ml10"> <div class="right-icon ml10">
<slot name="right-icon"></slot> <slot name="right-icon"></slot>
</div> </div>
@@ -25,21 +27,20 @@ import { defineEmits, ref, onMounted, watch } from 'vue';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import CommonApi from '@/api/common.js'; import CommonApi from '@/api/common.js';
const props = defineProps({ defineProps({
modelValue: {
type: String,
default: ''
},
className: { className: {
type: String, type: String,
default: '' default: ''
},
active: {
type: Boolean,
default: false
} }
}); });
const modelValue = defineModel('modelValue', {
type: String,
default: ''
});
const active = defineModel('active', {
type: Boolean,
default: false
});
const id = ref(uuidv4()); const id = ref(uuidv4());
const editor = ref(null); const editor = ref(null);
@@ -47,10 +48,9 @@ const editorAction = ref(null);
const emit = defineEmits(['update:modelValue', 'blur']); const emit = defineEmits(['update:modelValue', 'blur']);
const save = (e) => { const save = (e) => {
emit('update:modelValue', e.innerHTML); emit('update:modelValue', e.innerHTML);
emit('blur', e.innerHTML);
}; };
const savedRange = ref(null); const savedRange = ref(null);
const functions = { const functions = {
boldModern: () => { boldModern: () => {
document.execCommand('bold', true, null); document.execCommand('bold', true, null);
@@ -103,16 +103,17 @@ const funEvent = (item) => {
}; };
watch( watch(
() => props.active, () => active.value,
(newVal) => { (newVal) => {
if (newVal) { if (!newVal) {
// showAction.value = true;
} else {
save(editor.value); save(editor.value);
setTimeout(() => { setTimeout(() => {
showAction.value = false; showAction.value = false;
}, 100); }, 100);
} }
},
{
deep: true
} }
); );
@@ -162,7 +163,7 @@ onMounted(() => {
if (!isEditor && !isActionBar) { if (!isEditor && !isActionBar) {
showAction.value = false; showAction.value = false;
save(editor.value); save(editor.value);
emit('blur', editor.value); // emit('blur', editor.value);
} }
}); });

View File

@@ -192,7 +192,12 @@ const saveLogics = () => {
}; };
// 当前题目 // 当前题目
const activeQuestion = ref(props.data); const activeQuestion = defineModel('data', {
type: Object,
default: () => {
// 传递
}
});
// 设置更新 // 设置更新
const show = ref(false); const show = ref(false);
const questionShow = ref(false); const questionShow = ref(false);
@@ -251,7 +256,6 @@ watch(
immediate: true immediate: true
} }
); );
// 打开题目弹窗 // 打开题目弹窗
const openQuestionActionModel = () => { const openQuestionActionModel = () => {
show.value = true; show.value = true;

View File

@@ -14,8 +14,8 @@
<van-stepper <van-stepper
v-model="localConfig.min" v-model="localConfig.min"
button-size="22px" button-size="22px"
@blur="minChange"
@change="minChange" @change="minChange"
@blur="minChange(localConfig.min)"
/> />
</div> </div>
<div class="score"> <div class="score">
@@ -24,8 +24,8 @@
v-model="localConfig.max" v-model="localConfig.max"
:max="maxLimit" :max="maxLimit"
button-size="22px" button-size="22px"
@blur="maxChange"
@change="maxChange" @change="maxChange"
@blur="maxChange(localConfig.max)"
/> />
</div> </div>
<div class="score"> <div class="score">
@@ -35,7 +35,7 @@
:min="0" :min="0"
button-size="22px" button-size="22px"
@blur="intervalChange" @blur="intervalChange"
@change="intervalChange" @change="intervalChange(localConfig.score_interval)"
/> />
</div> </div>
</van-cell-group> </van-cell-group>

View File

@@ -40,17 +40,9 @@
</template> </template>
<script setup> <script setup>
import QuestionAction from '@/views/Design/components/ActionCompoents/QuestionAction.vue'; import QuestionAction from '@/views/Design/components/ActionCompoents/QuestionAction.vue';
import { ref } from 'vue';
import { basicQuesTypeList } from '@/utils/common.js'; import { basicQuesTypeList } from '@/utils/common.js';
const props = defineProps({ const props = defineProps({
element: {
type: Object,
default: () => {
// 此方法目前为空,未来可能扩展
}
},
index: { index: {
type: Number, type: Number,
default: 0 default: 0
@@ -86,14 +78,19 @@ const getQuestionType = (type) => {
return typeName; return typeName;
}; };
const element = ref(props.element); const element = defineModel('element', {
type: Object,
default: () => {
return {};
}
});
// 选中题目后出现的操作 // 选中题目后出现的操作
const emit = defineEmits(['getChooseQuestionId', 'move', 'copy', 'setting', 'logics']); const emit = defineEmits(['getChooseQuestionId', 'move', 'copy', 'setting', 'logics']);
// 选中题目 // 选中题目
const chooseItem = () => { const chooseItem = () => {
emit('getChooseQuestionId', props.element, props.index); emit('getChooseQuestionId', element.value, props.index);
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -117,8 +117,7 @@ function handleMatrixRadioChange(row: number, col: number) {
// emits('update:matrixAnswer', props.matrixAnswer); // emits('update:matrixAnswer', props.matrixAnswer);
// emits('update:rowRecord', props.rowRecord); // emits('update:rowRecord', props.rowRecord);
// }; // };
const emitValue = (val: unknown) => { const emitValue = () => {
console.log(val);
emit('update:element', element.value); emit('update:element', element.value);
}; };
</script> </script>

View File

@@ -49,14 +49,10 @@
</template> </template>
<script setup> <script setup>
import { ref, toRefs, watch } from 'vue'; import { ref } from 'vue';
import RateCharacter from './RateCharacter.vue'; import RateCharacter from './RateCharacter.vue';
const props = defineProps({ defineProps({
element: {
type: Object,
required: true
},
active: { active: {
type: Boolean, type: Boolean,
default: false default: false
@@ -72,18 +68,14 @@ const props = defineProps({
const emit = defineEmits(['update:element']); const emit = defineEmits(['update:element']);
const chooseId = ref(''); const chooseId = ref('');
const { element } = toRefs(props);
const emitValue = (newVal) => { const element = defineModel('element', {
emit('update:element', newVal || element.value); type: Object,
required: true
});
const emitValue = () => {
emit('update:element', element.value);
}; };
watch(
element.value,
(newVal) => {
emitValue(newVal);
},
{ deep: true }
);
const chooseOption = (item) => { const chooseOption = (item) => {
chooseId.value = item.id; chooseId.value = item.id;

View File

@@ -46,13 +46,10 @@ const test = ref(1);
setTimeout(() => { setTimeout(() => {
test.value = 2; test.value = 2;
}, 300); }, 300);
const props = defineProps({ const config = defineModel('config', {
config: {
type: Object, type: Object,
required: true required: true
}
}); });
const index = defineModel('index', { const index = defineModel('index', {
type: Number type: Number
}); });
@@ -94,26 +91,29 @@ watch(
// 监听 min、max 和 score_interval 的变化 // 监听 min、max 和 score_interval 的变化
watch( watch(
() => [props.config.min, props.config.max, props.config.score_interval], () => [config.value.min, config.value.max, config.value.score_interval],
(newValues) => { (newValues) => {
const [newMin, newMax, newScoreInterval] = newValues; const [newMin, newMax, newScoreInterval] = newValues;
renderScore(newMin, newMax, newScoreInterval); renderScore(newMin, newMax, newScoreInterval);
}, },
{ immediate: true } { immediate: true, deep: true }
); );
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
ul { ul {
display: flex; display: flex;
align-items: center;
justify-content: space-between;
//margin-bottom: 10px; //margin-bottom: 10px;
} }
.rate_item { .rate_item {
width: 21px; width: 20px;
height: 21px; height: 20px;
margin: 0 5px 0 0;
//margin: 0 5px 0 0;
border: 1px solid #979797; border: 1px solid #979797;
border-radius: 5px; border-radius: 5px;

View File

@@ -51,7 +51,7 @@
import { ref, defineProps, onMounted } from 'vue'; import { ref, defineProps, onMounted } from 'vue';
import { deleteTemplate } from '@/api/home/index.js'; import { deleteTemplate } from '@/api/home/index.js';
import { showDialog, showSuccessToast, showFailToast } from 'vant'; import { showDialog, showSuccessToast, showFailToast } from 'vant';
import { useRouter } from 'vue-router'; // import { useRouter } from 'vue-router';
import png11 from '@/assets/img/home/11.png'; import png11 from '@/assets/img/home/11.png';
import png13 from '@/assets/img/home/13.png'; import png13 from '@/assets/img/home/13.png';
import png14 from '@/assets/img/home/14.png'; import png14 from '@/assets/img/home/14.png';
@@ -61,7 +61,7 @@ import png17 from '@/assets/img/home/17.png';
import png18 from '@/assets/img/home/18.png'; import png18 from '@/assets/img/home/18.png';
import png31 from '@/assets/img/home/31.png'; import png31 from '@/assets/img/home/31.png';
const router = useRouter(); // const router = useRouter();
const { info } = defineProps({ const { info } = defineProps({
info: { info: {
type: Object, type: Object,
@@ -70,13 +70,14 @@ const { info } = defineProps({
} }
}); });
const userInfo = ref({ userName: '' }); const userInfo = ref({ userName: '' });
const toDetail = (item) => { const toDetail = () => {
router.push({ // return false
path: '/create', // router.push({
query: { // path: '/create',
sn: item.sn // query: {
} // sn: item.sn
}); // }
// });
}; };
const deleteItem = (item) => { const deleteItem = (item) => {
showDialog({ showDialog({
@@ -107,7 +108,8 @@ const setImg = (code) => {
18: png18, 18: png18,
31: png31 31: png31
}; };
return imageMap[code] || png11; // 默认返回 png11 如果 code 不存在 // 默认返回 png11 如果 code 不存在
return imageMap[code] || png11;
}; };
onMounted(() => { onMounted(() => {

View File

@@ -553,11 +553,13 @@ watch(
// 保存 目前没有任何逻辑可以执行所有保存 // 保存 目前没有任何逻辑可以执行所有保存
const saveAs = () => { const saveAs = () => {
sync({ sn: route.query.sn }).then(() => {
// 保存所有 // 保存所有
showConfirmDialog({ showConfirmDialog({
message: '问卷保存成功', message: '问卷保存成功',
showCancelButton: false showCancelButton: false
}); });
});
}; };
// 投放 // 投放
const publishQuestion = () => { const publishQuestion = () => {

View File

@@ -1429,17 +1429,20 @@ function hasNConsecutiveNumbers(arr, n, onTrue, onFalse) {
// eslint-disable // eslint-disable
// 跳转链接 // 跳转链接
function toUrl(url) { function toUrl(url) {
// 创建一个新的变量来存储修改后的 URL
let modifiedUrl = url;
// 判断是否小程序路径 // 判断是否小程序路径
if (url[0] === '/') { if (modifiedUrl[0] === '/') {
// 判断是否在小程序环境 // 判断是否在小程序环境
wx.miniProgram.getEnv(() => { wx.miniProgram.getEnv(() => {
wx.miniProgram.redirectTo({ url }); wx.miniProgram.redirectTo({ url: modifiedUrl });
}); });
} else { } else {
if (url.indexOf('http://') === -1 && url.indexOf('https://') === -1) { if (modifiedUrl.indexOf('http://') === -1 && modifiedUrl.indexOf('https://') === -1) {
url = `http://${url}`; modifiedUrl = `http://${modifiedUrl}`;
} }
open(url); open(modifiedUrl);
} }
} }
/* eslint-enable */ /* eslint-enable */

View File

@@ -121,8 +121,8 @@ function shareLink() {
const params = { const params = {
type: 'shareToWx', type: 'shareToWx',
title: title:
surveyTitle.value || surveyTitle.value
(publishInfo.value.download_url.title || (publishInfo.value.download_url.title
? publishInfo.value.download_url.title.replace(/_发布二维码\.[a-zA-Z]+$/, '') ? publishInfo.value.download_url.title.replace(/_发布二维码\.[a-zA-Z]+$/, '')
: ''), : ''),
description: publishInfo.value.desc || '填写问卷', description: publishInfo.value.desc || '填写问卷',