使用element插件点击跳转时报错form-item.vue:315 Uncaught (in promise) TypeErelForm.removeField is not a function

本文探讨了一个关于Element UI中面包屑导航点击后路由变化但内容未更新的问题。问题源于在使用input和select时不正确地包裹在<el-formref>标签内。解决方法是在组件中添加<el-formref>以确保数据绑定和页面响应。

问题描述:
使用element插件中的面包屑导航跳转页面,点击后路由地址变了,但是页面内容没变,报错
在这里插入图片描述
原因:
如果使用了element中的input、select等插件,但是没有在最外层添加‘<el-form ref=“form” >’,就会报上述错误

解决方法:
添加<el-form ref=“form” ></el-form>

<el-form ref="form" >
	
	el-form-item label="Activity name">
      <el-input v-model="sizeForm.name"></el-input>
    </el-form-item>
    <el-form-item label="Activity zone">
      <el-select
        v-model="sizeForm.region"
        placeholder="please select your zone"
      >
        <el-option label="Zone one" value="shanghai"></el-option>
        <el-option label="Zone two" value="beijing"></el-option>
      </el-select>
    </el-form-item>
</el-form>
<template> <div class="login-container"> <div class="login-content"> <h1>登录页面</h1> <el-form :model="loginForm" label-width="80px"> <el-form-item label="用户名"> <el-input v-model="loginForm.name"></el-input> </el-form-item> <el-form-item label="密码"> <el-input type="password" v-model="loginForm.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="handleLogin">登录</el-button> </el-form-item> </el-form> </div> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import { useRouter } from 'vue-router'; import axios from 'axios' import { ElMessage } from 'element-plus' const router = useRouter(); const loginForm = ref({ name: '', password: '' }); let list=ref(); function handleLogin(){ axios.post('/api/admin/UserLogin',loginForm.value) .then(rst=>{ list.value=rst.data; if(rst.data.code==200){ ElMessage('登录成功!') if(list.value.is_admin){ router.push('/main_admin') } else router.push({ path: '/main_user', query: { id: list.value.id } }) }else{ ElMessage('登录失败!请检查用户名或密码是否正确!') } } ) } </script> <style scoped> .login-container { display: flex; justify-content: center; align-items: center; height: 100vh; /* 使用vite的url函数处理图片路径 */ background-image: url(../assets/login-image-bg.png); background-size: cover; background-position: center; } .login-content { padding: 40px; background-color: rgba(255, 255, 255, 0.8); border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); width: 400px; } h1 { font-size: 28px; margin-bottom: 20px; color: #333; text-align: center; } .el-form-item { width: 100%; margin-bottom: 15px; } .el-button { width: 100%; } </style>这段代码在登录可以成功请求,但不能正常跳转,帮我分析可能的错误原因
07-10
<template> <el-form label-width="90px"> <el-form-item label="类别"> <el-cascader v-model="category" :props="category_props" :options="categoryData.category_options" filterable clearable style="width:100%" /> </el-form-item> <el-form-item label="信息标题"> <el-input v-model="form.title" /> </el-form-item> <el-form-item label="缩略图"> <el-upload ref="uploadRef" class="avatar-uploader" action="#" :limit="1" :multiple="false" :auto-upload="false" :show-file-list="false" :on-change="handleChange"> <img v-if="form.image_url" :src="form.image_url" class="avatar" /> <el-icon v-else class="avatar-uploader-icon"> <Plus /> </el-icon> </el-upload> </el-form-item> <el-form-item label="内容"> <div style="border:1px solid #ccc;width:180%;"> <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" /> <Editor style="height: 300px; overflow-y: hidden;" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleEditorCreated" @onChange="handleEditorChange" /> </div> </el-form-item> <el-form-item> <el-button type="danger" @click="handleSubmit">确定</el-button> <el-button type="primary">返回</el-button> </el-form-item> </el-form> </template> <script setup> import { reactive, toRefs } from 'vue' import { onBeforeUnmount, ref, shallowRef, onBeforeMount } from 'vue' import '@wangeditor/editor/dist/css/style.css'//入css import { Editor, Toolbar } from '@wangeditor/editor-for-vue' import { useCategoryHook } from '@/hooks/categoryHook' import useStore from '@/store' const store = useStore() const uploadRef = ref(null) const { categoryData, getAllCategory } = useCategoryHook() const data = reactive({ category: 0, category_props: { label: 'name', value: 'id' }, file: null, form: { category_id: [], title: '', image_url: '', content: '' }, }) const { category_props, form } = toRefs(data) onBeforeMount(() => { getAllCategory() }) const checkUploadFile = (rawFile) => { console.log('file.size', rawFile.size) if (rawFile.size / 1024 / 1024 > 2) { ElMessage.error('上传的文件大小不能超过2MB!') return false } return true } const handleChange = (file) => { if (!checkUploadFile(file)) return data.file = file.raw form.value.image_url = URL.createObjectURL(file.raw) uploadRef.value.clearFiles() } const mode = 'default' const editorRef = shallowRef() //内容HTML const valueHtml = ref('') const toolbarConfig = {} toolbarConfig.excludeKeys = ['group-video', 'insertTable', 'fullScreen'] const editorConfig = { placeholder: '请输入内容...' } //组件销毁,也即是销毁编辑器 onBeforeUnmount(() => { const editor = editorRef.value if (editor == null) return editor.destroy() }) const handleEditorCreated = (editor) => { editorRef.value = editor//记录 editor 实例,重要! } const handleEditorChange = (editor) => { form.value.content = editor.getHtml() } const handleSubmit = async () => { const { category_id, title, content } = form.value const fd = new FormData() fd.append('category_id', category_id[category_id.length - 1]) fd.append('title', title) fd.append('content', content) fd.append('file', data.file) console.log('fd', fd); const res = await store.info.createInfoAction(fd) console.log('res', res) } </script> <style scoped> .avatar { width: 178px; height: 178px; object-fit: cover; display: block; } </style> <style> .avatar-uploader .el-upload { border: 1px dashed var(--el-border-color); border-radius: 6px; display: inline-block; cursor: pointer; position: relative; overflow: hidden; transition: var(--el-transition-duration-fast); } .avatar-uploader .el-upload:hover { border-color: var(--el-color-primary); } .el-icon.avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; text-align: center; } .w-e-text img { max-width: 100%; height: auto; } </style> <template> <div class="form-button-group margin-bottom-20"> <router-link :to="{ name: 'InfoDetail' }"> <el-button type="danger">新增</el-button> </router-link> </div> <el-form :inline="true" ref="searchFormRef"> <el-form-item label="类别" class="type"> <el-cascader v-model="category" :props="category_props" :options="categoryData.category_options" filterable clearable style="width:100%" /> </el-form-item> <!-- <el-form-item label="关键词" prop="key"> <el-select class="select" v-model="keywords.key" placeholder="请选择"> <el-option v-for="item in keywords.options" :key="item.value" :value="item.value" :label="item.label"></el-option> </el-select> </el-form-item> <el-form-item prop="value"> <el-input placeholder="请输入关键词" v-model="keywords.value" clearable /> </el-form-item> --> <el-form-item> <el-button type="danger" @click="handleSearch">搜索</el-button> <el-button type="default" @click="handleReset">重置</el-button> </el-form-item> </el-form> <el-table ref="table" :data="infoList" border style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="60" /> <el-table-column label="标题" width="200" prop="title" /> <el-table-column label="类别" width="100" prop="category.name" /> <el-table-column label="创建日期" width="200" prop="created_time" /> <el-table-column label="发布状态" width="120"> <template #default="scope"> <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" :loading="scope.row.loading" @change="handleChangStatus($event, scope.row)" /> </template> </el-table-column> <el-table-column label="发布日期" width="200" prop="release_time" /> <el-table-column label="操作"> <template #default="scope"> <el-button size="small" @click="handleEdit(scope.row.id)"> 编辑 </el-button> <el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-row class="margin-top-20"> <el-col :span="6"> <el-button type="danger">批量删除</el-button> </el-col> <el-col :span="18"> <el-pagination class="pull-right" v-model:current-page="request_data.pageIndex" v-model:page-size="request_data.pageSize" :page-sizes="[10, 20, 30, 50]" background small layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </el-col> </el-row> </template> <script setup> import { ref, reactive, toRefs, onBeforeMount } from 'vue' import { useRouter } from 'vue-router' import useStore from '@/store' import { useCategoryHook } from '@/hooks/categoryHook' import { ElMessage } from 'element-plus' const store = useStore() const router = useRouter() const { categoryData, getAllCategory } = useCategoryHook() const data = reactive({ category: 0, category_props: { label: 'name', value: 'id' }, infoList: [], total: 0, request_data: { pageIndex: 1, pageSize: 10 } }) const { category, category_props, infoList, total, request_data } = toRefs(data) const getInfoList = async () => { try { const res = await store.info.getInfoListAction({ pageIndex: request_data.value.pageIndex, pageSize: request_data.value.pageSize, category_id: category.value || undefined }) data.infoList = res.data.rows data.total = res.data.count } catch (error) { console.error('获取列表失败', error) } } const handleSizeChange = (val) => { console.log(`${val} items per page`); request_data.value.pageSize = val }; const handleCurrentChange = (val) => { console.log(`current page: ${val}`); request_data.value.pageIndex = val }; const handleEdit = (id) => { console.log('handle id', id); router.push({ name: 'InfoDetail' }) } onBeforeMount(() => { getInfoList(), getAllCategory() }) </script> <style lang="scss" scoped> .type { width: 200px; } </style> import { defineStore } from "pinia"; import { GetInfoList, // ChangeInfoStatus, GetAllCategory, UploadFile, CreateInfo, // UpdateInfo, // DeleteInfo, } from "@/api/info"; export const useInfoStore = defineStore("info", () => { function getInfoListAction(requestData) { return new Promise((resolve, reject) => { GetInfoList(requestData).then(resolve).catch(reject); }); } // function changeInfoStatusAction(requestData) { // const { id, data } = requestData; // return new Promise((resolve, reject) => { // ChangeInfoStatus(id, data).then(resolve).catch(reject); // }); // } function getAllCategoryAction() { return new Promise((resolve, reject) => { GetAllCategory().then(resolve).catch(reject); }); } function uploadFileAction(requestData = {}) { return new Promise((resolve, reject) => { UploadFile(requestData) .then((response) => { resolve(response); }) .catch((error) => { reject(error); }); }); } function createInfoAction(requestData = {}) { return new Promise((resolve, reject) => { CreateInfo(requestData) .then((response) => { resolve(response); }) .catch((error) => { reject(error); }); }); } // function updateInfoAction({ id, data }) { // return new Promise((resolve, reject) => { // UpdateInfo(id, data).then(resolve).catch(reject); // }); // } // function deleteInfoAction({ id, data }) { // return new Promise((resolve, reject) => { // DeleteInfo(id, data).then(resolve).catch(reject); // }); // } return { getInfoListAction, // changeInfoStatusAction, getAllCategoryAction, uploadFileAction, createInfoAction, // updateInfoAction, // deleteInfoAction, }; }); import installer from "@/utils/request"; export function GetInfoList(params = {}) { return installer.request({ url: "/infos", method: "GET", params, }); } // export function ChangeInfoStatus(id, data = {}) { // return installer.request({ // url: `/infos/${id}/status`, // method: "PUT", // data, // }); // } export function GetAllCategory(params) { return installer.request({ url: "/categories", method: "GET", params, }); } export function UploadFile(data = {}) { return instance.request({ url: "/uplosd", method: "POST", data, }); } export function CreateInfo(data = {}) { return installer.request({ url: "/infos", headers: { "Content-Type": "multipart/form-data" }, method: "POST", data, }); } // export function UpdateInfo(id, data = {}) { // return installer.request({ url: `/infos/${id}`, method: "PUT", data }); // } // export function DeleteInfo(id, data = {}) { // return installer.request({ url: `/infos/${id}`, method: "DELETE", data }); // } import { reactive } from "vue"; import useStore from "@/store"; export function useCategoryHook() { const store = useStore(); const categoryData = reactive({ category_options: [], }); const getAllCategory = async () => { const res = await store.info.getAllCategoryAction(); categoryData.category_options = res.data; }; return { categoryData, getAllCategory }; } :8888/#/info-detail:1 Uncaught (in promise) {code: 1, msg: 'id为undefined的类别不存在呀!', data: null} code : 1 data : null msg : "id为undefined的类别不存在呀!" [[Prototype]] : Object constructor : ƒ Object() hasOwnProperty : ƒ hasOwnProperty() isPrototypeOf : ƒ isPrototypeOf() propertyIsEnumerable : ƒ propertyIsEnumerable() toLocaleString : ƒ toLocaleString() toString : ƒ toString() valueOf : ƒ valueOf() __defineGetter__ : ƒ __defineGetter__() __defineSetter__ : ƒ __defineSetter__() __lookupGetter__ : ƒ __lookupGetter__() __lookupSetter__ : ƒ __lookupSetter__() __proto__ : (…) get __proto__ : ƒ __proto__() set __proto__ : ƒ __proto__()
最新发布
10-16
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值