组件用.vue还是.js

by Cathy Ha

由凯茜·哈(Cathy Ha)

如何使用Vue.js 2.0构建灵活的图像上传器组件 (How to build a flexible image uploader component using Vue.js 2.0)

I’ve been coding with Vue.js 2.0 for about half a year now, and it’s pretty awesome. It’s incredibly intuitive and simple. The partitioning between HTML/CSS/Javascript makes both learning and coding a breeze.

我已经使用Vue.js 2.0编码了大约半年了,这非常棒。 这是非常直观和简单的。 HTML / CSS / Javascript之间的分区使学习和编码变得轻而易举。

But the trouble (and the fun) of coding with a relatively new framework is the lack of tutorials for what you want to build. Especially when you have a specific thing in mind.

但是,使用相对较新的框架进行编码的麻烦(也很有趣)是缺少想要构建的教程。 特别是当您有特定的想法时。

I ran into this issue when I was trying to build a profile photo uploader for Torneo. Sure, I could have used a fancy package, but where’s the fun in that?

当我尝试为Torneo构建个人资料照片上传程序时遇到了这个问题。 当然,我本可以使用精美的包装,但是这样做的乐趣在哪里?

So, by modifying and combining two great tutorials, I created my own reusable image uploader component.

因此,通过修改和组合两个 出色的教程,我创建了自己的可重用图像上传器组件

Check out the git repository for all the code.

检出git存储库中的所有代码。

期望的行为 (Desired Behaviour)

I created the component with the following goals in mind:

我在创建组件时考虑了以下目标:

  • The component should be capable of being activated by any element in its parent component to upload images该组件应该能够被其父组件中的任何元素激活以上传图像
  • We should be able to see a preview of the image in the parent component我们应该能够在父组件中看到图像的预览
  • The uploaded image should be saved in a FormData format to send to the back-end上传的图像应以FormData格式保存,以发送到后端
  • The component should check for a size limit in the uploaded image (this can be done in the back-end as well, but it’s a bit faster in the front-end)该组件应检查上传图像中的大小限制(这也可以在后端完成,但是在前端要快一些)
  • One file at a time (note that this tutorial talks about how to handle multiple files — all you need are some loops)

    一次一个文件(请注意, 本教程讨论了如何处理多个文件-您只需要一些循环即可)

步骤1:设定 (Step 1: Setup)

We’ll get started by installing the webpack-simple template. We’ll also be installing Vuetify to save some time on styling. Note that everything wrapped in <v-…> is from Vuetify. Since their tags are pretty self-explanatory, I won’t go too deep into it. I will leave you to read their documentation.

我们将从安装webpack-simple模板开始。 我们还将安装Vuetify,以节省样式时间。 请注意,<v-…>中包装的所有内容均来自Vuetify。 由于它们的标签是不言自明的,因此我不会对其进行深入研究。 我将让您阅读他们的文档。

# install the vue-clinpm install vue-cli -g# initiate the webpack-simple, and follow instructionsvue init webpack-simple image-upload
# install dependenciesnpm install
# install Vuetifynpm install vuetify --save

步骤2:建立图片上载范本 (Step 2: Create the Image Upload Template)

Great! Now that we have the templates set up and installed, we can delete any placeholder content. Then we can create a new component file for the image uploader.

大! 现在我们已经设置并安装了模板,我们可以删除任何占位符内容。 然后,我们可以为图像上传器创建一个新的组件文件。

<template>  <div>
<!-- slot for parent component to activate the file changer -->    <div @click="launchFilePicker()">      <slot name="activator"></slot>    </div>
<!-- image input: style is set to hidden and assigned a ref so that it can be triggered -->    <input type="file"       ref="file"       :name="uploadFieldName"       @change="onFileChange(          $event.target.name, $event.target.files)"       style="display:none">
<!-- error dialog displays any potential errors -->    <v-dialog v-model="errorDialog" max-width="300">      <v-card>        <v-card-text class="subheading">{{errorText}}</v-card-text>        <v-card-actions>          <v-spacer></v-spacer>          <v-btn @click="errorDialog = false" flat>Got it!</v-btn>        </v-card-actions>      </v-card>    </v-dialog>
</div></template>
  1. To make the image uploader component capable of being activated by any element in the parent component, we can take advantage of Vue’s “slot” functionality.

    为了使图像上载器组件能够被父组件中的任何元素激活,我们可以利用Vue的“插槽”功能。

  2. Since we want the “trigger” for the input to be in the parent component, we want the functionality of the file input in the child component, without being able to see it. We can change the style of the input to “display:none” to hide it.由于我们希望输入的“触发器”位于父组件中,因此我们希望子组件中文件输入的功能无法看到。 我们可以将输入的样式更改为“ display:none”以将其隐藏。
  3. The image input is assigned a “ref” so that when the slot is clicked on, we can activate the image input by its reference.为图像输入分配了一个“参考”,以便在单击插槽时可以通过其参考激活图像输入。
  4. To make the image uploader more user-friendly, we can use a dialog to display any potential errors.为了使图像上传器更加用户友好,我们可以使用对话框来显示任何潜在的错误。

Next, we can use some Vue.js magic in the JavaScript portion to massage some life into our component:

接下来,我们可以在JavaScript部分中使用一些Vue.js魔术来为我们的组件增加生命:

<script>
export default {
name: 'image-input',
data: ()=> ({      errorDialog: null,      errorText: '',      uploadFieldName: 'file',      maxSize: 1024    }),
props: {          // Use "value" here to enable compatibility with v-model      value: Object,    },
methods: {      launchFilePicker(){        this.$refs.file.click();      },
onFileChange(fieldName, file) {        const { maxSize } = this        let imageFile = file[0]          //check if user actually selected a file        if (file.length>0) {          let size = imageFile.size / maxSize / maxSize          if (!imageFile.type.match('image.*')) {            // check whether the upload is an image            this.errorDialog = true            this.errorText = 'Please choose an image file'          } else if (size>1) {            // check whether the size is greater than the size limit            this.errorDialog = true            this.errorText = 'Your file is too big! Please select an image under 1MB'          } else {            // Append file into FormData & turn file into image URL            let formData = new FormData()            let imageURL = URL.createObjectURL(imageFile)            formData.append(fieldName, imageFile)
// Emit FormData & image URL to the parent component            this.$emit('input', { formData, imageURL })          }        }      }    }  }</script>

5. To make the image uploader component v-model compatible, use “value” in the props. Whatever data that is emitted by the component will be captured in the “value” prop.

5.要使图像上传器组件的v模型兼容,请在道具中使用“值”。 组件发出的任何数据都将在“值”属性中捕获。

6. When the file input activator in the parent component is clicked, “this.$refs.file.click()” is used to activate the file selector.

6.单击父组件中的文件输入激活器时,“ this。$ refs.file.click()”用于激活文件选择器。

7. Once the user picks something from the file selector / closes the file selector, we need to check:

7.一旦用户从文件选择器中选择了某些内容/关闭了文件选择器,我们需要检查:

  • Whether the user has actually selected a file用户是否实际选择了文件
  • Whether the file is an image该文件是否为图像
  • Whether the file is greater than the size limit (often a good idea when it comes to user uploads)文件是否大于大小限制(关于用户上传,通常是个好主意)

8. If the file that the user selected is fine, create a FormData element and append the file into the element using a name that your server would accept. Also, convert the image file into an object URL so that the parent component can read it for a preview.

8.如果用户选择的文件很好,请创建一个FormData元素,然后使用服务器可以接受的名称将该文件附加到该元素中。 另外,将图像文件转换为对象URL,以便父组件可以读取该文件以进行预览。

9. Emit the data (FormData for uploading to the server, and imageURL for the preview) to the parent component.

9.将数据(用于上传到服务器的FormData和用于预览的imageURL)发送到父组件。

步骤3:创建父组件 (Step 3: Create the Parent Component)

In the parent component, we can visualize the child component’s functionality.

在父组件中,我们可以可视化子组件的功能。

<template>  <v-app id="app" class="mt-0">    <v-container grid-list-xl>      <image-input v-model="avatar">        <div slot="activator">          <v-avatar size="150px" v-ripple v-if="!avatar" class="grey lighten-3 mb-3">            <span>Click to add avatar</span>          </v-avatar>          <v-avatar size="150px" v-ripple v-else class="mb-3">            <img :src="avatar.imageURL" alt="avatar">          </v-avatar>        </div>      </image-input>      <v-slide-x-transition>        <div v-if="avatar && saved == false">          <v-btn class="primary" @click="uploadImage" :loading="saving">Save Avatar</v-btn>        </div>      </v-slide-x-transition>    </v-container>  </v-app></template>
  1. Wrap the activator element in a <div/> and let the child component know that it belongs in the slot that we named “activator”.将激活器元素包装在<div />中,并让子组件知道它属于我们称为“激活器”的插槽中。
  2. Use Vue’s v-if and v-else to display a prompt to upload or the avatar preview depending on whether the user has selected a file.

    根据用户是否选择了文件,使用Vue的v-if和v-else显示提示上传或头像预览。

  3. Conditionally display a button to save the user’s changes.有条件地显示一个按钮来保存用户的更改。

Almost done! Next, time to add in some Javascript to the parent component:

快完成了! 接下来,是时候向父组件添加一些Javascript了:

<script>import ImageInput from './components/ImageInput.vue'
export default {  name: 'app',  data () {    return {      avatar: null,      saving: false,      saved: false    }  },  components: {    ImageInput: ImageInput  },  watch:{    avatar: {      handler: function() {        this.saved = false      },      deep: true    }  },  methods: {    uploadImage() {      this.saving = true      setTimeout(() => this.savedAvatar(), 1000)    },    savedAvatar() {      this.saving = false      this.saved = true    }  }}</script>

4. In the script portion, import the child component.

4.在脚本部分中,导入子组件。

5. When the user clicks “save”, upload the avatar to the server (note that I am faking an upload in the code above. In reality, we use axios to upload the file to the server. The back-end then saves the file in a filesystem and passes the path to the file in the data).

5.当用户单击“保存”时,将头像上传到服务器(请注意,我在上面的代码中伪造了一个上传。实际上,我们使用axios将文件上传到服务器。后端然后保存文件系统中的文件,并将路径传递到数据中的文件)。

That’s it! There’s much room to enhance this component — like passing props to resize the image being uploaded, handling multiple files, etc. If you see any potential points for improvement or spot a mistake in my code, please please leave a comment!

而已! 增强此组件的空间很大,例如传递道具以调整要上传的图像的大小,处理多个文件等。如果您发现任何潜在的改进点或在我的代码中发现错误,请发表评论!

Again, feel free to check out the git repository for all the code.

再次,随时检查git存储库中的所有代码。

Finally, a shameless plug here: if you happen to be interested in sports, check out Torneo — a sports-related startup that I’ve helped to develop.

最后,这里是一个无耻的插件:如果您对体育感兴趣,请访问Torneo ,这是我帮助开发的与体育相关的初创公司。

翻译自: https://www.freecodecamp.org/news/how-to-build-a-flexible-image-uploader-component-using-vue-js-2-0-5ee7fc77516/

组件用.vue还是.js

组件用.vue还是.js_如何使用Vue.js 2.0构建灵活的图像上传器组件相关推荐

  1. 微信小程序之网易云音乐(五)- 排行详情页、歌单详情页、播放器组件开发

    微信小程序之网易云音乐(五)- 排行详情页.歌单详情页.播放器组件开发 一. 排行详情页模块 二. 歌单详情页模块 三. 播放器组件 微信小程序之网易云音乐导航 一. 排行详情页模块 rank.vue ...

  2. jsx怎么往js里传参数_实践Vue 3.0做JSX(TSX)风格的组件开发

    作者:莫夭 转发链接:https://zhuanlan.zhihu.com/p/102668383 前言 我日常工作都是使用React来做开发,但是我对React一直不是很满意,特别是在推出React ...

  3. Vue 单文件组件||Vue 单文件组件的基本用法||webpack 中配置 vue 组件的加载器|| 在 webpack 项目中使用 vue

    Vue 单文件组件 传统组件的问题和解决方案 1. 问题 1. 全局定义的组件必须保证组件的名称不重复 2. 字符串模板缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \ 3. 不支持 CS ...

  4. rideo选中 vue_适用于 Vue 的播放器组件Vue-Video-Player操作

    如果h5的标签不能满足你的需求,那就用这个组件Vue-Video-Player吧,也许可以覆盖到你的需求. class="video-player vjs-custom-skin" ...

  5. vue vuex 挂载_vue.js,javascript_Vuex的初始化失败,一直显示没有挂载到根组件上,奇怪了!,vue.js,javascript - phpStudy...

    Vuex的初始化失败,一直显示没有挂载到根组件上,奇怪了! 代码如下 import 'babel-polyfill' import Vue from 'vue' import VueRouter fr ...

  6. vue导入html登陆页,Vue 实现 登陆后打开主页面(登陆组件 + 主页面组件)

    本次演示,项目所需 iview,router 首先 在 views 目录 新建 两个 组件 ( login.vue ,index.vue ) login.vue 登录 登 录 export defau ...

  7. [vue] 你有自己用vue写过UI组件库吗?

    [vue] 你有自己用vue写过UI组件库吗? {{item.title}}<dl v-if="item.list.length > 0"><dd v-fo ...

  8. [vue] 说下你的vue项目的目录结构,如果是大型项目你该怎么划分结构和划分组件呢?

    [vue] 说下你的vue项目的目录结构,如果是大型项目你该怎么划分结构和划分组件呢? views目录存放一级路由的组件,即视图组件 Components目录存放组件 Store存放vuex相关文件 ...

  9. 前端学习(2011)vue之电商管理系统电商系统之初步使用upload上传组件

    目录结构 router.js import Vue from 'vue' import Router from 'vue-router' import Login from './components ...

最新文章

  1. 2013蓝桥杯-B-省赛-七、错误票据
  2. 少儿编程150讲轻松学Scratch(七)-Scratch学习中需要注意的地方
  3. php根据分类生成网址,PHP实现无限极分类生成分类树的方法
  4. 计算机雕刻教学设计,教学设计季花的雕刻方法.doc
  5. STL学习笔记-multimap的基本使用
  6. python函数分为哪几类_Python 69个内置函数分8类总结
  7. PHP距离春节还剩多少天,2019年春节倒计时 现在距离2019年春节还有多少天 - 中国万年历...
  8. 实验四 lr0分析程序的设计与实现_试验机海外直播丨实现高精度CAE分析实验的材料评价案例技术介绍...
  9. 【东软实训】SQL函数
  10. ubuntu搭建nginx服务器,并测试axel与wget的下载速度
  11. python数字类型及运算_Python基础教程:运算符以及数据类型解析
  12. iphone4 Safari实现滚动条功能
  13. 225.队列实现栈 (力扣leetcode) 博主可答疑该问题
  14. 路由器开发相关知识总结 —— 光口和电口
  15. 物理计算机技术研究生就业前景,物理学就业前景
  16. Restful 接口传递参数
  17. centos7安装Memcached
  18. python刷网易云_Python脚本用于定时关闭网易云音乐PC客户端
  19. 异贝服装店都可以做会员营销?神奇的逆向思维让他快速裂变赚钱!
  20. 微信朋友圈十周年,你设置了三天可见吗?

热门文章

  1. 设置让终端保持utf8 cmd的设置
  2. linux-使用xshell连接linux教程
  3. Android的图片叠加
  4. 解决Zend OPcache huge_code_pages: mmap(HUGETLB) fail
  5. 2015 年出现的十大流行 Python 库
  6. Tips:无法在Windows2012 R2+exchange2010中文版上安装SP3 RU8v2
  7. 谈一下关于CQRS架构如何实现高性能
  8. 函数调用过程实例详解
  9. 【分享】纯js的n级联动列表框 —— 基于jQuery,支持下拉列表框和列表框,最重要的是n级,当然还有更重要的...
  10. 企业网络高级技术-VTP中继协议(2)