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和端口,以及启动后是否默认打开浏览器

server:{
host:"127.0.0.1",
port:3001,
open:true
}
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:

<template>
    <div>0000</div>
</template>

TestPage.vue:
<template>
    <div>1111</div>
</template>


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

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


router文件夹下index.ts配置

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

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

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


在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文件中导入:

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


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

AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
Components({
      resolvers: [ElementPlusResolver()],
    }),


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

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

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

import * as ElementPlusIconsVue from '@element-plus/icons-vue'

const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}


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

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

<el-button :icon="Search" circle />
<el-button type="primary" :icon="Edit" circle />
还要加入下面的代码
<script lang="ts" setup>
import {
  Check,
  Delete,
  Edit,
  Message,
  Search,
  Star,
} from '@element-plus/icons-vue'
</script>


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

"moduleResolution": "Node",
"noUnusedLocals": false,


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

HomePage.vue增加:

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

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

.container{        //居中
  margin: 100px auto;
  width: 50%;
}
.table{            //表格间距等
  margin: 10px 0;
}

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

<el-row>
        <el-col :span="12">
          <el-input v-model="SearchVal" placeholder="Please input" class="input-with-select" @keyup.enter="enterSearch">
            <template #append>
              <el-button :icon="Search" @click="enterSearch"></el-button>
            </template>
          </el-input>
        </el-col>
        <el-col :span="12">
          <el-button type="primary" @click="openAdd">add</el-button>
          <el-button type="danger" @click="onDel">delete</el-button>
        </el-col>
      </el-row>

script标签增加:

import { ref } from 'vue';
import { Search } from '@element-plus/icons-vue';
const SearchVal = ref("")
const enterSearch=()=>{

}

const onDel=()=>{

}

const openAdd=()=>{

}


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

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


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

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


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

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

const handleDelete=(index: number, row: any)=>{
  console.log(index,row)
}

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

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


实现:

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


每页数据:

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


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

<template>
    <el-dialog v-model="dialogVisible" title="新增" width="30%">
        <el-form>
            <el-form-item label="时间" prop="date">
                <el-date-picker v-model="form.date" type="date" placeholder="请选择一个时间" :disabled-date="disablesDate"></el-date-picker>
            </el-form-item>
            <el-form-item label="名称" prop="name">
                <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="地址" prop="address">
                <el-input v-model="form.address"></el-input>
            </el-form-item>
            <el-form-item label="排序" prop="order">
                <el-input v-model.number="form.order"></el-input>
            </el-form-item>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="closeAdd()">Cancel</el-button>
                <el-button type="primary" @click="save()">Confirm</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue'       //导入ref
const dialogVisible = ref(false)        //控制显示与隐藏,默认不显示
const form = ref()
const disablesDate = (time: any) =>{
//最大时间,从今天开始,只能选今天及以后的时间
    const _maxTime = Date.now() - 24 * 60 * 60 * 1000 * 1
    return time.getTime() <= _maxTime
}

const closeAdd = () =>{

}

const save = () =>{
    
}

</script>

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

export default class User{      //导出一个默认User类
    id: string = ""
    date: string = ""
    name: string = ""
    address: string = ""
    order: number = 0
}

add.vue文件修改:

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


定义一个表单:

const form: Ref<User> = ref<User>({            //声明form是User类型
    id: "",
    date: "",
    name: "",
    address: "",
    order: 0
})


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

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


导入add和User:

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


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

const isShow = ref(false)

数据来源:

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


修改与删除控制:

const handleEdit=(index: number, row: User)=>{        //row:数据类型
  console.log(index,row)
  info.value = row        //编辑时赋值
  isShow.value = true    //点击编辑时修改为显示
}
const handleDelete=(index: number, row: User)=>{
  console.log(index,row)
}
const openAdd=()=>{        //添加时也显示
  isShow.value = true
}


运行测试,点击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

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


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

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


修改closeAdd事件:

const closeAdd = () => {
    emits("closeAdd")        //执行closeAdd事件
}


修改save事件:

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

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

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


将事件绑定到弹窗,修改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默认接口,改为:

 

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
//极简API接口,MapGet:访问方式
app.MapGet("/test", () =>
{
    return "ok";
});
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内容:

 

public class User
{
    [SugarColumn(IsPrimaryKey = true)]      //设置为主键
    public string Id { get; set; }
    public string Name { get; set; }
    public DateTime Date { get; set; }
    public string Address { get; set; }
    public int Order { get; set; }
}

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


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

public class SqlSugarHelper
{
    public static SqlSugarScope Db = new SqlSugarScope(new ConnectionConfig()
    {
        ConnectionString = "server=127.0.0.1;uid=root;pwd=admin;database=myDatabase",
        DbType = DbType.MySql,//设置数据库类型(我用的MySQL,根据自己的需要修改)     
        IsAutoCloseConnection = true,//自动释放数据务,如果存在事务,在事务结束后释放     
        InitKeyType = InitKeyType.Attribute //从实体特性中读取主键自增列信息
    },
    db =>
    {
        //打印sql日志,调试阶段可以开着,方便调试
        db.Aop.OnLogExecuting = (sql, pars) =>
        {
            Console.WriteLine(sql);
        };
    }
    );


    //初始化数据库
    public static string InitDateBase()
    {
        try
        {
            //创建数据库
            Db.DbMaintenance.CreateDatabase();
            //初始化数据表,如果没有则创建
            string nspace = "api.Model";        //过滤,表示只使用api.Model下的类(User)
            //LoadFrom可以加载AppContext.BaseDirectory程序集下的api.dll文件;GetTypes获取dll文件下的所有类;使用where过滤,确保拿到的是api.Model下的文件
            Type[] ass = Assembly.LoadFrom(AppContext.BaseDirectory + "api.dll").GetTypes().Where(p => p.Namespace == nspace).ToArray();
            Db.CodeFirst.SetStringDefaultLength(200).InitTables(ass);       //初始化table
            //添加数据前清空数据
            Db.Deleteable<User>().ExecuteCommand();

            //添加模拟数据
            List<User> list = new List<User>();
            for (int i = 1; i <= 5; i++)
            {
                list.Add(new User()
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = "Tom" + i,
                    Date = DateTime.Now,
                    Address = "No.  189, Grove St, Los Angeles",
                    Order = i
                });
            }

            for (int i = 6; i <= 10; i++)
            {
                list.Add(new User()
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = "Tom" + i,
                    Date = DateTime.Now,
                    Address = "No.  129, Grove St, Los Angeles",
                    Order = i
                });
            }

            for (int i = 11; i <= 30; i++)
            {
                list.Add(new User()
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = "Tom" + i,
                    Date = DateTime.Now,
                    Address = "No.  87, Grove St, Los Angeles",
                    Order = i
                });
            }
            //添加到表中
            Db.Insertable(list).ExecuteCommand();
            return "ok";
        }
        catch(Exception ex)
        {
            return ex.Message;
        }
    }

}



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

public class Model
{
    public string KeyWord { get; set; }     //关键字查询
    public int PageIndex { get; set; }      //分页
    public int PageSize { get; set; }
    public int Total { get; set; }      //分页总数
}

//对结果包装
public class Result
{
    public int Total { get; set; }
    public object Res { get; set; }
}

//添加的请求参数
public class AddReq
{
    public string Name { get; set; }
    public DateTime Date { get; set; }
    public string Address { get; set; }
    public int Order { get; set; }
}

写查询方法:

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

写添加方法:

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

写修改方法:

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

//删除方法

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


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

app.MapGet("/codefirst", () =>
{
    return SqlSugarHelper.InitDateBase();
});
app.MapPost("/list", (Model req) =>
{
    return SqlSugarHelper.GetUsers(req);
});
app.MapPost("/add", (AddReq req) =>
{
    return SqlSugarHelper.Add(req);
});
app.MapPost("/edit", (User req) =>
{
    return SqlSugarHelper.Edit(req);
});
app.MapGet("/del", (string ids) =>
{
    return SqlSugarHelper.Del(ids);
});

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

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

安装命令:
pnpm install axios

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

 

import axios from 'axios'
import UserDto from '../class/UserDto'
//查询
export const getList = (req: UserDto) => {
    return axios.post("/api/list",req)
}
//新增
export const add = (req: {}) => {
    return axios.post("/api/add",req)
}
//修改
export const edit = (req: {}) => {
    return axios.post("/api/edit",req)
}
//删除
export const del = (ids: string) => {
    return axios.get("/api/del?ids="+ids)
}


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

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


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

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

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

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


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

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

server:{
    open: true,     //自动打开浏览器
    proxy:{
      '/api':{
        target:"http://localhost:5173",
        changeOrigin:true,
        rewrite(path){
          return path.replace(/^\/api/,'')
        }
      }
    }
  }


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

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

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

修改:

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

实现搜索功能:
修改:

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

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

const multipleTableRef = ref()


导入删除方法:

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


修改删除方法:

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

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

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


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

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


获取表单对象:

const ruleFormRef = ref<FormInstance>()


验证规则:

const rules = reactive<FormRules>({
    date:[{
        type: 'date',
        required: true,
        message: '请选择一个时间',
        trigger: 'change',
    }],
    name:[{
        required: true, message: '请输入名称', trigger: 'blur'
    }],
    address:[{
        required: true, message: '请输入地址', trigger: 'blur'
    }],
    order:[
        {required: true, message: '请输入一个序号'},
        {type: 'number', message: '该字段必须是数字'}
    ]
})

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

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

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

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


增加closeAdd与save方法:

const emits = defineEmits(["closeAdd","success"])
const closeAdd = async (formEl: FormInstance | undefined) => {
    if(!formEl) return
    formEl.resetFields()    //重置表单
    emits("closeAdd")
}
const save = async (formEl: FormInstance | undefined) => {
    if(!formEl) return
    await formEl.validate((valid, fields) => {
        if(valid){        //如果表单校验成功,则执行修改或者添加操作
            if(form.value.id){        //如果id存在,执行修改方法
                edit(form.value).then(function (res){
                    if(res.data){
                        emits("success","修改成功!")
                    }
                })
            } else {        //如果id不存在,执行添加方法
                add(form.value).then(function (res){
                    if(res.data){
                        emits("success","添加成功!")
                    }
                })
            }
        }else{
            console.log('error submit!', fields)
        }
    })
}


修改HomePage.vue中success方法:

const success = async (message: string) => {
    isShow.value = false
    info.value = new User()
    ElMessage.success(message)
    await load()
}
  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值