v-if and v-show 的坑 -- 图片预览

本文深入探讨了在Vue.js项目中使用v-if与v-show指令进行DOM元素控制时的区别,特别是在图片预览功能实现上。通过实例讲解了v-if可能导致上传功能失效的原因,并给出了改用v-show的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

v-if and v-show 的坑 – 图片预览

小白记录自己在日常开发中遇到的问题

v-if

v-if是动态的向DOM树内 添加 或者 删除 DOM元素;删除后该元素将不存在DOM树内

v-show

v-show是通过设置DOM元素的 display 样式属性控制显隐;相当于给元素添加 display 属性,根据 v-show 的布尔值来控制 display 属性的值

项目开发时遇到的坑

在这里插入图片描述
当上传图片时需要有图片预览效果。
我的方法是在文件域绑定一个change事件进行监听。把当前元素传到方法中获取图片地址并在另一个元素上展示,并在展示时改变图片状态。

而大坑是获取到图片地址之后,文件就无法传到后台了。当时以为是获取图片地址后改变了文件本身。后来想用别的图片代替文件域的上传才发现,是因为 v-if 将元素节点 删除 了才导致无法上传图片!之后改成v-show后就可以上传了

下面贴上代码:


// 浏览器上预览本地图片或视频
getObjectURL(file) {  
var url = null ;   
 // 下面函数执行的效果是一样的,只是需要针对不同的浏览器执行不同的 js 函数而已
 if (window.createObjectURL!=undefined) { // basic  
     url = window.createObjectURL(file) ;  
 } else if (window.URL!=undefined) { // mozilla(firefox)  
     url = window.URL.createObjectURL(file) ;  
 } else if (window.webkitURL!=undefined) { // webkit or chrome  
     url = window.webkitURL.createObjectURL(file);
 }
 return url ;  
},
changeimage (event) {
    // 调用上面的方法
 var objurl = this.getObjectURL(event.target.files[0])
 console.log(objurl)
 $('#myimg').attr('src',objurl);
 this.imgStat = false;
},
<div class="my_IDCard_header" v-show="imgStat && imgStat2">
	<img src="../images/icon/add.png" v-show="imgStat" class="my_IDCard_header_img" alt="">
	<input type="file" name="picfile" @change="changeimage($event)" ref="img" class="my_IDCard_header_input">
</div>
<div v-show="!imgStat" style="background: none;" class="my_IDCard_header">
	<img src="" id="myimg" style="width: 100%;height: 100%;border-radius:5px;" alt="">
</div>
调整一下代码,让代码更合理:<template> <a-card :bordered="false"> <a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form"> <a-row :gutter="24"> <a-col :span="6"> <a-form-item label="反馈人" name="username"> <a-input v-model:value="searchFormState.username" placeholder="请输入反馈人" /> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="创建时间" name="createTime"> <a-range-picker v-model:value="searchFormState.createTime" value-format="YYYY-MM-DD HH:mm:ss" show-time /> </a-form-item> </a-col> <a-col :span="6"> <a-button type="primary" @click="tableRef.refresh()">查询</a-button> <a-button style="margin: 0 8px" @click="reset">重置</a-button> </a-col> </a-row> </a-form> <s-table ref="tableRef" :columns="columns" :data="loadData" :alert="options.alert.show" bordered :row-key="(record) => record.id" :tool-config="toolConfig" :row-selection="options.rowSelection" > <template #operator class="table-operator"> <a-space> <!-- <a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('problemAdd')"> <template #icon><plus-outlined /></template> 新增 </a-button> --> <!-- <a-button @click="importModelRef.onOpen()" v-if="hasPerm('problemImport')"> <template #icon><import-outlined /></template> <span>导入</span> </a-button> --> <a-button @click="exportData" v-if="hasPerm('problemExport')"> <template #icon><export-outlined /></template> <span>导出</span> </a-button> <xn-batch-button v-if="hasPerm('problemBatchDelete')" buttonName="批量删除" icon="DeleteOutlined" buttonDanger :selectedRowKeys="selectedRowKeys" @batchCallBack="deleteBatchProblem" /> </a-space> </template> <template #bodyCell="{ column, record }"> <template #imageList="{ text }"> <div style="display: flex; gap: 5px"> <template v-if="text"> <a-image v-for="(url, index) in text.split(',')" :key="index" :width="40" :src="url.trim()" v-if="url.trim()" /> </template> <span v-else>-</span> </div> </template> <template v-if="column.dataIndex === 'action'"> <a-space> <!-- <a @click="formRef.onOpen(record)" v-if="hasPerm('problemEdit')">编辑</a> <a-divider type="vertical" v-if="hasPerm(['problemEdit', 'problemDelete'], 'and')" /> --> <a-popconfirm title="确定要删除吗?" @confirm="deleteProblem(record)"> <a-button type="link" danger size="small" v-if="hasPerm('problemDelete')">删除</a-button> </a-popconfirm> </a-space> </template> </template> </s-table> </a-card> <ImportModel ref="importModelRef" /> <Form ref="formRef" @successful="tableRef.refresh()" /> </template> <script setup name="problem"> import { cloneDeep } from 'lodash-es' import Form from './form.vue' import ImportModel from './importModel.vue' import downloadUtil from '@/utils/downloadUtil' import problemApi from '@/api/biz/problemApi' const searchFormState = ref({}) const searchFormRef = ref() const tableRef = ref() const importModelRef = ref() const formRef = ref() const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false } const columns = [ { title: '反馈人Id', dataIndex: 'userId' }, { title: '反馈人', dataIndex: 'userName' }, { title: '图片列表', dataIndex: 'imageList', key: 'imageList', scopedSlots: { customRender: 'imageList' } }, { title: '问题描述', dataIndex: 'description' }, { title: '创建时间', dataIndex: 'createTime' } ] // 操作栏通过权限判断是否显示 if (hasPerm(['problemEdit', 'problemDelete'])) { columns.push({ title: '操作', dataIndex: 'action', align: 'center', width: 150 }) } const selectedRowKeys = ref([]) // 列表选择配置 const options = { // columns数字类型字段加入 needTotal: true 可以勾选自动算账 alert: { show: true, clear: () => { selectedRowKeys.value = ref([]) } }, rowSelection: { onChange: (selectedRowKey, selectedRows) => { selectedRowKeys.value = selectedRowKey } } } const loadData = (parameter) => { const searchFormParam = cloneDeep(searchFormState.value) // createTime范围查询条件重载 if (searchFormParam.createTime) { searchFormParam.startCreateTime = searchFormParam.createTime[0] searchFormParam.endCreateTime = searchFormParam.createTime[1] delete searchFormParam.createTime } return problemApi.problemPage(Object.assign(parameter, searchFormParam)).then((data) => { return data }) } // 重置 const reset = () => { searchFormRef.value.resetFields() tableRef.value.refresh(true) } // 删除 const deleteProblem = (record) => { let params = [ { id: record.id } ] problemApi.problemDelete(params).then(() => { tableRef.value.refresh(true) }) } // 导出 const exportData = () => { if (selectedRowKeys.value.length > 0) { const params = selectedRowKeys.value.map((m) => { return { id: m } }) problemApi.problemExport(params).then((res) => { downloadUtil.resultDownload(res) }) } else { problemApi.problemExport([]).then((res) => { downloadUtil.resultDownload(res) }) } } // 批量删除 const deleteBatchProblem = (params) => { problemApi.problemDelete(params).then(() => { tableRef.value.clearRefreshSelected() }) } </script>
最新发布
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值