vue 点击或者拖拽 上传单文件或多文件 并读取文件内容

在这里插入图片描述

<file-read :fileReadDialog.sync="fileReadDialog" fileType='json' :multiple="true"></file-read>
<template>
    <div>
        <el-dialog
            :modal="true"
            :modal-append-to-body="false"
            title="上传"
            width="30%"
            :visible.sync="dialogVisible"
            :before-close="handleClose"
        >
            <div>
                <div class="file-box"
                    :class="dropType ? 'dropbox-shadow' : ''"
                    type="file"
                    @dragenter.stop.prevent="fileBoxDragenter(true)"
                    @dragleave.stop.prevent="fileBoxDragleave"
                    @drop.stop.prevent="fileBoxDrop($event, true)"
                    @dragover.stop.prevent=""
                    @click="openFile">
                    <div><i class="el-icon-upload upload-icon"></i></div>
                    <div class="upload-text">
                        <span>将文件拖到此处,或</span>
                        <span>点击上传</span>
                    </div>
                </div>
                 <input ref="inputfile" class="file-content" type="file" :multiple="multiple" @change="inputFile">
            </div>
            <span slot="footer" class="dialog-footer">
                <el-button @click="handleClose">取消</el-button>
                <el-button type="primary" @click="confirmFileRead">确定</el-button>
            </span>
        </el-dialog>
    </div>
</template>
<script>
export default {
    props: {
        fileReadDialog: {  // 弹窗显示
            type: Boolean,
            default: false
        },
        fileType: {  // 上传文件格式
            type: String,
            default: 'txt'
        },
        multiple: {  // 单张false or 多张true
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            dropType: false, // 拖拽
            boxLock: false, // 拖拽
            innerHTMLList: [],  // 对文件进行读取
        }
    },
    computed: {
        dialogVisible() {
            return this.fileReadDialog
        }
    },
    mounted() {
    },
    methods: {
        /**
         * 取消
         */
        handleClose() {
            this.$emit('update:fileReadDialog', false)
            this.dropType = false
            this.boxLock = false
            this.innerHTMLList = []

        },

        /**
         * 确定
         */
        confirmFileRead() {
        },

        inputFile(e) {
            this.readFile(e.target.files)
        },

        openFile() {
            this.$refs.inputfile.click()
        },

        /**
         * 文件拖拽dragenter进入
         */
        fileBoxDragenter(flag) {
            console.log('handlePictureBoxDragenter==')
            // 这里传入一个10ms的延迟锁,让drapleave在enter延迟后触发
            this.boxLock = true
            setTimeout(() => {
                this.boxLock = false
            }, 10)
            // dropType屎文件拖拽进选中范围的高亮效果
            this.dropType = flag
        },

        /**
         * 文件拖拽dragleave离开
         */
        fileBoxDragleave() {
            console.log('handlePictureBoxDragleave===')
            if (this.boxLock) return
            this.dropType = false
        },

        /**
         * 文件拖拽drop落下
         */
        fileBoxDrop(e) {
            this.dropType = false
            // 判断file是文件夹还是文件
            const isDirectory = e.dataTransfer.items[0].webkitGetAsEntry().isDirectory
            let fileList = e.dataTransfer.files
            console.log(fileList)

            if (isDirectory) {
                this.$message({
                    message: `上传${this.fileType}文件`,
                    type: 'warning'
                })
                return
            }

            this.readFile(fileList)
        },

        /**
         * 文件-约束、读取
         */
        readFile(fileList) {
            console.log('readFile===', fileList)
            console.log(fileList.length)
            if(!this.multiple && fileList.length !== 1) {
                this.$message({
                    message: `不支持上传多文件`,
                    type: 'warning'
                })
                return
            }
            
            if ((!this.multiple && Object.keys(fileList).length !== 1 ) || (!this.multiple && Object.keys(this.fileLists).length !== 0)) {
                this.$message({
                    message: '最多支持一个文件',
                    type: 'warning'
                })
                return
            }

            let filterFileType = Object.keys(fileList).filter(item => {
                if (fileList[item].name.split('.')[1] !== this.fileType) {
                    return true
                }
                return false
            })
            if(filterFileType.length !== 0) {
                this.$message({
                    message: `只支持${this.fileType}格式`,
                    type: 'warning'
                })
                return
            }


            Object.keys(fileList).forEach(item => {
                console.log(fileList[item])
                const reader = new FileReader()
                reader.readAsText(fileList[item], 'utf8')
                reader.onload = () => {
                    console.log(reader)
                    console.log(reader.readyState)
                    this.innerHTMLList.push(reader.result)
                    console.log(this.innerHTMLList)
                }
                reader.onerror = () => {
                    console.log('onError')
                }
            })
        }
    }
}
</script>
<style lang="less" scoped>
/deep/ .el-upload {
    width: 100%;
}
/deep/ .el-upload-dragger {
    width: 100%;
}
.file-box {
    width: 100%;
    height: 180px;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    background-color: #fff;
    text-align: center;
    box-sizing: border-box;
    padding-top: 50px;
}
.file-box:hover {
    border-color: #409eff;
}
.file-content {
    display: none;
}
.upload-icon {
    color: #c0c4cc;
    font-size: 67px;
}
.upload-text {
    color: #606266;
    font-size: 14px;
    & > span:nth-child(2) {
        margin-left: 4px;
        color: #409eff;
    }
}
.dropbox-shadow {
    box-shadow: 0px 0px 12px #409eff;
}
</style>

<think>好的,用户想在Vue.js读取本地的ASM文件内容展示到网页上。首先,我需要回忆一下Vue中处理文件上传和读取的方法。Vue本身不直接处理文件操作,但可以结合HTML5的File API来实现。 用户的需求是读取本地的.asm文件,所以需要一个文件输入控件,让用户选择文件。然后通过FileReader读取文件内容。接下来,将读取到的内容绑定到Vue的数据属性上,这样就能在模板中渲染出来了。 可能需要注意的地方是,文件读取是异步的,所以要用FileReader的onload事件来处理读取完成后的操作。另外,由于Vue的响应式系统,数据更新后会自动刷新视图,所以只要将文件内容赋值给data里的属性即可。 另外,用户可能还需要处理大文件的情况,或者文件读取时的错误处理,但根据问题描述,暂时先实现基本功能。需要提醒用户注意浏览器的兼容性,比如File API在不同浏览器中的支持情况。 可能还需要考虑如何展示ASM文件内容,比如使用<pre>标签保留格式,或者用代码高亮库来提升可读性,比如highlight.js或者prism.js。这部分可以作为优化建议提到。 最后,根据用户提供的引用,特别是引用[2]和[3],可能需要考虑在打包后的Vue项目中路径是否正确,避免出现空白页的问题,确保静态资源被正确加载。不过这个问题主要在打包配置,如果用户只是本地测试可能暂时不需要处理,但可以提醒用户注意。 总结步骤:创建文件输入组件,使用FileReader读取文件内容,将内容绑定到Vue实例,渲染到页面,可能添加代码高亮。</think>在Vue.js中实现本地ASM文件读取与展示,可以通过以下步骤实现: ### 实现步骤 1. **创建文件上传组件** ```vue <template> <div> <input type="file" @change="handleFileUpload" accept=".asm"> <pre>{{ fileContent }}</pre> </div> </template> ``` 2. **实现文件读取逻辑** ```javascript export default { data() { return { fileContent: '' } }, methods: { handleFileUpload(event) { const file = event.target.files[0] if (file && file.name.endsWith('.asm')) { const reader = new FileReader() reader.onload = (e) => { this.fileContent = e.target.result } reader.readAsText(file) } else { alert('请选择有效的ASM文件') } } } } ``` 3. **添加代码高亮(可选增强)** ```bash npm install highlight.js ``` ```vue <script> import hljs from 'highlight.js' import 'highlight.js/styles/github.css' export default { //... updated() { this.$nextTick(() => { document.querySelectorAll('pre code').forEach((block) => { hljs.highlightBlock(block) }) }) } } </script> ``` ### 关键实现说明 - 使用HTML5的`<input type="file">`实现文件选择[^3] - 通过`FileReader`API异步读取文件内容[^1] - 响应式数据绑定实现自动更新视图[^2] - 可选代码高亮提升可读性
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值