当前位置:   article > 正文

VUE3+Element-Plus入门

vue3+element-plus

前端:Vue3,Vite,TypeScript,SCSS,Element Plus,Router,axios
后端:.NET6,Minimal API,Sql sugar(CodeFirst)

根据哔哩哔哩视频整理的,比较详细了,建议先根据文档写,有问题再看代码,记忆比较深刻。

代码已上传.

哔哩哔哩视频地址:001.教学演示和技术栈介绍_哔哩哔哩_bilibili

------------------------------------------------------------安装环境---------------------------------------------------
安装nodejs:

开发vue项目需要通过那npm指令,安装这个只是为了使用npm命令
下载地址:http://nodejs.cn/download/
下载是否成功测试:node --version


安装pnpm:
官网:https://www.pnpm.cn/
安装:npm install -g pnpm@next-7
相比npm更快更稳定,所有使用npm安装包的命令都能替换成pnpm;pnpm dev等价于npm run dev


创建前端项目:
新建文件夹,在文件夹路径进入cmd,执行指令:pnpm create vite@latest web(web为项目名称)
指令执行完毕会返回一些打印,让你选择项目模板,按上下键选择,我们选择Vue然后回车
再次选择TypeScript
然后会返回一些打印,提示你运行的步骤


用VSCODE打开项目:
文件-->打开文件夹-->选择刚才创建的文件
node_modules:模块包(通过install安装的包都在这个目录里面)
public:公共资源(json,images)
src:项目目录
assets:静态资源
components:组件
App.vue:根组件
main.ts:根函数入口,全局配置生效的地方
package.json:项目配置文件,项目的标题,版本,模块的版本等信息
如果没有node_modules文件,只需要在终端执行pnpm install即可


vite.config.ts文件可以配置ip和端口,以及启动后是否默认打开浏览器

  1. server:{
  2. host:"127.0.0.1",
  3. port:3001,
  4. open:true
  5. }
  6. server:{open: true}    //自动打开浏览器


安装sass
官网介绍:https://www.sass.hk/guide/
命令:pnpm install sass
目的:支持嵌套css编写;支持定义变量


安装路由(多界面相互之间跳转):
介绍:https://router.vuejs.org/zh/introduction.html
指令:pnpm install vue-router@4
测试:
src下新建router文件夹下新建index.ts文件

import { createRouter, createWebHistory } from 'vue-router'


src下新建views文件夹下新建HomePage.vue与TestPage.vue文件,格式如下,内容不同

HomePage.vue:

  1. <template>
  2.     <div>0000</div>
  3. </template>
  4. TestPage.vue:
  5. <template>
  6.     <div>1111</div>
  7. </template>


在main.ts中配置路由,增加下面两行

  1. import router from './router/index'
  2. create(App).use(router).mount('#app')


router文件夹下index.ts配置

  1. import {createRouter,createWebHistory} from 'vue-router'
  2. var router=createRouter({
  3.     history:createWebHistory(),
  4.     routes:[
  5.         {name:"home", path:"/", component: () => import("../views/HomePage.vue")},    //name:路由名字;path:路由路径;import:路由组件
  6.         {name:"test", path:"/test", component: () => import("../views/TestPage.vue")}
  7.     ]
  8. })
  9. export default router

解决./App.vue或者其他.vue文件报错,在vite-env.d.ts增加以下代码解决(ts需要固定格式,这里跳过格式检查)

  1. declare module '*.vue' {
  2.     import { App, defineComponent } from 'vue'
  3.     const component: ReturnType<typeof defineComponent> & {
  4.       install(app: App): void
  5.     }
  6.     export default component
  7.   }


在App.vue文件中添加<router-view></router-view>,此标签就是表示把路由页面呈现在哪个地方

------------------------------------------------------集成element-plus--------------------------------------------------
Element Plus

官网介绍:https://element-plus.gitee.io/zh-CN/
安装命令:pnpm install element-plus
在element-plus官网中快速入门
按需引入包:
 

pnpm install -D unplugin-vue-components unplugin-auto-import


因为我使用的是Vite,所以就用教程的Vite引入,其他自己做的页面的话就用Webpack
首先在vite.config.ts文件中导入:

  1. import AutoImport from 'unplugin-auto-import/vite'
  2. import Components from 'unplugin-vue-components/vite'
  3. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'


再在plugins的vue(),后面添加

  1. AutoImport({
  2.       resolvers: [ElementPlusResolver()],
  3.     }),
  4. Components({
  5.       resolvers: [ElementPlusResolver()],
  6.     }),


在HomePage.vue文件里面把element的组件(随便在element官网找几个button按钮组件)写入进去,运行代码,查看是否是element的UI

按需导入后,组件可以使用了,但是少数部分组件会有报错,但是不影响功能,如果想要解决报错信息,需要修改tsconfig.json文件
在include节点里面加入:"**/*.d.ts"即可导入图标:

根据element官网文档
icon图标:先安装包管理器:pnpm install @element-plus/icons-vue
注册所有图标(放在main.ts文件中):

  1. import * as ElementPlusIconsVue from '@element-plus/icons-vue'
  2. const app = createApp(App)
  3. for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  4.   app.component(key, component)
  5. }


最后一行改为app.use(router).mount('#app')

在HomePage.vue文件加入icon图标代码(element文档Button里面有)
例如:

  1. <el-button :icon="Search" circle />
  2. <el-button type="primary" :icon="Edit" circle />
  3. 还要加入下面的代码
  4. <script lang="ts" setup>
  5. import {
  6.   Check,
  7.   Delete,
  8.   Edit,
  9.   Message,
  10.   Search,
  11.   Star,
  12. } from '@element-plus/icons-vue'
  13. </script>


如果有报错就把tsconfig.json里面的配置修改为:

  1. "moduleResolution": "Node",
  2. "noUnusedLocals": false,


-----------------------------------------------------静态页面的实现-------------------------------------------------------
注释掉main.ts的import './style.css'          //不用自带的样式

HomePage.vue增加:

  1. <template>    //页面
  2.     <div></div>
  3. </template>
  4. <script lang="ts" setup>    //脚本
  5. </script>
  6. <style lang="scss" scoped>    //scss:样式;scoped:只在本页面有效,不影响其他页面
  7. </style>

以element组件表格为例,直接复制到HomePage.vue页面
然后在style标签添加:

  1. .container{        //居中
  2.   margin: 100px auto;
  3.   width: 50%;
  4. }
  5. .table{            //表格间距等
  6.   margin: 10px 0;
  7. }

增加页面的搜索,添加,删除操作:div中增加以下代码

  1. <el-row>
  2.         <el-col :span="12">
  3.           <el-input v-model="SearchVal" placeholder="Please input" class="input-with-select" @keyup.enter="enterSearch">
  4.             <template #append>
  5.               <el-button :icon="Search" @click="enterSearch"></el-button>
  6.             </template>
  7.           </el-input>
  8.         </el-col>
  9.         <el-col :span="12">
  10.           <el-button type="primary" @click="openAdd">add</el-button>
  11.           <el-button type="danger" @click="onDel">delete</el-button>
  12.         </el-col>
  13.       </el-row>

script标签增加:

  1. import { ref } from 'vue';
  2. import { Search } from '@element-plus/icons-vue';
  3. const SearchVal = ref("")
  4. const enterSearch=()=>{
  5. }
  6. const onDel=()=>{
  7. }
  8. const openAdd=()=>{
  9. }


增加多选框:
在table里面添加

  1. <el-table-column type="selection" width="55"></el-table-column>        //多选框
  2. <el-table-column prop="order" label="Order" width="80" />    //排序列


在script数据里面增加字段order,例如:order: 1,在table标签最后一列增加数据后修改与删除按钮(插槽):

  1. <el-table-column label="Operations">
  2.           <template #default="scope">
  3.             <el-button size="small" @click="handleEdit(scope.$index,scope.row)">Edit</el-button>
  4.             <el-button size="small" type="danger" @click="handleDelete(scope.$index,scope.row)">Delete</el-button>
  5.           </template>
  6.         </el-table-column>


修改与删除按钮实现方法:

  1. const handleEdit=(index: number, row: any)=>{    //index类型指定number,row类型指定任何数据类型都可以
  2.   console.log(index,row)
  3. }
  4. const handleDelete=(index: number, row: any)=>{
  5.   console.log(index,row)
  6. }

在div里面,table外增加分页代码:

<el-pagination background layout="prev,pager,next" :total="total" @current-change="currentChange"></el-pagination>


实现:

const total = ref(100)        //最大100页


每页数据:

  1. const currentChange=(val:number)=>{
  2.   console.log(val)
  3. }


--------------------------------------------------增加add与edit组件-----------------------------------------------------
components文件夹下增加add.vue文件
使用官网的弹窗组件

  1. <template>
  2.     <el-dialog v-model="dialogVisible" title="新增" width="30%">
  3.         <el-form>
  4.             <el-form-item label="时间" prop="date">
  5.                 <el-date-picker v-model="form.date" type="date" placeholder="请选择一个时间" :disabled-date="disablesDate"></el-date-picker>
  6.             </el-form-item>
  7.             <el-form-item label="名称" prop="name">
  8.                 <el-input v-model="form.name"></el-input>
  9.             </el-form-item>
  10.             <el-form-item label="地址" prop="address">
  11.                 <el-input v-model="form.address"></el-input>
  12.             </el-form-item>
  13.             <el-form-item label="排序" prop="order">
  14.                 <el-input v-model.number="form.order"></el-input>
  15.             </el-form-item>
  16.         </el-form>
  17.         <template #footer>
  18.             <span class="dialog-footer">
  19.                 <el-button @click="closeAdd()">Cancel</el-button>
  20.                 <el-button type="primary" @click="save()">Confirm</el-button>
  21.             </span>
  22.         </template>
  23.     </el-dialog>
  24. </template>
  25. <script lang="ts" setup>
  26. import { ref } from 'vue'       //导入ref
  27. const dialogVisible = ref(false)        //控制显示与隐藏,默认不显示
  28. const form = ref()
  29. const disablesDate = (time: any) =>{
  30. //最大时间,从今天开始,只能选今天及以后的时间
  31.     const _maxTime = Date.now() - 24 * 60 * 60 * 1000 * 1
  32.     return time.getTime() <= _maxTime
  33. }
  34. const closeAdd = () =>{
  35. }
  36. const save = () =>{
  37.     
  38. }
  39. </script>

------------------------------------------页面引用组件(实现点击按钮跳出弹框)-------------------------------------
在src下新建class文件夹,class文件夹下新建User.ts文件

  1. export default class User{      //导出一个默认User类
  2.     id: string = ""
  3.     date: string = ""
  4.     name: string = ""
  5.     address: string = ""
  6.     order: number = 0
  7. }

add.vue文件修改:

  1. import { ref,Ref,computed } from 'vue'       //导入ref与计算函数computed和Ref表单
  2. import User from '../class/User'    //导入User对象
  3. const props = defineProps({         //定义一个对象,defineProps为内置函数,用于接收参数
  4.     isShow: Boolean,         //控制弹窗的弹出与隐藏的参数
  5.     info: User             //对象类型(参数)
  6. })
  7. const dialogVisible = computed(()=>props.isShow)        //控制弹窗显示与隐藏,实现props中isShow与dialogVisible值的联动


定义一个表单:

  1. const form: Ref<User> = ref<User>({            //声明form是User类型
  2.     id: "",
  3.     date: "",
  4.     name: "",
  5.     address: "",
  6.     order: 0
  7. })


修改HomePage.vue页面
导入弹窗:

<addVue :isShow = "isShow"></addVue>


导入add和User:

  1. import addVue from '../components/add.vue';   //将add.vue导入
  2. import User from '../class/User';     //将User导入


如果addVue报错,禁用Vetur插件,使用Vue Language Features插件
设置默认不显示:

const isShow = ref(false)

数据来源:

const info = ref<User>(new User())        //数据


修改与删除控制:

  1. const handleEdit=(index: number, row: User)=>{        //row:数据类型
  2.   console.log(index,row)
  3.   info.value = row        //编辑时赋值
  4.   isShow.value = true    //点击编辑时修改为显示
  5. }
  6. const handleDelete=(index: number, row: User)=>{
  7.   console.log(index,row)
  8. }
  9. const openAdd=()=>{        //添加时也显示
  10.   isShow.value = true
  11. }


运行测试,点击add和edit就可以跳出弹窗


------------------------------------------------------侦听器Watch()-------------------------------------------------------
作用:将页面form与数据info绑定
修改HomePage.vue页面
导入弹窗:

<addVue :isShow = "isShow" :info = "info"></addVue>        //增加info,将数据传入


修改add.vue,修改title:
:title="info?.name ? '修改' : '新增'"    //改为根据客户点击add还是edit改变title

import { ref, Ref, computed, watch } from 'vue'        //增加watch

  1. watch(() => props.info,(newInfo) => {       //监听props.info值,如果info值改变,则将改变后的值赋值给newInfo,将newInfo值重新赋值给info;其实这里有两个参数,后面还有一个oldInfo(修改前的数据),但是我们这里用不到
  2.     if(newInfo){            //如果newInfo值改变,则重新对form表单进行赋值
  3.         form.value = {
  4.             id: newInfo.id,
  5.             date: newInfo.date,
  6.             name: newInfo.name,
  7.             address: newInfo.address,
  8.             order: newInfo.order
  9.         }
  10.     }
  11. })


-------------------------------------------------子组件触发父组件事件--------------------------------------------------
在add.vue中定义两个事件:

const emits = defineEmits(["closeAdd","success"])


修改closeAdd事件:

  1. const closeAdd = () => {
  2.     emits("closeAdd")        //执行closeAdd事件
  3. }


修改save事件:

  1. const save = () => {
  2.     emits("success")        //执行success事件
  3. }

在子组件触发了父组件的事件,父组件要定义对应事件;在HomePage.vue中定义closeAdd事件与success事件:

  1. const closeAdd = () => {
  2.     isShow.value = false        //关闭弹窗
  3.     info.value = new User()        //数据值初始化
  4. }
  5. const success = (message: string) => {        //加参数打印成功
  6.     isShow.value = false
  7.     info.value = new User()
  8.     ElMessage.success(message)        //成功弹窗出来
  9. }


将事件绑定到弹窗,修改addVue标签

<addVue :isShow="isShow" :info="info" @closeAdd="closeAdd" @success="success"></addVue>


修改add.vue,实现弹窗右上角关闭(x)功能:
在<el-dialog>标签中添加@close="$emit('closeAdd')"
在<el-dialog>标签中添加draggable,实现弹窗随意拖动效果

---------------------------------------------------.NET Core Minimal API----------------------------------------------
打开VS2019 --> 创建新项目 --> 选择ASP.NET Core Web API --> 下一步 --> 修改项目名称和位置 --> 下一步 --> 启用OpenAPI支持,其他不用选 --> 创建
进入Program,删除app.MapGet默认接口,改为:

 

  1. if (app.Environment.IsDevelopment())
  2. {
  3.     app.UseSwagger();
  4.     app.UseSwaggerUI();
  5. }
  6. //极简API接口,MapGet:访问方式
  7. app.MapGet("/test", () =>
  8. {
  9.     return "ok";
  10. });
  11. app.Run();

运行后会到swagger UI,调试成功即可


 

------------------------------------------------------SqlSugar介绍与安装-----------------------------------------------
官网:

介绍:https://www.donet5.com/Home/Doc
教学:https://www.donet5.com/Doc/29
是一款老牌的.NET开源ORM框架

项目安装引用:
在解决方案资源管理器中右键依赖项 --> 管理NuGet程序包 --> 浏览 --> 输入sqlsugarcore --> 点击后安装即可
安装完成后在项目目录的依赖项下的包下就会看到sqlsugarcore的包,说明安装成功
根目录下新建Model文件夹,Model文件夹中新建User实体类
User内容:

 

  1. public class User
  2. {
  3.     [SugarColumn(IsPrimaryKey = true)]      //设置为主键
  4.     public string Id { get; set; }
  5.     public string Name { get; set; }
  6.     public DateTime Date { get; set; }
  7.     public string Address { get; set; }
  8.     public int Order { get; set; }
  9. }

波浪线无影响,如需要去掉,鼠标放在波浪线,找到无提示即可


--------------------------------------------------------实现CodeFirst-----------------------------------------------------
1.根据数据库中的字符串信息,动态创建数据库
2.通过反射读取当前程序集下的类,然后创建表
3.添加测试数据到数据库,完成初始化根目录下创建Data文件夹,Data文件夹下创建SqlSugarHelper辅助类

  1. public class SqlSugarHelper
  2. {
  3.     public static SqlSugarScope Db = new SqlSugarScope(new ConnectionConfig()
  4.     {
  5.         ConnectionString = "server=127.0.0.1;uid=root;pwd=admin;database=myDatabase",
  6.         DbType = DbType.MySql,//设置数据库类型(我用的MySQL,根据自己的需要修改)     
  7.         IsAutoCloseConnection = true,//自动释放数据务,如果存在事务,在事务结束后释放     
  8.         InitKeyType = InitKeyType.Attribute //从实体特性中读取主键自增列信息
  9.     },
  10.     db =>
  11.     {
  12.         //打印sql日志,调试阶段可以开着,方便调试
  13.         db.Aop.OnLogExecuting = (sql, pars) =>
  14.         {
  15.             Console.WriteLine(sql);
  16.         };
  17.     }
  18.     );
  19.     //初始化数据库
  20.     public static string InitDateBase()
  21.     {
  22.         try
  23.         {
  24.             //创建数据库
  25.             Db.DbMaintenance.CreateDatabase();
  26.             //初始化数据表,如果没有则创建
  27.             string nspace = "api.Model";        //过滤,表示只使用api.Model下的类(User)
  28.             //LoadFrom可以加载AppContext.BaseDirectory程序集下的api.dll文件;GetTypes获取dll文件下的所有类;使用where过滤,确保拿到的是api.Model下的文件
  29.             Type[] ass = Assembly.LoadFrom(AppContext.BaseDirectory + "api.dll").GetTypes().Where(p => p.Namespace == nspace).ToArray();
  30.             Db.CodeFirst.SetStringDefaultLength(200).InitTables(ass);       //初始化table
  31.             //添加数据前清空数据
  32.             Db.Deleteable<User>().ExecuteCommand();
  33.             //添加模拟数据
  34.             List<User> list = new List<User>();
  35.             for (int i = 1; i <= 5; i++)
  36.             {
  37.                 list.Add(new User()
  38.                 {
  39.                     Id = Guid.NewGuid().ToString(),
  40.                     Name = "Tom" + i,
  41.                     Date = DateTime.Now,
  42.                     Address = "No.  189, Grove St, Los Angeles",
  43.                     Order = i
  44.                 });
  45.             }
  46.             for (int i = 6; i <= 10; i++)
  47.             {
  48.                 list.Add(new User()
  49.                 {
  50.                     Id = Guid.NewGuid().ToString(),
  51.                     Name = "Tom" + i,
  52.                     Date = DateTime.Now,
  53.                     Address = "No.  129, Grove St, Los Angeles",
  54.                     Order = i
  55.                 });
  56.             }
  57.             for (int i = 11; i <= 30; i++)
  58.             {
  59.                 list.Add(new User()
  60.                 {
  61.                     Id = Guid.NewGuid().ToString(),
  62.                     Name = "Tom" + i,
  63.                     Date = DateTime.Now,
  64.                     Address = "No.  87, Grove St, Los Angeles",
  65.                     Order = i
  66.                 });
  67.             }
  68.             //添加到表中
  69.             Db.Insertable(list).ExecuteCommand();
  70.             return "ok";
  71.         }
  72.         catch(Exception ex)
  73.         {
  74.             return ex.Message;
  75.         }
  76.     }
  77. }



-------------------------------------------------------------写接口-----------------------------------------------------------
实体类(正常情况是要新建类,但是demo为了方便,直接写在接口下面)

  1. public class Model
  2. {
  3.     public string KeyWord { get; set; }     //关键字查询
  4.     public int PageIndex { get; set; }      //分页
  5.     public int PageSize { get; set; }
  6.     public int Total { get; set; }      //分页总数
  7. }
  8. //对结果包装
  9. public class Result
  10. {
  11.     public int Total { get; set; }
  12.     public object Res { get; set; }
  13. }
  14. //添加的请求参数
  15. public class AddReq
  16. {
  17.     public string Name { get; set; }
  18.     public DateTime Date { get; set; }
  19.     public string Address { get; set; }
  20.     public int Order { get; set; }
  21. }

写查询方法:

  1. //分页查询
  2. public static Result GetUsers(Model req)
  3. {
  4.     Result result = new Result();
  5.     int total = 0;
  6.     result.Res = Db.Queryable<User>()       //sql查询
  7.         .WhereIF(!string.IsNullOrEmpty(req.KeyWord), s => s.Name.Contains(req.KeyWord) || s.Address.Contains(req.KeyWord))      //判断如果前面部分成立则执行后面的条件,否则全部返回
  8.         .OrderBy(s => s.Order)      //排序
  9.         .ToOffsetPage(req.PageIndex, req.PageSize, ref total);      //分页
  10.     result.Total = total;
  11.     return result;
  12. }

写添加方法:

  1. public static bool Add(AddReq req)
  2. {
  3.     User info = new User()
  4.     {
  5.         Id = Guid.NewGuid().ToString(),
  6.         Name = req.Name,
  7.         Date = req.Date,
  8.         Address = req.Address,
  9.         Order = req.Order
  10.     };
  11.     if (Db.Queryable<User>().Any(p => p.Name == req.Name))      //判断是否存在,存在则返回false
  12.     {
  13.         return false;
  14.     }
  15.     return Db.Insertable(info).ExecuteCommand() > 0;        //不存在则插入到数据库里面,并且返回插入成功或者失败
  16. }

写修改方法:

  1. public static bool Edit(User req)
  2. {
  3.     User info = Db.Queryable<User>().First(p => p.Id == req.Id);        //先读一遍
  4.     if (info == null)      //判断是否存在,不存在则返回false
  5.     {
  6.         return false;
  7.     }
  8.     //存在则赋值
  9.     info.Name = req.Name;
  10.     info.Date = req.Date;
  11.     info.Address = req.Address;
  12.     info.Order = req.Order;
  13.     return Db.Updateable(info).ExecuteCommand() > 0;        //更新数据,并且返回更新成功或者失败
  14. }

//删除方法

  1. public static bool Del(string ids)
  2. {
  3.     return Db.Ado.ExecuteCommand($"DELETE from `User` WHERE Id IN({ids})") > 0;
  4. }


在Program文件中增加接口实现:

  1. app.MapGet("/codefirst", () =>
  2. {
  3.     return SqlSugarHelper.InitDateBase();
  4. });
  5. app.MapPost("/list", (Model req) =>
  6. {
  7.     return SqlSugarHelper.GetUsers(req);
  8. });
  9. app.MapPost("/add", (AddReq req) =>
  10. {
  11.     return SqlSugarHelper.Add(req);
  12. });
  13. app.MapPost("/edit", (User req) =>
  14. {
  15.     return SqlSugarHelper.Edit(req);
  16. });
  17. app.MapGet("/del", (string ids) =>
  18. {
  19.     return SqlSugarHelper.Del(ids);
  20. });

运行代码,会自动跳转到页面
先执行/codefirst初始化数据库
再执行/list,将条件换成全查条件,查看输出是否正确

------------------------------------------------------前后端数据交互------------------------------------------------------
axios的安装与使用:
官网介绍:http://www.axios-js.com/

安装命令:
pnpm install axios

在前端src文件夹下新建一个文件夹http(所有请求都放在这个文件夹里面)
在http下新建文件index.ts
在index.ts中写:

 

  1. import axios from 'axios'
  2. import UserDto from '../class/UserDto'
  3. //查询
  4. export const getList = (req: UserDto) => {
  5.     return axios.post("/api/list",req)
  6. }
  7. //新增
  8. export const add = (req: {}) => {
  9.     return axios.post("/api/add",req)
  10. }
  11. //修改
  12. export const edit = (req: {}) => {
  13.     return axios.post("/api/edit",req)
  14. }
  15. //删除
  16. export const del = (ids: string) => {
  17.     return axios.get("/api/del?ids="+ids)
  18. }


在class文件夹下新建文件:UserDto.ts

  1. export default class UserDto{        //列表分页参数传到后端
  2.     keyWord: string = ""
  3.     PageIndex: number = 1
  4.     PageSize: number = 10
  5. }


修改HomePage.vue
增加:
导入UserDto:import UserDto from '../class/UserDto';
导入getList:import {getList} from '../http';

  1. let userDto = ref<UserDto>(new UserDto())
  2. const load = async()=>{
  3.     console.log(await getList(userDto.value))
  4. }

实现页面加载时请求数据
import { ref } from 'vue'改为import { ref,onMounted } from 'vue'  //定义关键字
增加:

  1. onMounted(async () => {        //在页面加载时执行load方法
  2.     await load()
  3. })


运行代码,F12显示跨域问题

---------------------------------------------------------解决跨域问题------------------------------------------------------
浏览器显示CORS问题,原因是前端IP和后端IP不匹配导致,浏览器出于同源策略的安全性校验不允许直接访问资源,则会返回跨域错误
解决:通过代理解决
在vite.config.ts文件中修改server配置:

  1. server:{
  2.     open: true,     //自动打开浏览器
  3.     proxy:{
  4.       '/api':{
  5.         target:"http://localhost:5173",
  6.         changeOrigin:true,
  7.         rewrite(path){
  8.           return path.replace(/^\/api/,'')
  9.         }
  10.       }
  11.     }
  12.   }


在index.ts中修改接口:
http://localhost:5173改为/api

-----------------------------------------------------------列表页数据联调-------------------------------------------------
HomePage.vue增加:

const tableData = ref<any[]>([])    //把默认数据改为读接口数据(定义ref响应式变量,any类型数组)

修改:

  1. const load = async () => {
  2.     let data = (await getList(userDto.value)).data        //将接口数据放入变量data
  3.     tableData.value = data.res        //接口数据给到table表格
  4.     total.value = data.total        //total数据也给到表格
  5. }

实现搜索功能:
修改:

  1. const enterSearch = async () => {
  2.     userDto.value.keyWord = SearchVal.value        //将搜索框中的值传入userDto.value.KeyWord作为条件
  3.     await load()    //重新请求
  4. }

实现删除功能:
el-table标签中增加ref="multipleTableRef"
定义:

const multipleTableRef = ref()


导入删除方法:

import {getList} from '../http'改为import {getList,del} from '../http'


修改删除方法:

  1. const onDel = async() => {
  2.     let rows = multipleTableRef.value?.getSelectionRows() as Array<User>    //获取到复选框选中的数据
  3.     if(rows.length > 0){    //如果选中的值大于0
  4.         console.log(rows.map(item => {return `'${item.id}'`}).join(","))
  5.         //在${item.id}外层加一个单引号是为了序列化成字符串,结果示例:'a','b','c',传到后端放在in查询里面
  6.         let res = (await del(rows.map(item => {return `'${item.id}'`}).join(","))).data
  7.         if(res){
  8.             ElMessage.success("删除成功!")
  9.             await load()
  10.         }else{
  11.             ElMessage.error("删除失败!")
  12.         }
  13.     }else{
  14.         ElMessage.waring("请选中需要删除的行!")
  15.     }
  16. }

实现分页效果:
修改currentChange方法:

  1. const currentChange = async (val: number) => {
  2.     userDto.value.PageIndex = val
  3.     await load()
  4. }


编辑页表单验证:
add.vue中el-form增加:
:model="form" label-width="60px" ref="ruleFormRef"   用于获取表单
导入用于表单验证的类型:

import {FormInstance,FormRules} from 'element-plus'


获取表单对象:

const ruleFormRef = ref<FormInstance>()


验证规则:

  1. const rules = reactive<FormRules>({
  2.     date:[{
  3.         type: 'date',
  4.         required: true,
  5.         message: '请选择一个时间',
  6.         trigger: 'change',
  7.     }],
  8.     name:[{
  9.         required: true, message: '请输入名称', trigger: 'blur'
  10.     }],
  11.     address:[{
  12.         required: true, message: '请输入地址', trigger: 'blur'
  13.     }],
  14.     order:[
  15.         {required: true, message: '请输入一个序号'},
  16.         {type: 'number', message: '该字段必须是数字'}
  17.     ]
  18. })

修改import{...}from 'vue'中增加reactive

在el-form中增加:
:rules="rules"

在Cancel与Confirm按钮中点击事件增加参数ruleFormRef(表单对象)
导入添加和修改方法:

import {add,edit} from '../http'


增加closeAdd与save方法:

  1. const emits = defineEmits(["closeAdd","success"])
  2. const closeAdd = async (formEl: FormInstance | undefined) => {
  3.     if(!formEl) return
  4.     formEl.resetFields()    //重置表单
  5.     emits("closeAdd")
  6. }
  7. const save = async (formEl: FormInstance | undefined) => {
  8.     if(!formEl) return
  9.     await formEl.validate((valid, fields) => {
  10.         if(valid){        //如果表单校验成功,则执行修改或者添加操作
  11.             if(form.value.id){        //如果id存在,执行修改方法
  12.                 edit(form.value).then(function (res){
  13.                     if(res.data){
  14.                         emits("success","修改成功!")
  15.                     }
  16.                 })
  17.             } else {        //如果id不存在,执行添加方法
  18.                 add(form.value).then(function (res){
  19.                     if(res.data){
  20.                         emits("success","添加成功!")
  21.                     }
  22.                 })
  23.             }
  24.         }else{
  25.             console.log('error submit!', fields)
  26.         }
  27.     })
  28. }


修改HomePage.vue中success方法:

  1. const success = async (message: string) => {
  2.     isShow.value = false
  3.     info.value = new User()
  4.     ElMessage.success(message)
  5.     await load()
  6. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/119078
推荐阅读
相关标签
  

闽ICP备14008679号