使用vue render el-date-picker出现 date.getHours is not a function

Element UI 中的日期选择器问题及解决方案
在使用Element UI的项目中,遇到el-date-picker组件无法选择日期的问题,点击后报date.getHours is not a function错误。原因是通过render函数渲染的el-date-picker元素中,this.value初始为'undefined'字符串,导致错误。解决方法是在内部修改value值,但此做法违反Vue最佳实践。寻求完美解决方案,避免后续可能出现的json存储回显问题。

背景是这样的,客户要自己设计表单,所以表单页面全都是用render函数渲染出来的。
项目使用的是element ui。别的都没问题,就这个el-date-picker出问题了。
渲染出来的元素是这样的
在这里插入图片描述
看起来也没啥问题,也能点开,但是就是不能选择日期,点击就报date.getHours is not a function。
报错发生在element-ui.common,js的18439行。打断点仔细对比了正常的和渲染出来的元素发生点击事件时走的代码,发现下面这行代码
在这里插入图片描述
这个this.value在正常的el-date-picker元素中首次点击其实是空,但是在渲染出来的元素里他是’undefined’,是字符串类型的,被识别为true,走了三元表达式前面的代码,所以出错了。
那么在前面加下下面的代码,这个问题就解决了。
在这里插入图片描述
这么做的缺点是在子组件内修改了value的值,vue不推荐这样做,控制台会报错,虽然不影响使用。如果有大佬知道为啥value是undefined字符串麻烦告知一下完美解决方法。

因为字段全部使用json存储,后面可能还会有回显失败的问题。json转换的时候加上后面这个时间格式就没有问题了。
在这里插入图片描述

<template> <div> <div> <el-form ref="form" :model="form" label-width="80px"> <el-form-item label=""> 课程类型 <el-select v-model="selectedType" placeholder="请选择" clearable="" @change="returnTypeId" > <el-option v-for="type in typeList" :label="type.typeName" :value="type.id" :key="type.id" ></el-option> </el-select> 课程时间 <el-date-picker v-model="startEndTime" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" > </el-date-picker> </el-form-item> <el-form-item label="课程名称"> <el-input v-model="form.courseName"></el-input> </el-form-item> <el-form-item> <el-button style="background-color: red; color: aliceblue" @click="findCourseAll()" >搜索</el-button > </el-form-item> </el-form> </div> <div> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="courseName" label="课程名称" width="180"> </el-table-column> <el-table-column prop="typeName" label="类型" width="180"> </el-table-column> <el-table-column prop="startTime" label="开始时间" width="180"> </el-table-column> <el-table-column prop="endTime" label="结束时间" width="180"> </el-table-column> <el-table-column prop="pic" label="封面" width="180"> <img v-bind:src="tableData.pic" alt="" /> </el-table-column> </el-table> </div> <!-- 分页组件 --> <el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize" :current-page="pageNum" @current-change="handlePageChange" ></el-pagination> </div> </template> <script> import { findAll } from "@/api/user"; import { findCourseAll } from "@/api/user"; export default { data() { return { selectedType: "", pageNum: 1, bookingContent: "", startEndTime: "", pageSize: 7, total: 0, pic:"", form: { typeId: "", startTime: "", endTime: "", page: "", size: "", resname: "", cocahId: localStorage.getItem("userId"), }, tableData:[{ pic:"", courseId:1 }], typeList: [ { id: "", typeName: "", }, ], }; }, created() { this.getTypeAll(); this.getCourseByCoachId(); }, methods: { getCourseByCoachId() { this.form.page = this.pageNum; this.form.size = this.pageSize; this.form.resname = this.form.courseName; this.form.startTime = this.formatDate(this.startEndTime[0]); this.form.endTime = this.formatDate(this.startEndTime[1]); findCourseAll(this.form).then((resp) => { if (resp.data.code == 200) { this.tableData = resp.data.data.list; } }); }, getTypeAll() { findAll().then((resp) => { this.typeList = resp.data.data.list; }); }, returnTypeId(value) { this.form.typeId = value; }, handlePageChange(page) { this.pageNum = page; this.findCourseAll(); }, formatDate(date) { if (!date) return ""; const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, "0"); const day = date.getDate().toString().padStart(2, "0"); const hours = date.getHours().toString().padStart(2, "0"); const minutes = date.getMinutes().toString().padStart(2, "0"); const seconds = date.getSeconds().toString().padStart(2, "0"); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, }, }; </script>报错CoachCourseView.vue:116 [Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'pic')"
09-05
<template> <div> <div> <el-form ref="form" :model="form" label-width="80px"> <el-form-item label=""> 标题 <el-input v-model="form.title" style="width: 200px"></el-input> 创建人 <el-input v-model="form.resname" style="width: 200px"></el-input> 创建时间 <el-date-picker v-model="startEndTime" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" > </el-date-picker> <el-button type="primary" @click="findBulletinAll">搜索</el-button> </el-form-item> <el-form-item> <el-button type="primary" @click="openSaveDialog()" >新增公告</el-button > </el-form-item> </el-form> </div> <div> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="title" label="标题"> </el-table-column> <el-table-column prop="content" label="内容"> <template slot-scope="scope"> {{ scope.row.content.substring(0, 6) }}... </template> </el-table-column> <el-table-column prop="userName" label="创建人"> </el-table-column> <el-table-column prop="createTime" label="创建时间"> <template slot-scope="scope"> {{ formatTime(scope.row.createTime) }} </template> </el-table-column> <el-table-column prop="pic" label="封面"> <template slot-scope="scope"> <img v-bind:src="scope.row.pic" alt="" style="width: 100px; height: 80px" /> </template> </el-table-column> <el-table-column prop="" label="操作"> <template slot-scope="scope"> <el-button type="primary" circle @click="openUpdateDialog(scope.row.id)" >编辑</el-button > <el-button type="danger" circle @click="deleteById(scope.row.id)" >删除</el-button > </template> </el-table-column> </el-table> </div> <div> <!-- 新增 --> <el-dialog title="输入反馈信息" :visible.sync="dialogFormVisible"> <el-form :model="saveForm" ref="formRef"> <el-form-item label="封面"> <el-upload class="avatar-uploader" action="http://localhost:8081/file/upload" :show-file-list="false" :on-success="handleAvatarSuccessSave" :before-upload="beforeAvatarUpload" style="width: 200px" > <img v-if="saveForm.pic" :src="saveForm.pic" class="avatar" /> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </el-form-item> <el-form-item label="标题"> <el-input v-model="saveForm.title" autocomplete="off"></el-input> </el-form-item> <el-form-item label="内容"> <el-input v-model="saveForm.content" autocomplete="off"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible = false">取 消</el-button> <el-button type="primary" @click="saveBulletin">确 定</el-button> </div> </el-dialog> </div> <div> <!-- 修改 --> <el-dialog title="输入反馈信息" :visible.sync="dialogFormVisible2"> <el-form :model="updateForm" ref="formRef"> <el-form-item label="封面"> <el-upload class="avatar-uploader" action="http://localhost:8081/file/upload" :show-file-list="false" :on-success="handleAvatarSuccessUpdate" :before-upload="beforeAvatarUpload" style="width: 200px" > <img v-if="updateForm.pic" :src="updateForm.pic" class="avatar" /> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </el-form-item> <el-form-item label="标题"> <el-input v-model="updateForm.title" autocomplete="off"></el-input> </el-form-item> <el-form-item label="内容"> <el-input v-model="updateForm.content" autocomplete="off" ></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible2 = false">取 消</el-button> <el-button type="primary" @click="updateById">确 定</el-button> </div> </el-dialog> </div> <!-- 分页组件 --> <el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize" :current-page="pageNum" @current-change="handlePageChange" ></el-pagination> </div> </template> <script> import { findBulletinAll } from "@/api/admin"; import { deleteById } from "@/api/admin"; import { saveOrUpdateBulletin } from "@/api/admin"; import { findBulletinById } from "@/api/admin"; export default { name: "adminBulletin", data() { return { dialogFormVisible: false, dialogFormVisible2: false, pageNum: 1, pageSize: 6, total: 0, pic: "", startEndTime: "", form: { startTime: "", endTime: "", title: "", resname: "", page: "", size: "", }, tableData: [], saveForm: { userId: localStorage.getItem("userId"), pic: "", title: "", content: "", }, updateForm: { id: "", userId: localStorage.getItem("userId"), pic: "", title: "", content: "", }, }; }, created() { this.findBulletinAll(); }, methods: { findBulletinAll() { console.log(this.form); this.form.page = this.pageNum; this.form.size = this.pageSize; this.form.startTime = this.formatDate(this.startEndTime[0]); this.form.endTime = this.formatDate(this.startEndTime[1]); findBulletinAll(this.form).then((resp) => { console.log(resp.data.data.list.list); this.tableData = resp.data.data.list.list; this.total = resp.data.total; }); }, openSaveDialog() { this.dialogFormVisible = true; }, saveBulletin() { saveOrUpdateBulletin(this.saveForm).then((resp) => { if (resp.data.code == 200) { this.$message.success(resp.data.message); } else { this.$message.error(resp.data.message); } location.reload(); }); }, openUpdateDialog(id) { this.dialogFormVisible2 = true; findBulletinById(id).then((resp) => { this.updateForm = resp.data.data.bulletin; this.pic = resp.data.data.bulletin.pic; }); }, updateById() { saveOrUpdateBulletin(this.updateForm).then((resp) => { if (resp.data.code == 200) { this.$message.success(resp.data.message); } else { this.$message.error(resp.data.message); } location.reload(); }); }, deleteById(id) { deleteById(id).then((resp) => { if (resp.data.code == 200) { this.$message.success(resp.data.message); } else { this.$message.error(resp.data.message); } location.reload(); }); }, handlePageChange(page) { this.pageNum = page; this.findBulletinAll(); }, formatDate(date) { if (!date) return ""; const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, "0"); const day = date.getDate().toString().padStart(2, "0"); const hours = date.getHours().toString().padStart(2, "0"); const minutes = date.getMinutes().toString().padStart(2, "0"); const seconds = date.getSeconds().toString().padStart(2, "0"); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, formatTime(timeStr) { const date = new Date(timeStr); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); const hours = String(date.getHours()).padStart(2, "0"); const minutes = String(date.getMinutes()).padStart(2, "0"); const seconds = String(date.getSeconds()).padStart(2, "0"); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, //图片回显 handleAvatarSuccessSave(res) { this.saveForm.pic = res.data.url; }, //图片回显 handleAvatarSuccessUpdate(res) { this.updateForm.pic = res.data.url; }, //设置文件格式 beforeAvatarUpload(file) { const isLt2M = file.size / 1024 / 1024 < 10; if (!isLt2M) { this.$message.error("上传头像图片大小不能超过 2MB!"); } return isLt2M; }, }, }; </script> 美化,风格统一,很漂亮那种
最新发布
09-23
<template> <div> <h3>课程信息</h3> <el-form ref="form" :model="form" label-width="80px"> <el-form-item label=""> 课程名称 <el-input v-model="form.courseName" style="width: 200px"></el-input> 课程时间 <el-date-picker v-model="startEndTime" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" > </el-date-picker> <el-button style="background-color: red; color: aliceblue" >搜索</el-button > </el-form-item> </el-form> <div id="box"> <div> <el-radio-group v-model="form.status" style="width: 300px; float: left"> <el-radio-button label="1">已预约</el-radio-button> <el-radio-button label="2">已结束</el-radio-button> </el-radio-group> </div> <ul> <li v-for="v in list" :key="v.id"> <div> <el-button @click="toCourseDetail(v.id)"> <img v-bind:src="v.pic" alt="" /> <h4>{{ v.courseName }}</h4> <p style="white-space: pre-wrap">{{ v.introduce }}</p> </el-button> </div> </li> </ul> </div> <div> <el-dialog title="提示" :visible.sync="centerDialogVisible" width="30%" center > <span slot="footer" class="dialog-footer"> <el-button @click="centerDialogVisible = false">取 消</el-button> <el-button type="primary" @click="courseDetail">确 定</el-button> </span> </el-dialog> </div> <!-- 分页组件 --> <el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize" :current-page="pageNum" @current-change="handlePageChange" ></el-pagination> </div> </template> <script> import { findAllUserCourse } from '@/api/user'; export default { data() { return { centerDialogVisible:false, startEndTime: "", pageSize:6, pageNum:1, total:0, form: { startTime: "", endTime: "", page: "", size: "", resname: "", userId: "", }, list: [ { value: "0", id: "", pic: "", courseName: "", introduce: "", }, ], }; }, created() { this.findAllUserCourse(); }, methods: { findAllUserCourse(){ this.userId=localStorage.getItem("userId") this.form.page = this.pageNum; this.form.size = this.pageSize; this.form.resname = this.form.courseName; this.form.startTime = this.formatDate(this.startEndTime[0]); this.form.endTime = this.formatDate(this.startEndTime[1]); findAllUserCourse(this.form).then((resp)=>{ this.list = resp.data.data.courses.list; console.log(this.list); this.total = resp.data.data.courses.total; this.form.startTime = ""; this.form.endTime = ""; }) }, toCourseDetail(id) { this.centerDialogVisible=true this.courseDetail(id) }, courseDetail(){ }, handlePageChange(page) { this.pageNum = page; this.findCourseAll(); }, formatDate(date) { if (!date) return ""; const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, "0"); const day = date.getDate().toString().padStart(2, "0"); const hours = date.getHours().toString().padStart(2, "0"); const minutes = date.getMinutes().toString().padStart(2, "0"); const seconds = date.getSeconds().toString().padStart(2, "0"); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, }, }; </script> <style scoped> #box ul { display: flex; flex-wrap: wrap; position: absolute; top: 220px; } #box li { padding: 3px; list-style: none; margin-right: 15px; border: 1px solid #eee; } #box img { width: 200px; height: 150px; } </style>报错UserCourseView.vue:110 [Vue warn]: Error in render: "TypeError: Cannot read properties of null (reading 'id')"
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值