课程名称:web前端架构师
课程章节:第11周 第五章
主讲老师:张轩
课程内容:完成编辑器中的上传功能
将上传组件添加到编辑器中
昨天完成对上传组件文件校验进行了封装,下面将它添加到编辑器中
function befeforeUpload (file: File) {
  const condition = {
    format: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'],
    size: 10 * 1024 * 1024
  }
  const res = uploadCheck(file, condition)
  if (!res.passed) {
    message.error(res.err)
  }
  return res.passed
}
这里我们对图片格式和大小进行了校验
封装一个组件用来上传图片
<script setup lang="ts">
...
function onUploaded (file: FileItem) {
  emit('uploaded', file.res.data.url as string)
}
</script>
<template>
  <upload-file
    :show-list="false"
    :before-upload="befeforeUpload"
    @uploaded="onUploaded"
  >
    <template #default>
      <a-button>点击上传</a-button>
    </template>
    <template #loading>
      <a-button>点击上传</a-button>
    </template>
    <template #uploaded>
      <a-button>点击上传</a-button>
    </template>
  </upload-file>
</template>
将该组件添加到编辑器上
<script setup lang="ts">
const emit = defineEmits<{(e: 'item-click', item: ComponentData): void}>()
function onUploaded (src: string) {
  const componentData: ComponentData = {
    tag: 'a-image',
    ...ImageDetaultProps,
    width: '200px',
    src
  }
  emit('item-click', componentData)
}
</script>
<template>
  组件列表
  ...
  <style-upload @uploaded="onUploaded" />
</template>
这里暂时先将图片设置为200px,否则图片显示不出来
获取图片的原始宽高
上传图片到编辑器时,我们需要给它设置一个合适的高度
- 首先获取到图片的原始宽高,宽高都要/2, ,因为我们是在移动端显示
- 图片宽度大于编辑器宽度时,可以给它设置为编辑器的宽度,即给图片设置个最大宽度
- 图片宽度小于编辑器宽度时,我们可以设置它为图片的原始高度
获取图片宽高
Image 构造器,带有两个可选的参数,分别表示资源的宽度和高度,创建了一个尚未被插入 DOM 树中的 HTMLImageElement 实例
所以可以通过获取元素的 naturalWidth 和 naturalHeight 来获取到图片的原始宽高
unction getImageDimensions (src: string) {
  return new Promise<{width: number;height: number}>((resolve, reject) => {
    const img = new Image()
    img.src = src
    img.addEventListener('load', () => {
      const { naturalWidth: width, naturalHeight: height } = img
      resolve({
        width: width / 2,
        height: height / 2
      })
    })
  })
}
将它添加到编辑器上。
我们的高度可以不用设置,可以让它自动撑开,这样更好控制,我们给图片设置最大宽度时,也不需要任何处理
async function onUploaded (src: string) {
 const { width } = await getImageDimensions(src)
 const componentData: ComponentData = {
   tag: 'a-image',
   ...ImageDetaultProps,
   width: width/2 + 'px',
   src
 }
 emit('item-click', componentData)
}
这样上传图片就完成了
这里还需要注意的是由于 andtv 的image 组件无法设置最大宽度,所以还需要自己写一个图片组件,这个组件实现也非常简单