VUE3自定义组件-富文本框

目录

一、自定义组件

二、使用改自定义组件

三、展示效果


一、自定义组件

       Editor.vue

<!-- 自定义的富文本框的组件 -->
<template>
  <div style="border: 1px solid #ccc">
    <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" />
    <Editor
      style="height: 300px; overflow-y: hidden"
      v-model="valueHtml"
      @onCreated="handleCreated"
      @onChange="handleChange"
    />
  </div>
</template>

<script lang="ts" setup>
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { ref, shallowRef, onMounted, watch } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { uploadApi } from "@/api";
//定义modelValue属性
const props = defineProps({ modelValue: { type: String, default: "" } });
const emit = defineEmits(["update:modelValue"]);

// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref("");

watch(
  () => props.modelValue,
  () => {
    editorRef.value.setHtml(props.modelValue);
  }
);

const handleCreated = (editor: any) => {
  editorRef.value = editor; // 记录 editor 实例,重要!

  editor.setHtml(props.modelValue);

  editor.getConfig().MENU_CONF["uploadImage"] = {
    // 自定义上传
    async customUpload(file: File, insertFn: any) {
      // TS 语法
      // file 即选中的文件
      // 自己实现上传,并得到图片 url alt href
      // 最后插入图片
      let reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = (f) => {
        uploadApi.upload
          .call({ name: file.name, base64: f.target?.result })
          .then((url: any) => {
            insertFn(url, file.name, url);
          });
      };
    },
  };
  editor.getConfig().MENU_CONF["uploadVideo"] = {
    // 自定义上传
    async customUpload(file: File, insertFn: any) {
      // TS 语法
      // file 即选中的文件
      // 自己实现上传,并得到图片 url alt href
      // 最后插入图片
      let reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = (f) => {
        uploadApi.upload
          .call({ name: file.name, base64: f.target?.result })
          .then((url: any) => {
            // 从 res 中找到 url poster ,然后插入视频
            insertFn(url, "");
          });
      };
    },
  };
};

const handleChange = (editor: any) => {
  emit("update:modelValue", editor.getHtml());
};
</script>

二、使用改自定义组件

将自定义得组件到修改页面中 其中详情页是富文本得位置

<template>
  <el-form
    ref="formRef"
    :model="formData"
    label-width="120px"
    status-icon
  >
    <el-form-item label="商品名称" prop="name">
      <el-input v-model="formData.name" />
    </el-form-item>
    <el-form-item label="副标题" prop="subName">
      <el-input v-model="formData.subName" type="textarea" />
    </el-form-item>
    <el-form-item label="商品图片" prop="img">
      <el-space>
        <Tuku v-model="formData.img1" />
        <Tuku v-model="formData.img2" />
        <Tuku v-model="formData.img3" />
      </el-space>
    </el-form-item>
    <el-form-item label="商品价格" prop="price">
      <el-input-number
        v-model="formData.price"
        :precision="2"
        :step="0.1"
        :min="0"
      />
    </el-form-item>
    <el-form-item label="排序" prop="seq">
      <el-input-number v-model="formData.seq" />
    </el-form-item>
    <el-form-item label="商品分类" prop="categoryId">
      <el-input v-model="formData.categoryId" />
    </el-form-item>
    <el-form-item label="详情" >
      <Editor v-model="formData.brief"></Editor>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm(formRef)"> 保存 </el-button>
      <el-button @click="resetForm(formRef)">重置</el-button>
    </el-form-item>
  </el-form>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive } from "vue";
import { productApi } from "@/api/index";
import { ElMessage } from "element-plus";
import Tuku from "@/components/Tuku.vue";
import { useRoute } from "vue-router";
import Editor from "@/components/Editor.vue";
const route = useRoute();
const formRef = ref();
const formData = reactive({
  id: 0,
  name: "",
  subName: "",
  categoryId: "5",
  img1: "",
  img2: "",
  img3: "",
  seq: 0,
  price: 0,
  brief:""
});

onMounted(() => {
  formData.id = Number(route.query.id);
  callProductApi();
});
const callProductApi = () => {
  productApi.select.call({ id: formData.id }).then((res: any) => {
    formData.name = res[0].name;
    formData.subName = res[0].subName;
    formData.categoryId = res[0].categoryId;
    formData.seq = res[0].seq;
    formData.price = res[0].price;
    formData.brief = res[0].brief;
  
    
    let imgArray = res[0].img.split(",");
    formData.img1 = imgArray[0];
    if(imgArray.length > 1){
        formData.img2 = imgArray[1];
    } 
    if(imgArray.length > 2){
        formData.img3 = imgArray[2];
    } 
  });
};
const submit = () => {
  callSaveProductApi();
};
const callSaveProductApi = () => {
  let img = [];
  if (formData.img1 != "") {
    img.push(formData.img1);
  }
  if (formData.img2 != "") {
    img.push(formData.img2);
  }
  if (formData.img3 != "") {
    img.push(formData.img3);
  }
  let params = {
    id: formData.id,
    name: formData.name,
    subName: formData.subName,
    categoryId: formData.categoryId,
    img: img.join(","),
    price: formData.price,
    seq: formData.seq,
    lastUpdateBy: "admin",
    brief: formData.brief
  };

  productApi.update.call(params).then((_res: any) => {
    ElMessage.success("保存成功");
  });
};

const submitForm = async (formEl: any) => {
  if (!formEl) return;
  await formEl.validate((valid: any, _fields: any) => {
    if (valid) {
      submit();
    }
  });
};

const resetForm = (formEl: any) => {
  if (!formEl) return;
  formEl.resetFields();
};
</script>

三、展示效果

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天的接口写完了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值