vue3专栏项目 -- 六、上传组件(上)

1、上传组件需求分析

我们还需要新建和展示文章,新建文章自然是发送post请求,同时在post中自带对应的数据,展示文章就是根据id取出已有的数据并且展示出来。

这里有一个难点就是上传组件,上传文件是App应用中最基本的需求,在Ajax出现之前,我们一般都使用一个简单的input框来实现这个上传的流程,把它的type设置成file,把from提交以后都交给后端处理。

自从有了ajax出现了以后,JS有了异步发送请求的能力,我们可以更方便的在页面不跳转的情况下完成文件的上传,同时还能获得很好的可视化效果,比如说传的百分比、图片的预览、最终的状态等等

整个流程,一开始我们应该有能力让用户去检查这个图片的格式或者大小的,我们会提供一个属性叫beforeUpload,它是一个function,让用户去检查这个文件的一些具体的需求;然后通过以后,这个时候这个组件就会向外反射一个uploading这样一个事件;然后上传成功以后就会触发filrUploaded这个事件,或者出现错误就会触发uploadedError这个事件。这些事件对于用户来说非常重要,他们很需要知道这些事情是什么样的时间发生的,然后可以做取得额外的工作,比如说beforeUploaded我们进行上传前的检查如文件类型/大小等等,或者在最终上传失败的时候我们可以弹出一些额外信息等等,这些都是事件给我们带来的魔力,除了这些事件以外,自定义也是我们的一大看点,我们的用户应该可以使用template来自定义一些显示的内容,比如说我们一开始上传区域长成什么样可以是一大片也可以是一个button等,上传中显示什么图标什么文字,上传完毕以后要显示什么样的数据,这些我们应该是可以完全自定义的

通过流程这么分析,我们大致得出组件大致应该有些什么,如下

它应该有一个action,代表着我们要把这个请求发送到后端哪里去处理;然后应该有一个function即beforeUploaded去完成一些上传前的校验;之后就是3个要触发的事件,uploading(点击上传按钮后)、fileUploaded(上传成功后)、uploadedError(上传失败后);除了这些我们还要支持自定义模板,默认就是一开始它长什么样,我们这里是一个button,然后我们可以添加这个template,这个template分为uploaded的即上传前的模板和loading的即上传中的模板

发送异步请求是上传组件的一个核心内容,那么接下来我们就谈谈使用axios来发送异步请求怎样完成文件的上传这个流程

2、上传文件的两种实现方式

接下来我们来了解上传文件的原理

我们先从form提交的时候谈起,既然要上传文件,当然就要选择文件,那么就可以选用如下

<input type="file">的标签,这时候它就会渲染出一个可以选择文件的对话框;那么当文件选择完毕以后,我们有两种方式上传,一个是使用传统的form submit即表单提交的方式;第二种是使用JavaScript发送异步请求的方式,这是我们着重要实现和理解的方法;

(1)如下我们了解一下第一种使用传统的form submit即表单提交的方式的流程

如下例子,我们选择文件然后点击submit的时候它就会运行form的默认行为,带input当中的数据,然后直接发送到一个特定的HTTP request请求到axios 的url,我们这里axios是/api/upload即会把input中的数据post到后端API为upload的地方中去,然后server端接到这个请求以后会做对应的处理,并且返回结果,这是一种典型的request到server的形式。这里要特别注意,我们这个表单一般于发送普通消息的表单,不同的地方就在于我们发送了文件,文件和普通的字符串不同,文件属于一种二进制的格式,所以我们需要设置这个enctype="multipart/form-data",注意你要上传文件或者你表单发送的有二进制的文件,那么就最好设置这种enctype="multipart/form-data"格式,因为表单的默认格式不支持二进制数据,所以需要设置成支持二进制数据的

我们选择了文件后,点击submit可以看到后端拿到这个内容以后就会做出对应的响应,它会返回如下图片地址

我们的接口文档中也提供了对应的接口

(2)使用JavaScript做file类型的表单上传功能

了解了这些之后,我们就可以使用JavaScript来发送异步上传文件的post请求了,提交form其实也就是发送http请求,那么使用JavaScript发送异步当然有更好的体验了,其实它的过程也是万变不离其宗的,也是用它来模拟表单的发送http请求

我们来新建文章页面来尝试一下,如下

然后我们尝试一下上传功能,如下我们点击上传某图片后,上传成功后它就打印出上传成功的信息

从上面可以看到,使用JavaScript发送异步请求的方式和form提交的过程是非常相似的,只不过是用javascript模拟原生form的提交方式

3、Uploader组件 第一部分 -- 上传组件流程

就和上面一样,完成那个流程即可

(1)首先创建一个按钮,使得点击这个按钮就执行file类型的input的点击事件即弹出选择文件的弹窗

如下,创建一个上传组件叫Uploader.vue

复习一下:还记得怎么在setup中拿到一个dom节点吗,通过ref咋拿来着,如下首先在标签里通过加上ref="fileInput",然后const fileInput = ref<null | HTMLInputElement>(null),然后直接通过fileInput.value即可拿到这个fileInputDOM节点了

form那个方式是有一个input框,然后右边有一个submit按钮,我们想有一个按钮,然后点击这个按钮就触发file类型的input框,即想只展现出一个按钮,这个按钮的点击事件中就触发这个file input即form上传功能。

怎么做,我们就如下设置一个button,也设置一个file类型的input,但是让这个input隐藏即可,然后button的点击事件中去获取这个input的DOM节点,拿到input节点后接着去触发input的点击事件,即form中的那个submit的点击事件(这个点击事件就会去让你挑选文件这样子)。这样就实现了页面中展示一个点击上传的按钮,然后你点击这个按钮,就会自动去触发类型为file的input的点击事件,从而就会展示出让你选择文件的弹窗

接下来我们来添加属性

我们要接收一个action,这个action是接收发送请求的地址,而且是必选项是必须填的

(2)接下来就是上面说的经典的上传过程

这里有个问题就是我们要根据不同的上传阶段,展示不同的元素,所以我们需要有一个字段来指示一下状态如下,然后我们就开始做状态变化后触发的函数即handleFileChange函数

在这个函数中,我们做的就是如下获取input这个DOM节点,这是为了我们在选择文件的时候去获取这个input的files属性,因为我们选择文件后这个input会带上files属性,这个属性中就是我们选择的那些文件们。我们获取到我们选择的文件后,首先去修改上传的状态,如下

这个e.target即事件对象就是这个input

我们选择文件后,这个input就会加上这个files属性,这个属性即currenTarget.files打印出来可以看到就是我们选择的那些文件,是一个列表list

然后继续,获取到我们选择的文件后,我们把这个files变成一个Array,因为这个files是一个list并不是一个Array,我们用Array.form()来转换成Array,是为了后面取它第一个。

然后创建一个form表单数据的属性,怎么创建就通过new FormData() 从而创建一个Form表单数据属性;然后把files的第一个数据给新建的这个FormData;FormData表单中有数据了,那么就可以进行post请求了,这个post请求中要传三个参数,一个是url,一个是传的数据,一个是headers(要写成如下这个才可以接收二进制文件);最终处理请求的结果,通过.then() 接请求成功的结果然后进行如下处理,通过.catch() 接请求失败的结果然后进行如下处理,最后那个finally是无论成功还是失败都进行的函数,因为我们选择了文件了嘛,所以input中的value被这个文件占了,你得先清空,下次再选择时才不会出错

(3)整个上传流程总结:

我们的template中有button和file类型的input(给隐藏input),然后我们是通过点击这个button去触发该input的click点击事件,这个点击事件就会弹出让你选择文件的弹窗。

然后此时input在变化即change,说明此时在上传文件,那么我们就给个change事件,这个事件是上传的重点

在这个change事件中,我们要做的流程就是:获取上传的文件-->建表单数据-->发起请求,把选择的文件传给对应API

首先,获取这个input这个dom节点(因为选择文件后input会增加一个files属性,这个属性中就是我们选择上传的文件列表),获取这个input就是为了获取我们选择上传的文件

然后,拿到要上传的文件后,新建一个表单数据属性,并且给这个属性files的值(因为post请求中要提交你选择的文件嘛)

①把这个files列表变成Array即数组(这是为了获取列表的第一个文件,我们只能选择一个文件)

②新建一个form表单数据属性,通过new FormData()

③把files中第一个文件数据给新建的这个FormData

最后,发起post请求,处理请求可能的请求成功、请求失败的处理

至此文件已经可以成功上传

过程中有一个小错误:

这里有一个要注意的点,就是发现在setup中说取不到props,要注意,setup(){}的括号中要写上props才能取到props的值,有时候不小心漏了,setup函数,它接收两个参数,一个是props,一个是context

4、Uploader组件 第二部分 -- 不同阶段自定义操作

上面我们完成了上传组件的最基本的流程,现在我们要将这里面的功能慢慢丰富进去

第一大功能就是在不同阶段暴露出一系列的事件,对于用户想在不同阶段进行自定义操作的话就很有用;第二个是自定义模板,用户可以根据需求渲染自己想要的页面

(1)在上传组件前,我们想自定义一个函数在上传之前去检查,比如上传前检查图片是不是JGP格式,是JPG格式才能上传

在上传前我们想要有一些检查的流程即beforeUpload函数,这个检查是怎么检查我们想要自定义式,怎么才能自定义呢,就你使用的地方定这个检查逻辑,在这个上传组件中只调用这个函数即可。

这个函数中应该接收用户选择的文件,然后经过一些列检查,最终返回布尔值,布尔值代表着检查的结果

如下在Uploader组件中

如下在Home.vue中,我们创建自定义检查的这个beforeUpload函数,并且传给uploader组件

即可如下,点击上传比如png的图片,就会出现如下提示

(2)上传成功后和上传失败后,我们想在这两个时候做一些自定义的事情,则如下

如下,定义emits,emits中有file-uploaded表示上传成功时调的函数、file-uploaded-error表示上传失败时调的函数,然后在上传的post请求成功时通过context.emit()去调用对应的函数

从接口文档中,我们可以看到返回的数据都是code、msg、data这样的,所以我们到store中定义一个通用的格式,这样就能享受到TypeScript类型的帮助,如下

然后我们在Home组件中定义这个上传成功的函数以及上传失败的函数,如下

5、Uploader 组件第三部分 -- 自定义模板

(1)使用slot来做自定义模板

我们在Dropdown组件中我们已经见识过自定义模板,它是使用这个slot来完成这个对应功能的,让我们来复习一下,我们使用name slot 来完成不同自定义模板的需求,我们在组件中添加slot,并且加上对应的name属性,然后在使用的时候我们可以使用template标签配合v-slot:name属性来使用,这里面就是你自定义的HTML内容,v-slot也可以简写成一个#

现在要展示3个阶段的界面,所以自然要展示三个slot来放置对应的自定义模板,所以如下我们来修改一下Uploader

如下,把正在上传、上传成功、点击上传都做成一个slot插槽,然后默认没什么的时候它们就是一个个按钮

然后如果这里面插入了东西,比如插入一段<h2>,那么就会替换这个插槽,但是这个h2标题还是有这个button这个按钮功能,如下

插槽名为default时即展示h2的点击上传文本

插槽名为loading时,则展示这个旋转图标

上传完毕后,我们需要在父组件Home.vue中拿到子组件Uploader.vue的一些数据,比如我们上传完毕后想展示出这个图片啥的,为了让组件在slot中访问子组件的某些特性,vue提供我们Scoped Slots就是为了让我们解决这个问题的

(2)使用scoped slot 来解决子组件传值给父组件的问题

看文档,如下,子组件slot标签中可以通过v-bind将一个属性绑定到这个slot上面去,然后我们就可以给父组件中对应标签中加上v-slot="xxx",然后通过xxx.这个属性即可拿到这个属性

如下,在Uploader组件中,我们新建一个ref属性记录请求成功时返回的数据,然后我们在slot中通过v-bind把这个数据传出去,如下

然后到Home组件中使用,如下用v-slot接传过来的值,把传过来的值取名叫dataProps,然后在img中使用如下

如下,上传成功后,图片就展示出来了,这样就实现了在slot中父组件使用子组件的数据的问题

6、改进路由验证系统

接下来我们将上传组件添加到新建文章页面中,但是现在路由跳转还有一些问题,我们先处理这个。

我们刚开始的路由验证流程是如下这样

但是我们发现了有一些问题,就是我们在下拉菜单组件点击新建文章按钮,可以正常跳转到新建文章页面,但是如果此时我们在新建文章页面刷新就会发现会跳转到登录页面,但是我们明明已经登录了呀

这是因为路由中我们还是使用了store.state.user.isLogin来判断的,而点击刷新后store中的数据是都重置回初始值的。所以你登录后isLogin确实从false置为true了,但是你刷新后isLogin就又是为false了,那么就符合这个if判断了,所以就重定向到了登录页面去给你了

但是其实你此时是已经登录状态,而你用store.state.user.isLogin判断就给你错判成了未登录状态,所以首页登录过以后再点击新建文章通过这个链接进行跳转的话就不会有这个问题,这是我们要解决的问题,这里涉及稍微复杂的流程

所以我们要改进一下路由验证系统,让它更完善一些

我们做个流程图,其实我们多的逻辑就是在发送请求这一步,其他的没有什么区别,只不过现在的逻辑比以前复杂了一些

如下,一开始我们判断这个user.isLogin,

如果已登录是true,则判断redirectAlreadyLogin这个参数存不存在,存在则跳转到首页,不存在则继续进行;

如果未登录是flase,那么我们就去判断是否有token,

如果token不存在,则去判断它访问的这个路由是不是需要登录才能访问的,如果不是则继续进行即让他去这个路由的页面,如果是需要登录才能访问的则跳转到登录页面让他先登录;

(前面的和我们之前的一样,我们新添加的逻辑就在这里)如果token存在,也就是说user的isLogin为false但是有token的情况,那么有可能是像上面这种刚刚刷新了isLogin为false但是其实是已登录的状态,也可能是有token但是是之前登录的现在确实还没有登录,有token就说明这个用户刚才或者之前登录过,所以就直接重新发送一次异步fetchCurrentUser请求去登录(这也是常见的,短时间内会自动登录的嘛);然后就如果登录失败就弹出提示回到登录页面让重新登录,如果登录成功则判断是不是要到登录或注册页面,如果是则重定向回首页,如果不是比如是要到新建文章页面那么直接next()即去新建文章页面反正此时都登录了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/12972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Socks5:网络世界的隐形斗篷

在数字化时代&#xff0c;网络隐私和安全已成为人们日益关注的话题。Socks5&#xff0c;作为一种代理协议&#xff0c;为用户在网络世界中的匿名性提供了强有力的支持。本文将从Socks5的多个方面&#xff0c;深入探讨这一技术如何成为网络世界的“隐形斗篷”。 一、Socks5的基本…

linux基础指令讲解(ls、pwd、cd、touch、mkdir)

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 总有光环在陨落&#xff0c;总有新星在闪烁 这个是我们今天要用到的初始…

P8805 [蓝桥杯 2022 国 B] 机房

P8805 [蓝桥杯 2022 国 B] 机房 分析 是一道lca题目&#xff0c;可以直接套模板 前缀和处理点权 具体思路&#xff1a; 1.n台电脑用n-1条网线相连&#xff0c;任意两个节点之间有且仅有一条路径&#xff08;拆分成各自到公共祖先节点的路径——lca&#xff09;&#xff1b;…

波搜索算法(WSA)-2024年SCI新算法-公式原理详解与性能测评 Matlab代码免费获取

​ 声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 原理简介 一、初始化阶段 二、全…

我与C++的爱恋:string类的常见接口函数

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 朋友们大家好啊&#xff0c;本节我们来到STL内容的第一部分&#xff1a;string类接口函数的介绍 ​ ​ 1.string类的认识 给大家分享一个c文档 https://legacy.cplusplus.…

Weblogic 管理控制台未授权远程命令执行漏洞(CVE-2020-14882,CVE-2020-14883)

1 漏洞概述 Weblogic Pre-Auth Remote Command Execution 漏洞&#xff08;CVE-2020-14882, CVE-2020-14883&#xff09;是针对 Oracle WebLogic Server 的两个安全漏洞。CVE-2020-14882 允许远程用户绕过管理员控制台组件中的身份验证&#xff0c;而 CVE-2020-14883 则允许经…

Sam Blackshear谈Move语言的起源

Move编程语言作为Sui生态系统的关键组成部分&#xff0c;通过可编程交易区块等机制支持其独特的对象数据模型&#xff0c;并支持高效的代码。五年前&#xff0c;Mysten Labs的联合创始人兼首席技术官Sam Blackshear创建了Move。他专门设计了Move&#xff0c;用于编写智能合约&a…

sqli-labs靶场第十四关

目录 1&#xff1a;分析 找闭合符&#xff1a; 2&#xff1a;开始注入 报错注入&#xff1a; 注入数据库名&#xff1a; 注入表名&#xff1a; 注入列名&#xff1a; 注入具体值&#xff1a; 1&#xff1a;分析 经过我们的实验发现当我们输入的密码后面存在双引号时会报…

【C++】学习笔记——多态_1

文章目录 十二、继承8. 继承和组合 十三、多态1. 多态的概念2. 多态的定义和实现虚函数重写的两个特殊情况override 和 final 3. 多态的原理1. 虚函数表 未完待续 十二、继承 8. 继承和组合 我们已经知道了什么是继承&#xff0c;那组合又是什么&#xff1f;下面这种情况就是…

英语学习笔记13——A new dress

A new dress 一件新连衣裙 词汇 Vocabulary colour / color n. 颜色 v. 上色&#xff0c;涂色  英  美 颜色短语&#xff1a;green hand 新手      black tea 红茶      white house 白宫      black sheep 害群之马 英文颜色类词汇&#xff1a; red 红色…

鸿蒙开发接口Ability框架:【ApplicationContext】

ApplicationContext ApplicationContext模块提供开发者应用级别的的上下文的能力&#xff0c;包括提供注册及取消注册应用内组件生命周期的监听接口。 说明&#xff1a; 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-shizhen-skin/harmony-os/blob/master/README.m…

静态IP代理:网络世界的隐秘通道

在数字化时代&#xff0c;网络安全和隐私保护日益受到重视。静态IP代理作为一种网络服务&#xff0c;为用户提供了一个稳定且可预测的网络连接方式&#xff0c;同时保护了用户的在线身份。本文将从五个方面深入探讨静态IP代理的概念、优势、应用场景、技术实现以及选择时的考量…

C语言学习【printf函数和scanf函数】

C语言学习【printf函数和scanf函数】 printf()函数和scanf()函数可以让用户与程序交流&#xff0c;是输入/输出函数 printf()函数 请求printf()函数打印数据的指令要与待打印数据的类型相匹配。例如&#xff0c;打印整数时使用%d&#xff0c;打印字符时使用%c。这些符号被称…

程序在银河麒麟系统下实现开机自启及创建桌面快捷方式

目录 1. 机器环境说明 2. 程序开机自启动设置 2.桌面快捷方式设置 3. 附加说明 1. 机器环境说明 机器安装的银河麒麟操作系统属性如下&#xff1a; 2. 程序开机自启动设置 第1步&#xff1a;编写一个脚本,用于自动化启动&#xff0c;为便于后文描述&#xff0c;该脚本名称…

干货教程【软件篇】| 免费实现游戏加速自由

需要这个游戏加速软件的小伙伴可以关注一下文章底部公众号&#xff0c;回复关键词【zdjs】即可获取。 该软件可以实现免费的游戏加速&#xff0c;实测延迟低体验好&#xff01; 建议看到后赶紧保存下来防止丢失&#xff01; 下面讲一下该软件安装流程~ 通过链接可以得到下面…

Linux进程控制——Linux进程程序替换

前言&#xff1a;Linux进程控制包含了进程终止&#xff0c;进程等待&#xff0c;进程程序替换。走到现在我们也只剩下进程程序替换没介绍了&#xff0c;那么让我们来看看进程程序替换到底是什么&#xff01; 本篇主要内容&#xff1a; 替换原理 替换函数 实现简易shell 我们所创…

Broad Learning System (BLS) 宽度学习系统

宽度学习&#xff08;Broad Learning System, BLS&#xff09;是一种有效的神经网络学习框架&#xff0c;旨在通过扩展网络的宽度而不是深度来提高学习能力和效率。与传统的深度学习相比&#xff0c;宽度学习通过堆叠多层特征节点和增强节点来构建网络&#xff0c;从而避免了深…

Maven依赖管理项目构建

Maven依赖管理项目构建工具 目录 文章目录 Maven依赖管理项目构建工具目录一、Maven简介1、为什么学习Maven1.1、Maven是一个依赖管理工具1.2、Maven是一个构建工具1.3、结论 2. Maven介绍3. Maven软件工作原理模型图&#xff08;了解&#xff09; 二、Maven安装和配置1. Mave…

PostgreSQL扩展之PGroonga:多语言全文搜索

简介 PGroonga 是一个 PostgreSQL 扩展&#xff0c;它增加了基于 Groonga 的全文搜索索引方法。虽然原生的 PostgreSQL 支持全文索引&#xff0c;但它仅限于基于字母和数字的语言。PGroonga 提供了更广泛的字符支持&#xff0c;使其成为 PostgreSQL 支持的语言的超集&#xff…

(实测验证)Gitee代码托管尝试(一)——克隆/下载

一、登录 Gitee&#xff08;码云&#xff09;代码托管平台&#xff1a; Gitee - 基于 Git 的代码托管和研发协作平台 新建个人账户如下&#xff1a; 二、SSH 公钥设置 1、在git安装目录打开“git-cmd.exe”; 2、通过命令 ssh-keygen 生成 SSH Key&#xff1a; ssh-keygen …