在html中如何创建vue自定义组件(以自定义文件上传组件为例,vue2+elementUI)

1、先上代码:vueUpload.js

javascript 复制代码
var dom = `<div class="upload-file">
        <el-upload :action="uploadFileUrl" :before-upload="handleBeforeUpload" :file-list="fileList" :limit="limit"
            :on-error="handleUploadError" :on-exceed="handleExceed" :on-success="handleUploadSuccess"
            :show-file-list="false" :headers="headers" class="upload-file-uploader" ref="upload">
            <!-- 上传按钮 -->
            <el-button size="mini" type="primary">选取文件</el-button>
            <!-- 上传提示 -->
            <div class="el-upload__tip" slot="tip" v-if="showTip">
                请上传
                <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
                <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
                的文件
            </div>
        </el-upload>

        <!-- 文件列表 -->
        <div>
            <div :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in list"
                v-if="file.url != null" style="display:flex;justify-content:space-between;align-item:center;max-width:300px;over-flow:hidden;text-overflow:ellipsis;white-space:nowrap;border: 1px solid #ddd;padding: 0 10px;cursor: pointer;">
                <el-link :href="file.url" :underline="false" target="_blank">
                    <span class="el-icon-document"> {{ file.name }} </span>
                </el-link>
                <div class="ele-upload-list__item-content-action">
                    <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
                </div>
            </div>
        </div>
    </div>`

    var demoComponent = Vue.extend({
        template:dom,
        props: {
            // 值
            value: [String, Object, Array],
            // 大小限制(MB)
            fileSize: {
                type: Number,
                default: 5,
            },
            // 文件类型, 例如['png', 'jpg', 'jpeg']
            fileType: {
                type: Array,
                default: () => ["doc", "xls", "ppt", "txt", "pdf"],
            },
            // 是否显示提示
            isShowTip: {
                type: Boolean,
                default: true
            },
            limit: {
                type: Number,
                default: 9
            }
        },
        data:function(){
          return {
            uploadFileUrl: '/file/rest/common/upload', // 上传的图片服务器地址
            headers: {
                Authorization: 'Bearer 123'
            },
            fileList: [],
          }
        },
        created() {
            this.fileList = this.list;
        },
        mounted() {
            console.log(this);
        },
        computed: {
            // 是否显示提示
            showTip() {
                return this.isShowTip && (this.fileType || this.fileSize);
            },
            // 列表
            list() {
                let temp = 1;
                if (this.value) {
                    const list = this.value;
                    return list.map((item) => {
                        item.name = item.fileName
                        item.url = item.fileUrl
                        item.uid = item.uid || new Date().getTime() + temp++;
                        return item;
                    });
                } else {
                    this.fileList = [];
                    return [];
                }
            },
        },
        methods:{
          // 上传前校检格式和大小
            handleBeforeUpload(file) {
                // 校检文件类型
                if (this.fileType) {
                    let fileExtension = "";
                    if (file.name.lastIndexOf(".") > -1) {
                        fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
                    }
                    const isTypeOk = this.fileType.some((type) => {
                        if (file.type.indexOf(type) > -1) return true;
                        if (fileExtension && fileExtension.indexOf(type) > -1) return true;
                        return false;
                    });
                    if (!isTypeOk) {
                        this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
                        return false;
                    }
                }
                // 校检文件大小
                if (this.fileSize) {
                    const isLt = file.size / 1024 / 1024 < this.fileSize;
                    if (!isLt) {
                        this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
                        return false;
                    }
                }
                return true;
            },
            // 文件个数超出
            handleExceed(e) {
                if(this.limit == 1) {
                    this.$message.error(`只能上传一个文件,请先删除原文件后重新上传!`);
                } else {
                    this.$message.error(`上传文件数量不能超过 ${props.limit} 个!`);
                }
            },
            // 上传失败
            handleUploadError(err) {
                this.$message.error("上传失败, 请重试");
            },
            // 上传成功回调
            handleUploadSuccess(res, file) {
                this.fileList.push({name:res.data.name, url:res.data.url, fileName:res.data.name, fileUrl:res.data.url})
                this.$message.success("上传成功");
                this.$emit("input", this.fileList);
            },
            // 删除文件
            handleDelete(index) {
                this.fileList.splice(index, 1);
                this.$emit("input", this.fileList);
            },
            // 获取文件名称
            getFileName(name) {
                if (name.lastIndexOf("/") > -1) {
                    return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
                } else {
                    return "";
                }
            }
        },
       })
       
       Vue.component('vue-upload',demoComponent)
       

2、在html中使用,在html中引入上面的vueUpload.js自定义组件文件

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试</title>
    <script src="https://unpkg.com/vue@2/dist/vue.js"></script>
    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <!-- 引入自定义上传组件 -->
    <script src="./vueUpload.js"></script>
</head>
<body>
    <div id="app">
      <vue-upload v-model="fileList" :limit="1" :file-type="['doc','docx','pdf']" :file-size="50"></vue-upload>        
    </div>
    <script>
      var app = new Vue({
        el: '#app',
        data () {
          return {
           fileList:[{fileName:'测试.pdf',fileUrl:'http://www.baidu.com/img/bd_logo1.png'}],
          }
        },
        mounted () {
         
        },
        methods: {
        }
      })
    </script>
</body>
</html>

3、展示效果

总结:在html中使用vue创建自定义组件和在vue中创建自定义组件基本一样,只不过写在js里最后记得把自定义组件通过Vue.component('vue-upload',demoComponent),挂载到vue上,还有在html中标签还有属性名都不可以用驼峰命名,切记!!!!!,驼峰命名的单词改用 '-' 的写法

相关推荐
MaCa .BaKa9 分钟前
38-日语学习小程序
java·vue.js·spring boot·学习·mysql·小程序·maven
小妖6663 小时前
vue2 切换主题色以及单页面好使方法
前端·vue.js·elementui
胡桃夹夹子3 小时前
【前端优化】vue2 webpack4项目升级webpack5,大大提升运行速度
前端·javascript·vue.js·webpack·性能优化
双叶8363 小时前
(C语言)超市管理系统 (正式版)(指针)(数据结构)(清屏操作)(文件读写)(网页版预告)(html)(js)(json)
c语言·javascript·数据结构·html·json
LuckyLay5 小时前
Vue百日学习计划Day9-15天详细计划-Gemini版
前端·vue.js·学习
码农黛兮_468 小时前
4. 文字效果/2D-3D转换 - 3D翻转卡片
3d·html·css3
大得3699 小时前
electron结合vue,直接访问静态文件如何跳转访问路径
javascript·vue.js·electron
小嘟嚷ovo11 小时前
h5,原生html,echarts关系网实现
前端·html·echarts
是千千千熠啊12 小时前
vue使用Fabric和pdfjs完成合同签章及批注
前端·vue.js
九月TTS12 小时前
TTS-Web-Vue系列:组件逻辑分离与模块化重构
前端·vue.js·重构