VUE项目实战54商品添加功能-商品图片上传模块

Posted 光仔December

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VUE项目实战54商品添加功能-商品图片上传模块相关的知识,希望对你有一定的参考价值。

接上篇《53、商品添加功能(三)-商品参数及属性模块
上一篇我们完成了商品参数和商品属性面板的开发,本篇我们来完成商品图片上传模块的开发。

一、要实现的效果

我们在商品图片页签,需要放置一个“点击上传”的按钮,点击后会让我们选择电脑里的图片,选择完图片后,图片会自动通过API接口上传到后台,然后在按钮下方展示:

如果需要查看该图片大图,点击该图片的名称即可:

如果需要删除该图片,我们点击右上角的叉叉即可:

以上就是商品图片页签的功能介绍。下面我们来逐步实现它。

二、实现上传组件

我们要是使用Element-UI中的upload组件来作为我们的上传组件,我们前往官网,使用Upload上传组件中的“图片列表缩略图”模式:

点击查看其代码,示例代码就是下面这段:

<el-upload
  class="upload-demo"
  action="https://jsonplaceholder.typicode.com/posts/"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :file-list="fileList"
  list-type="picture">
  <el-button size="small" type="primary">点击上传</el-button>
  <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
<script>
  export default 
    data() 
      return 
        fileList: [name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100', name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100']
      ;
    ,
    methods: 
      handleRemove(file, fileList) 
        console.log(file, fileList);
      ,
      handlePreview(file) 
        console.log(file);
      
    
  
</script>

我们复制上面的el-upload组件代码,在我们项目的商品图片所在的el-tab-pane中粘贴这段代码,然后进行修改:

<el-tab-pane label="商品图片" name="4">
    <!-- action为图片上传的API接口地址;
            on-preview为点击图片时触发预览前的函数;
            on-remove为点击右侧叉叉删除图片前触发的函数;
            file-list使用来指定选择的文件列表的,这里我们不需要,先删除了
            list-type为上传后展示的效果,这里picture就是缩略图效果-->
    <el-upload
        action="http://127.0.0.1:8888/api/private/v1/upload"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        list-type="picture">
        <el-button size="small" type="primary">点击上传</el-button>
    </el-upload>
</el-tab-pane>

有关组件里各项属性的说明,在注释中已经解释清楚。然后记得在element.js中注册“Upload”组件。上面的上传API一定要写完整路径,如果写相对路径,则请求的是我们前端服务器8080的地址,而不是后端接口的8888地址。API接口详情如下:

三、解决上传接口token认证问题

我们直接使用上面写好的组件进行上传,发现图片可以正常显示,但是我们打开F12开发者工具,查看NetWork中上传你请求的后台接口返回信息,发现报错了:

这里提示我们“无效token”,并且状态为400,这就说明我们的图片并没有正常上传到后台,上面是一个假象。
这里之所以报“无效token”,是因为我们目前所有的接口都是有访问权限的,必须先通过登录接口创建后台会话,拿到后台返回的token令牌,才能正常访问其他接口,否则就会报没有登录或者没有权限。我们之前在main.js中,使用axios的interceptors拦截器,在每次网络请求发起之前将token取出来放到request请求的head请求头里,才能正常访问接口:

//为axios添加拦截器
axios.interceptors.request.use(config =>
  console.log(config);
  config.headers.Authorization = window.sessionStorage.getItem('token');
  return config;//最后必须返回config
)
Vue.prototype.$http = axios //在原型链上给$http赋值为axios对象

上面是保证我们每次使用axios做网络请求的时候,都会给我们把token添加到请求对象上。而我们本次的图片上传请求,是通过el-upload上传图片的,这个组件并没有用到我们的axios来发送上传图片的请求,应该是组件自己封装了一套ajax来异步请求网络。

我们去看看官方文档,看看el-upload有没有让我们放置token值的地方:

我们看到el-upload的组件中提供了一个“headers”的属性,该属性就是用来设置上传的请求头部的,我们可以将token值放入到这个属性中:

<el-upload
    action="http://127.0.0.1:8888/api/private/v1/upload"
    :on-preview="handlePreview"
    :on-remove="handleRemove"
    list-type="picture" :headers="headersObj">
    <el-button size="small" type="primary">点击上传</el-button>
</el-upload>

上面我们定义了:headers="headersObj",这个headersObj对象我们在data数据区来定义:

data()
    return 
        //篇幅原因,上面的参数代码省略....
        //图片上传组件的headers请求头对象
        headersObj:
            Authorization : window.sessionStorage.getItem('token')
        
    

此时我们再次测试上传图片,可以看到上传成功了:

四、处理图片上传成功之后的逻辑

上面我们仅仅是吧图片成功上传到了后台,但是还没有将图片信息添加到商品信息的form表单中,我们观察一下添加商品的API:

可以看到,关于图片的环节,提交的是一个图片的临时路径,该路径封装在表单的pics属性上,所以我们首先在data区给原来的商品表单对象新增一个“pics”属性,用于封装上传的图片路径:

//添加商品的表单数据对象
addForm: 
    goods_name:'',
    goods_price: 0,
    goods_weight: 0,
    goods_number: 0,
    //商品所属的分类数组
    goods_cat: [],
    //图片的数组
    pics: []
,

“pics”属性中的每一个pic的路径,我们可以从图片上传接口反馈的信息“tmp_path”获取到:

我们需要监听上传成功的事件,然后将返回的“tmp_path”属性拿到,给封装到商品表单对象的pics属性上。

然后查看刚刚的官网手册,可以找到“on-success”方法是文件上传成功之后的钩子函数:

这个钩子函数有3个属性,其中response为接口返回的信息对象,file为文件对象,fileList为上传文件列表。我们这里只需要用到response。

我们为el-upload组件绑定on-success属性,并指定一个名为“handleSuccess”的函数,用于处理上传成功之后的逻辑:

<el-upload
    action="http://127.0.0.1:8888/api/private/v1/upload"
    :on-preview="handlePreview"
    :on-remove="handleRemove"
    list-type="picture" :headers="headersObj"
    :on-success="handleSuccess">
    <el-button size="small" type="primary">点击上传</el-button>
</el-upload>

在方法区定义“handleSuccess”函数:

//监听图片上传成功的事件
handleSuccess(response)
    //1.拼接得到一个图片信息对象
    const picInfo = pic:response.data.tmp_path;
    //2.将图片信息对象push到pics数组中
    this.addForm.pics.push(picInfo);
    console.log(this.addForm);

最后打印一下addForm对象,看看我们图片的路径是否成功添加上了。效果:

可以看到图片的地址已经封装到addForm对象中了,如果上传2张,pics数组里就会包含两个图片路径:

五、图片的移除操作

我们添加图片的时候,是将图片路径push封装到addForm的pics属性中,而移除图片就是反过来,将该图片的路径从pics属性中remove移除出去。

我们在方法区编写上面已经定义好的图片移除监听函数handleRemove(该函数就是点图片右上角叉叉的时候触发的),这里我们分3步来处理了删除图片的操作,如下:

//处理移除图片的操作
handleRemove(file)
    //1.获取将要删除的图片的临时路径
    const finePath = file.response.data.tmp_path;
    //2.从pics数组中,找到这个图片对应的索引值
    const i = this.addForm.pics.findIndex(x=>x.pic==finePath);
    //3.调用数组的splice方法,把图片信息对象,从pics数组中移除
    this.addForm.pics.splice(i,1);
    console.log(this.addForm)
,

效果:

可以看到图片移除成功。

六、图片的预览效果

我们要实现点击图片名字,可以弹出一个预览对话框进行预览,然后点击叉叉可以关闭预览的对话框:


这里我们在商品图片Tab页签中添加商品预览的el-dialog对话框,其中放置一个img标签:

<el-tab-pane label="商品图片" name="4">
    <!-- action为图片上传的API接口地址;
            on-preview为点击图片时触发预览前的函数;
            on-remove为点击右侧叉叉删除图片前触发的函数;
            file-list使用来指定选择的文件列表的,这里我们不需要,先删除了
            list-type为上传后展示的效果,这里picture就是缩略图效果-->
    <el-upload
        action="http://127.0.0.1:8888/api/private/v1/upload"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        list-type="picture" :headers="headersObj"
        :on-success="handleSuccess">
        <el-button size="small" type="primary">点击上传</el-button>
    </el-upload>
    <el-dialog
        title="图片预览" :visible.sync="previewVisible" width="50%" >
        <img :src="previewPath" alt="" style="width:100%"/>
    </el-dialog>
</el-tab-pane>

上面的previewVisible用来控制图片预览对话框是否显示,previewPath对象是图片预览的url地址。首先我们在data区定义previewVisible对象,默认是false不显示对话框:

data()
    return 
        //篇幅原因,上面的参数代码省略....
        //图片上传组件的headers请求头对象
        headersObj:
            Authorization : window.sessionStorage.getItem('token')
        
        //控制图片预览对话框是否显示的属性
        previewVisible: false,
        //图片预览的url路径
        previewPath: ""
    

然后我们在方法区编写上面已经定义好的图片预览监听函数handlePreview(该函数就是点图片名称的时候触发的),获取当前点击的图片文件的url路径,并赋值到previewPath对象上,然后通过previewVisible对象控制对话框的显示,逻辑如下:

//处理图片预览效果
handlePreview(file)
    //获取图片的显示路径
    this.previewPath = file.response.data.url;
    this.previewVisible = true;
,

效果:

至此我们的商品图片上传模块的所有功能就完成了。
下一篇我们来完成商品内容模块的开发。

参考:黑马程序员(www.itheima.com)Vue项目实战教学视频

转载请注明出处:https://blog.csdn.net/acmman/article/details/125243599

以上是关于VUE项目实战54商品添加功能-商品图片上传模块的主要内容,如果未能解决你的问题,请参考以下文章

VUE项目实战57订单管理功能介绍和基本结构搭建

VUE项目实战51商品添加功能

VUE项目实战52商品添加功能-基本信息

VUE项目实战41添加商品分类功能

VUE项目实战49商品列表功能模块初始化

VUE项目实战40添加商品分类功能