mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-09 02:18:55 +08:00
refactor: 四端完成 Options API → script setup + vuex → pinia 迁移
- buyer(95) / seller(169) / im(53) / manager(280) 共 597 个组件全部从 Options API 转换为 <script setup> - 四端 vuex 全部移除,状态管理统一迁移至 pinia 4(stores/ 目录) - util.js 等基础设施去除 vm 首参依赖;全局属性($Message/$filters 等)在 script 内改为具名导入 - 被外部 ref 访问的公共组件均已补齐 defineExpose(清单见各端 MIGRATION-VUE3.md) - 各端 eslint 启用 vue/component-api-style 防止新代码回退 Options API - 四端 yarn build 全部通过;迁移约定与注意事项已更新至各端 MIGRATION-VUE3.md
This commit is contained in:
@@ -8,132 +8,142 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
onActivated,
|
||||
onDeactivated,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
watch,
|
||||
} from "vue";
|
||||
import { initEditor } from "@/components/editor/config";
|
||||
import uploadImage from "@/components/editor/upload-image.vue";
|
||||
export default {
|
||||
components:{uploadImage},
|
||||
name: "Tinymce",
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
height:{
|
||||
type:String,
|
||||
default:'500px'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editorContent() {
|
||||
return this.modelValue ?? this.value ?? "";
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 引入编辑器的配置
|
||||
initEditor,
|
||||
hasChange: false, // 标记内容是否有更改
|
||||
hasInit: false, // 标记编辑器是否已初始化
|
||||
tinymceId:
|
||||
"tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + ""), // 生成唯一的编辑器 ID
|
||||
fullscreen: false, // 标记编辑器是否处于全屏模式
|
||||
toolbar: [], // 工具栏配置
|
||||
content: "", // 编辑器内容
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
watch: {
|
||||
editorContent: {
|
||||
handler(val) {
|
||||
if (!this.hasChange && this.hasInit) {
|
||||
// 当内容有更改且编辑器已初始化时,更新编辑器的内容
|
||||
this.$nextTick(() => {
|
||||
const editor = window.tinymce?.get(this.tinymceId);
|
||||
if (editor) editor.setContent(val || "");
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
emitContent(content) {
|
||||
this.$emit("update:modelValue", content);
|
||||
this.$emit("input", content);
|
||||
},
|
||||
// 数据返回并给富文本框插入图片
|
||||
insertImage(arr){
|
||||
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img src="${v}" >`))
|
||||
},
|
||||
init() {
|
||||
// 初始化编辑器
|
||||
this.initTinymce();
|
||||
},
|
||||
initTinymce() {
|
||||
const _this = this;
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
convert_urls: false,
|
||||
init_instance_callback: (editor) => {
|
||||
if (_this.editorContent) {
|
||||
// 如果有初始值,则设置编辑器的内容为初始值
|
||||
_this.$nextTick(() => editor.setContent(_this.editorContent));
|
||||
}
|
||||
_this.hasInit = true;
|
||||
// 监听编辑器内容的变化
|
||||
editor.on("NodeChange Change KeyUp SetContent", () => {
|
||||
_this.hasChange = true;
|
||||
// Vue3 v-model 使用 update:modelValue,同时保留 input 兼容旧用法
|
||||
_this.emitContent(editor.getContent());
|
||||
});
|
||||
},
|
||||
setup(editor) {
|
||||
// 监听全屏状态变化
|
||||
editor.on("FullscreenStateChanged", (e) => {
|
||||
_this.fullscreen = e.state;
|
||||
});
|
||||
},
|
||||
..._this.initEditor,
|
||||
|
||||
height:this.height
|
||||
defineOptions({ name: "Tinymce" });
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: "500px",
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(["update:modelValue", "input"]);
|
||||
|
||||
// 引入编辑器的配置(data 中的 initEditor 与 import 同名,直接使用 import)
|
||||
const hasChange = ref(false); // 标记内容是否有更改
|
||||
const hasInit = ref(false); // 标记编辑器是否已初始化
|
||||
const tinymceId =
|
||||
"tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + ""); // 生成唯一的编辑器 ID
|
||||
const fullscreen = ref(false); // 标记编辑器是否处于全屏模式
|
||||
const toolbar = ref([]); // 工具栏配置
|
||||
const content = ref(""); // 编辑器内容
|
||||
|
||||
const editorContent = computed(() => {
|
||||
return props.modelValue ?? props.value ?? "";
|
||||
});
|
||||
|
||||
watch(editorContent, (val) => {
|
||||
if (!hasChange.value && hasInit.value) {
|
||||
// 当内容有更改且编辑器已初始化时,更新编辑器的内容
|
||||
nextTick(() => {
|
||||
const editor = window.tinymce?.get(tinymceId);
|
||||
if (editor) editor.setContent(val || "");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function emitContent(content) {
|
||||
emit("update:modelValue", content);
|
||||
emit("input", content);
|
||||
}
|
||||
// 数据返回并给富文本框插入图片
|
||||
function insertImage(arr) {
|
||||
arr.forEach((v) =>
|
||||
window.tinymce.get(tinymceId).insertContent(`<img src="${v}" >`)
|
||||
);
|
||||
}
|
||||
function init() {
|
||||
// 初始化编辑器
|
||||
initTinymce();
|
||||
}
|
||||
function initTinymce() {
|
||||
window.tinymce.init({
|
||||
selector: `#${tinymceId}`,
|
||||
convert_urls: false,
|
||||
init_instance_callback: (editor) => {
|
||||
if (editorContent.value) {
|
||||
// 如果有初始值,则设置编辑器的内容为初始值
|
||||
nextTick(() => editor.setContent(editorContent.value));
|
||||
}
|
||||
hasInit.value = true;
|
||||
// 监听编辑器内容的变化
|
||||
editor.on("NodeChange Change KeyUp SetContent", () => {
|
||||
hasChange.value = true;
|
||||
// Vue3 v-model 使用 update:modelValue,同时保留 input 兼容旧用法
|
||||
emitContent(editor.getContent());
|
||||
});
|
||||
},
|
||||
setContent(value) {
|
||||
// 设置编辑器的内容
|
||||
window.tinymce.get(this.tinymceId).setContent(value);
|
||||
setup(editor) {
|
||||
// 监听全屏状态变化
|
||||
editor.on("FullscreenStateChanged", (e) => {
|
||||
fullscreen.value = e.state;
|
||||
});
|
||||
},
|
||||
getContent() {
|
||||
// 获取编辑器的内容
|
||||
return window.tinymce.get(this.tinymceId).getContent();
|
||||
},
|
||||
destroyTinymce() {
|
||||
const tinymce = window.tinymce.get(this.tinymceId);
|
||||
...initEditor,
|
||||
|
||||
if (tinymce) {
|
||||
// 销毁编辑器实例
|
||||
tinymce.destroy();
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
activated() {
|
||||
if (window.tinymce) {
|
||||
this.initTinymce();
|
||||
}
|
||||
},
|
||||
deactivated() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
unmounted() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
};
|
||||
height: props.height,
|
||||
});
|
||||
}
|
||||
function getEditor() {
|
||||
// 获取 tinymce 实例(原组件无此方法,为对齐 seller 版暴露能力而新增)
|
||||
return window.tinymce?.get(tinymceId);
|
||||
}
|
||||
function setContent(value) {
|
||||
// 设置编辑器的内容
|
||||
window.tinymce.get(tinymceId).setContent(value);
|
||||
}
|
||||
function getContent() {
|
||||
// 获取编辑器的内容
|
||||
return window.tinymce.get(tinymceId).getContent();
|
||||
}
|
||||
function destroyTinymce() {
|
||||
const tinymce = window.tinymce.get(tinymceId);
|
||||
|
||||
if (tinymce) {
|
||||
// 销毁编辑器实例
|
||||
tinymce.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// created 钩子:顶层直接执行(保留原 created + mounted 双重 init 的历史行为)
|
||||
init();
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
onActivated(() => {
|
||||
if (window.tinymce) {
|
||||
initTinymce();
|
||||
}
|
||||
});
|
||||
onDeactivated(() => {
|
||||
destroyTinymce();
|
||||
});
|
||||
onUnmounted(() => {
|
||||
destroyTinymce();
|
||||
});
|
||||
|
||||
// 父组件通过 ref 调用:articleList 使用 getContent;setContent/getEditor 对齐 seller 版暴露能力
|
||||
defineExpose({ getEditor, setContent, getContent });
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user