【2025新版】十分钟学会ElementPlus UI框架,1小时精通vue项目实战 ECharts趋势图,Vue3前端视频教程,借助AI人工智能快速入门web网站实战课程和vue后台管理系统
通常后台给我们返回的商品数据是这样的商品状态后台不直接给我们返回文本,而是数字,不同数字代表不同状态。我们如果直接显示,会把数字显示出来,这样肯定是不友好的。所以我们要把数字转换为对应的状态文本。就定义一个函数。来实现转换即可。下面是函数定义和使用。显示效果如下。
现在我们假设你没有任何编程基础,不会任何前端知识,完全是一个新手小白。
在之前想学习前端并开发出一款自己的项目至少要花费1个月的时间,现在我们有了AI人工智能帮我们学习前端,开发项目。
现在你完全可以利用30分钟就可以开发一款属于自己的前端网站,所以抽出你宝贵的30分钟,跟着石头哥从代码小白门外汉,30分钟开发一款属于自己的vue管理系统吧。
技能点
跟着石头哥学完,你可以精通以下技能
- vscode开发工具
- 通用管理后台系统
- vue3知识和项目实战
- Elementplus,elementUI框架
- Echarts可视化
- vite+vue3快速搭建项目
- vue-router
- pinia
- axios网络库
- api接口文档
- apifox工具调试接口
- 简单学会使用node搭建后台服务器
- 搜索,分页,登录,退出功能
- 添加,修改,删除,查询数据(增删改查)
能学到什么
- 零基础小白快速实战入门
- vue3+AI人工智能自动生成代码
- vue3项目实战
- 可以做为毕业设计
- 可以作为公司项目,真实接口请求,实战案例
先给大家看下项目效果图
我们通过两个实战案例来带大家学习相应的知识
- 第一个案例完全由ai生成的代码,教大家利用ai10分钟零基础开发一款vue3实战项目为那些想快速学习的同学准备。
- 第二个案例由石头哥带着大家动手写一款vue3+element+ecahrts通用管理后台系统,为那些想自己独立写项目的同学准备。
1,登录页

另外一种登录页
2,管理后台首页和用户管理页

接入真实数据的管理后台
3,商品管理页

4,订单管理页
分线上订单
点击编辑有弹窗
有分页功能
线下订单有搜索功能
我们可以搜索订单
可以搜索课后名
还可以根据订单状态筛选订单
5,ECharts趋势图
折线图
柱状对比图

当然还有更多炫酷的效果



跟着石头哥学完,上面的效果你都可以快速的实现
6,用户分权限
可以实现动态导航菜单栏,根据不同的用户权限,显示不同的菜单
如超级管理员可以管理所有功能,可以修改用户信息
而普通管理员就无法管理用户信息
7,接口文档
同时给大家提供真实后台数据的接口文档
一,安装开发软件并接入AI
0,为什么要使用AI
- 节省时间:同样的知识点我们都文档可能要1个小时才能学会,并且有时候文档比较乱的话,可能自己根本找不到对应的文档。如果用ai基本上2分钟就可以让ai帮我们找到对应的知识点,并提供demo。
- ai可以自动生成代码:在接下来的学习中,你将会深刻体会到ai生成代码的便利之处。只要你跟着石头哥认真学习,基本传统1个小时开发的页面,用ai的话,1分钟就可以完成。
- ai可以解释代码:我们如果要去读别人的代码,可能比较费劲,因为有些地方的代码你根本就没有学过,这个时候让ai帮我们做详细的解释。并且可以让ai给我们提供demo
- ai可以解答一些代码无关的问题:比如我们想知道vscode的一些快捷键,就可以直接问ai。
知道了ai这么多的好处,我们接下来就跟着石头哥
10分钟入门elementplus
1小时精通vue3后台管理系统吧。
1,下载vscode开发者工具
我们既然要开发前端网站,肯定要先选一款得心应手的开发者工具了。这里我们使用的是visual studio code,就是我们俗称的vscode。
下载很简单,自己百度下vscode去下载即可。
我们下载安装好vscode开发者工具后,最好汉化一些,这样方便我们新手学习。其实汉化也很简单,如下图。
安装好插件后记得重启下开发者工具
2,接入AI人工智能辅助学习编码
当前是Ai的时代,当然我们编码也离不开AI的辅助。国内做的比较好的就是通义灵码了。接下来教大家安装使用
vscode里安装通义灵码
如下图所示,安装也很方便。

安装完记得重启下Visual Studio Code,安装成功后点击打开如下。
这里也是一样的,记得登录以后再使用。我们接下来开发学习中,就会借助AI来提升我们的学习和开发效率。
3,安装vue3和elementplus插件
我们开发前端网站,用的是当前主流的vue3+Elementplus,所以我们这里再安装一些相关插件,可以做相关代码提示,提升开发效率
3-1,vue3-snippets-for-vscode
我们在编写的时候可以使用vue3-snippets-for-vscode来进行代码提示方便我们快速的智能的编写代码,去插件市场搜索vue3然后安装即可。
3-2,Vetur

3-3,Vue - Official
vue官方出品的插件
Vue - Official 插件(之前称为 Volar)是 Visual Studio Code 中专为 Vue.js 开发者设计的一个功能强大的插件。它为 Vue 3 提供了全面的支持,并且逐渐成为 Vue 3 开发的标准插件之一
3-4,安装elementPlus代码提示器
我们在编写的时候可以使用Element-Plus-doc来进行代码提示,去插件市场搜索Element-Plus然后安装即可。
然后我们在编写element代码的时候就可以智能提示了
也可以再安装一个Element Plus Snippet,它使用Element Plus的代码片段(Snippet)来加快开发速度。
使用方法: 键盘打出el开通的,就可以快速的实现element相关代码片段。
二,安装node和npm
我们的vue3项目是基于node,并且依赖是通过npm来安装的。所以我们先要安装node
1,下载node安装包
我们去node官网安装最新的即可
但是node官网是国外的网站,有时候访问比较慢,所以我给大家准备好了node安装包,评论区留言,石头哥可以提供给你。给大家准备的是最新版的20.17,如果你学习的时候比石头哥的版本还新,可以自行下载最新版。
2,安装node
安装很简单,双击然后一直下一步即可,所有的都保持默认就行。
两个注意点:
1,一定要保持默认安装目录
2,需要注意的就是要选中Add to PATH
然后等待安装完成即可。
我们前面安装好node以后,最好重启下电脑。
3,检验是否安装成功
安装完成后我们就进入vscode打开终端,用命令行试试是否安装成功
在终端中输入命令行node -v
能打印出版本号,就代表安装node成功了。
4,检验npm命令行
接下来再检验下npm命令行。
npm -v
如果也能打印出版本,代表成功。
注意:有时候用的同学使用 npm -v命令时会出现一个错误,显示‘npm’不是内部或外部命令,也不是可运行的程序或批处理文件
一般跟着石头哥安装node,不会出现这个问题,万一出现了,就自己百度下node配置环境变量
5,配置国内npm镜像
因为node是国外网站,有的同学使用npm加载依赖的时候可能会特别慢,这个时候把npm的镜像设置为国内的,这样加载依赖的时候就会比较快了。
npm查看镜像和设置国内镜像
查看当前镜像 npm get registry设置国内阿里云镜像
npm config set registry https://registry.npmmirror.com/

当然了,你如果不知道npm镜像是啥,可以直接问AI

当然,如果觉得ai解释的太官方,可以通俗些
到这里所有准备工作就做好了,接下来就要创建vue3+elementplus项目了。
三,创建vue3项目
1,创建新的vue3项目
我们先在桌面创建一个空白文件夹最好是英文或者拼音。然后用vscode去打开这个文件夹。
打开后如下图
然后我们就可以通过vite来创建vue3项目了。
2,使用vite创建vue3项目
同样是在终端里输入以下npm命令来创建vue3项目。
来到vscode终端
然后执行 npm create vite
Ok to proceed? (y) 输入y即可
然后会提示你输入项目名称之后,我这里设置的是 qcl 你也可以自己随意设置,但要是拼音或者英文。
回车之后,出现选择框架的提示,我们选择【vue】回车
之后根据你的编码习惯或需要,选择【ts】或者【js】,点回车。
我们这里选的是JavaScript
vite非常贴心,按照对应的提示,敲入对应的命令行即可
然后等待npm安装所需要的依赖,可能会有点慢,耐心等待即可。
安装好依赖如下
3,vscode里运行vue3项目

我们前面通过vite已经快捷的创建了一个vue3项目,然后就是启动运行项目了。
运行项目的命令行其实vite已经提示我们了,这也是我喜欢用vite构建vue项目的原因。太贴心了。
终端命令行执行 npm run dev
运行成功后就可以通过下面链接打开vue网站了

到此我们自己的第一个vue3项目就创建好了,接下来跟着石头哥愉快的开发吧。如果你只是想学习vue3的基本知识和语法,到这里就可以在这个框架里敲代码学习了。
假如你根本不知道vite是啥,可以问ai
当然也可以再通俗些
四,引入element-plus
先给大家看几个vue3结合Element-plus实现的效果图
网站登录页
商品管理后台
1,命令行安装element-plus

如果你重新打开了终端,记得 cd到你的源码目录里,
然后同样是要终端命令行里执行以下代码
npm install element-plus @element-plus/icons-vue
依然是耐心等待安装element
安装完成以后如下
2,配置引入element plus
在main.js里做如下操作
对应代码贴出来给到大家
// ElementPlus相关配置
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
createApp(App).use(ElementPlus).mount('#app')
3,编写ElementPlus代码
我们可以去ElementPlus官网查看对应的样式或者标签,写到我们的项目即可。
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
然后就可以看到我们正常的显示了ElementPlus的button按钮。
接下来我们就可以愉快的开发管理后台了。
4,让AI教我们引入Element
我前面已经教大家引入了elementplus,当然我们也可以让Ai教我们。
可以看到ai也会给我们列出引入elementplus的详细步骤,和石头哥的有点出入,不过这个没有关系,因为引入elementplus的方式有很多种。用那种方式都可以的。接下来我再带着大家用ai的方式引入下elementplus。
1,我们使用npm

2,在main.js里配置,主要下面三行

我们初学阶段,不用做按需引入。
使用一个按钮,看看是否引入成功
在app.vue里使用试试
记得使用npm run dev重启下网站
然后进入网站可以看到按钮,这就代表引入成功了。
五,让Ai教我们学习Element基础知识
按我们传统的学习方式,是要去到Element官网一点点的学习的。但是我们现在有Ai,也假设你没有时间去看官网的文档。
那么接下来就让Ai教我们学习Element基础知识吧,我们把一些常用的给大家用ai讲一下,并且在代码中使用下。
1,按钮
提问词:教我使用elementplus里的按钮
来给大家看看ai讲的有多么详细
我们使用下ai的代码,并看下运行起来的效果图
当然你可以让ai解释下它生成的代码,选中代码,然后右键点击通义灵码,再点击解释代码。
可以看到ai的解释
可以点击更详细
我这里给大家演示了如何让ai给我们解释代码,后面学习中,大家有不懂的地方,直接让ai解释就行的。
2,输入框
提问词:教我使用elementplus里的输入框
我截取ai回答的一部分。
可以看出element里的输入框还是很美观的
3,单选框
提问词:我已引入elementplus教我使用elementplus里的单选框
来看下ai的回答

我们使用ai给的代码,看下效果
4,多选框
提问词:我已引入elementplus教我使用elementplus里的多选框
来看看ai的回答
以及给出的示例代码
效果图如下
5,下拉框
提问词:教我使用elementplus里的下拉框
可以看到ai给出了示例代码
我们直接使用ai的代码,看下效果图
也有多选的下拉框
你先使用ai的代码,然后不懂的地方让ai给解释下。就可以快速的掌握下拉框了。
6,日期选择器
提问词:教我使用elementplus里的日期选择器
可以看出ai给出了各种时间选择器。
我们以其中一个为例看下效果。
效果图
是不是感觉ai给出的代码很高大上。当然你也可以让ai一行行的给你解释下这些代码。
7,提示框
提问词:教我使用elementplus里的提示框
ai给出的代码,我们这里稍微整合下
<template>
<div>
<el-button type="success" @click="showConfirm">点击弹出提示框</el-button>
</div>
</template>
<script setup>
import { ElMessage } from 'element-plus';
function showConfirm() {
ElMessage({
showClose: true,
message: '这是一个消息提示框',
type: 'success',
});
}
</script>
看下效果,点击按钮弹出如下提示框。
8,进度条
提问词:教我使用elementplus里的进度条
通过ai的回答,我们可以看到进度条分很多种
可以看到如下几种进度条
代码贴给大家
<template>
<el-progress :percentage="percentage"></el-progress>
<el-progress type="circle" :percentage="percentage"></el-progress>
<el-progress :percentage="percentage" status="success"></el-progress>
<el-progress :percentage="percentage" status="exception"></el-progress>
<el-progress :percentage="percentage" status="warning"></el-progress>
<!-- 自定义进度条颜色 -->
<el-progress :percentage="percentage" :color="customColor" />
</template>
<script setup>
import { ref } from 'vue';
const percentage = ref(50); // 初始百分比值
const customColor = ref('#cccc00')
</script>
9,表格
提问词:教我简单的使用elementplus里的表格
看下ai的回答
再看下效果图
10,分页
我们前面学完表格了,当然我们也可以让ai显示分页表格
提问词:再写一个可以分页的表格
先看下ai生成的效果图

ai真是超预期实现了我的需求,不仅仅给分页了,还实现了按照日期排序功能。这个代码值得珍藏,后面再有类似需求,直接复制这段代码即可。
<template>
<div>
<el-table
:data="currentTableData"
style="width: 100%"
@row-click="handleRowClick"
>
<el-table-column prop="date" label="日期" width="180" sortable></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
<el-pagination
background
layout="prev, pager, next"
:total="totalRows"
:page-size="pageSize"
:current-page="currentPage"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
// 示例数据
const tableData = [
{ date: '2024-09-05', name: '张三', address: '上海市' },
{ date: '2024-09-04', name: '李四', address: '北京市' },
{ date: '2024-09-03', name: '王五', address: '广州市' },
{ date: '2024-09-02', name: '赵六', address: '深圳市' },
{ date: '2024-09-01', name: '孙七', address: '杭州市' },
{ date: '2024-08-31', name: '周八', address: '南京市' },
{ date: '2024-08-30', name: '吴九', address: '成都市' },
{ date: '2024-08-29', name: '郑十', address: '武汉市' },
{ date: '2024-08-28', name: '钱十一', address: '长沙市' },
{ date: '2024-08-27', name: '孙十二', address: '重庆市' },
];
// 分页相关变量
const currentPage = ref(1);
const pageSize = ref(5);
const totalRows = ref(tableData.length);
// 计算当前页面的数据
const currentTableData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return tableData.slice(start, end);
});
// 处理分页变化
const handleCurrentChange = (val) => {
currentPage.value = val;
};
// 处理行点击事件
const handleRowClick = (row) => {
console.log('Clicked row data:', row);
};
</script>
<style scoped>
/* 这里可以添加一些自定义样式 */
</style>
代码有点多,里面新知识也比较多可以让ai给我们解释下代码。
11,表单
表单分很多种,我们先让ai帮我们实现一个最基础的登录表单
提问词:教我简单使用elementplus里的登录表单
可以看出ai帮我们生成了代码,并且也解释了代码

效果图如下
代码贴给大家,大家可以让ai再一行行的解释
<template>
<div class="login-form-container">
<el-form :model="loginForm" :rules="loginRules" ref="loginFormRef" label-width="80px">
<h2>登录</h2>
<el-form-item label="用户名" prop="username">
<el-input v-model="loginForm.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="loginForm.password" type="password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit('loginFormRef')">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { ElMessage } from 'element-plus';
// 登录表单数据
const loginForm = reactive({
username: '',
password: ''
});
// 表单验证规则
const loginRules = reactive({
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
});
// 表单引用
const loginFormRef = ref(null);
// 提交表单
const handleSubmit = (formName) => {
const form = loginFormRef.value;
form.validate((valid) => {
if (valid) {
// 提交表单逻辑
ElMessage.success('登录成功!');
} else {
console.log('error submit!!');
return false;
}
});
};
</script>
<style scoped>
.login-form-container {
width: 300px;
padding: 20px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}
.login-form-container h2 {
text-align: center;
margin-bottom: 20px;
}
</style>
12,对话框
提问词:教我使用elementplus里的对话框
可以看下最简单的对话框
复杂的对话框
我把第二个复杂的对话框代码贴给大家,然后教下大家让ai给我们解释代码,并修改下代码
<template>
<el-button @click="openDialog">打开对话框</el-button>
<el-dialog v-model="dialogVisible" title="提示">
<el-form label-position="left" inline class="demo-form-inline">
<el-form-item label="用户名">
<el-input v-model="username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="password" placeholder="请输入密码" show-password></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmDialog">登 录</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { ref } from 'vue';
const dialogVisible = ref(false);
const username = ref('');
const password = ref('');
const openDialog = () => {
dialogVisible.value = true;
};
const confirmDialog = () => {
dialogVisible.value = false;
console.log('用户名:', username.value);
console.log('密码:', password.value);
};
</script>
先让ai解释代码
可以看到这个案例把我们之前学过的知识点基本上都用到了。并且ai详细的给我们解释了代码。
我们现在让ai给我们改代码
提问词:把账号密码分两行显示,不要显示在一行
然后使用ai的代码可以看到,分两行显示了
所以我们让ai改代码的步骤就是先让ai解释代码然后再提出自己的要求,让ai改代码
13,导航–Menu菜单
提问词:教我简单使用elementplus里左侧的导航
- ai回答:
Element Plus 中的导航组件主要包括 el-menu 和 el-sub-menu 或 el-menu-item。在 Element Plus 中,创建一个左侧导航通常涉及到使用 el-menu 组件来构建菜单结构
同样也有代码解释
看下ai生成的代码效果图
还有二级菜单导航栏
这个知识点后面会经常用到,代码贴给大家,不懂的地方可以让ai重点解释。
<template>
<el-menu class="el-menu-vertical-demo" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"
unique-opened>
<el-menu-item index="/">
<template #title>
<span>首页</span>
</template>
</el-menu-item>
<el-sub-menu index="/products">
<template #title>
<span>产品</span>
</template>
<el-menu-item index="/products/new">新产品</el-menu-item>
<el-menu-item index="/products/old">旧产品</el-menu-item>
</el-sub-menu>
<el-menu-item index="/about">
<template #title>
<span>关于我们</span>
</template>
</el-menu-item>
</el-menu>
</template>
<script setup>
</script>
<style scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
</style>
我们后面会结合实战案例教大家实现一个完整的管理后台网站。
14,Tabs标签页

我们前面学完导航里的menu菜单,接下来再学习下标签
提问词:教我使用elementplus里的标签页
看下ai回答
使用ai的代码看下效果图,可以看到点击不同的标签,显示不同的内容。
当然如果你觉得简陋,可以让ai生成的更美观些。
来看下ai给我们做的美化,是不是要美观很多了。
15,轮播图
先看下轮播图的效果
ai提问词:教我使用elementplus里的轮播图
这里ai生成的代码如下,但是我们使用的时候会报错,因为ai提供的图片链接不存在。

两个解决方案
1,去网上找网络图片
2,本地提供几个图片
都给大家演示下:
15-1,显示网络图片
网上找图片,右键,复制图片地址即可
放到我们的代码里,替换之前不能显示的图片
效果图如下
15-2,显示本地图片
在public目录下创建一个imgs目录,然后我们准备三张图片,放到imgs目录下。直接使用如下。
这样就可以显示本地轮播图了。
15-3,显示卡片样式轮播图
其实我们给轮播图设置一个属性,可以显示的高大上。
只需要设置type=“card”,如下图,是不是瞬间高大上了。
完整代码贴给大家,记得把图片替换成自己的。
<template>
<!-- 给下面div设置宽高 -->
<div style="width: 800px; height: 300px;">
<el-carousel height="300px" type="card">
<el-carousel-item v-for="item in images" :key="item.id">
<img :src="item.url" alt="" :style="{ width: '100%', height: '100%' }" />
</el-carousel-item>
</el-carousel>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 示例图片数据
const images = ref([
{ id: 1, url: '/imgs/1.jpg' },
{ id: 1, url: '/imgs/2.jpg' },
{ id: 1, url: '/imgs/3.jpg' }
]);
</script>
<style scoped>
/* 如果需要,可以在这里添加额外的样式 */
</style>
16,icon图标
其实element有给我们提供一些图标,可以直接使用的。接下来我们就让ai教下我们怎么使用。
提问词:教我使用elementplus里的icon图标
可以看出我们使用icon图标要先安装图标库element-plus/icons-vue,
ai也给出我们安装命令
npm install @element-plus/icons-vue
我们安装好以后,分两种方式使用
16-1,局部使用图标
在需要使用图标的页面里直接引入你需要的图标,如下图,我们使用搜索图标和编辑图标
页面显示效果,我们通过size设置图标大小。
16-2,全局注册图标
我们在main.js里全局注册图标,这样在任何页面就可以直接使用了。
到我们自己的main.js里做如下配置。
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 引入element
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
// 引入图标库
import * as ElIcons from '@element-plus/icons-vue';
const app = createApp(App);
// 挂载element
app.use(ElementPlus);
// 全局注册所有图标
for (const name in ElIcons) {
app.component(name, ElIcons[name]);
}
app.mount('#app');
这样我们在任何页面里直接使用任何我们想要的图标。直接使用即可。无需再次注册图标了。因为在main.js里已经全局注册过了。
如上图,你直接在注释里打出你想要使用的图标,ai就会自动帮你把对应的图标代码写出来。
到这里我们常用的element基础知识就讲完了,下一章就来带大家写一些综合性的案例。来进一步通过实战学习elementplus。
六,综合实战案例
我们正式下案例之前,把vue3自带的样式给注释或者删除掉。避免一些不必要的样式冲突。
1,登录页开发
我们学完基础,就先来让ai给我们开发一个登录页。我们向ai提问之前,把问题描述的越详细越好。
提问词:你是资深前端开发,现在用vue3和elementplus帮我开发一个登录页,页面背景是一个图片,登录区域是一个卡片有阴影,居于页面中间,里面有账号密码输入,页面尽量美观些
先来看下ai生成的效果图
可以看到,除了背景图没有显示出来以外,其他功能都给我们实现了,前后耗费不超过10秒。就快速的帮忙我们把登录页面写好了。是不是很高效。
我们接下来把背景图标设置为自己的就可以了。
再来看下效果图,一个可以直接实战使用的登录页是不是就写好了。
并且还带校验规则
输入信息错误还有弹窗提示
我先把完整代码贴出来给到大家,如果你的ai生成的代码不能运行,或者运行出来比较丑,可以直接使用石头哥的ai生成的这段代码。
<template>
<div class="login-container">
<img :src="backgroundImage" alt="Background" class="background-image" />
<el-card class="login-card" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);">
<div class="login-header">
<h2 class="login-title">登录</h2>
</div>
<el-form ref="loginFormRef" :model="loginForm" :rules="rules" label-width="80px">
<el-form-item label="账号" prop="username">
<el-input v-model="loginForm.username" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="loginForm.password" :type="password" show-password placeholder="请输入密码" @keyup.enter="handleLogin">
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleLogin">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
const backgroundImage = '/imgs/1.jpg'
const loginFormRef = ref(null)
const loginForm = reactive({
username: '',
password: ''
})
const showPassword = ref(false)
const rules = reactive({
username: [
{ required: true, message: '请输入账号', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
})
const handleLogin = () => {
loginFormRef.value.validate((valid) => {
if (valid) {
ElMessage.success('登录成功!')
// 进行实际的登录逻辑
} else {
ElMessage.error('请检查输入的信息')
}
})
}
onMounted(() => {
// 初始化操作
})
</script>
<style scoped>
.login-container {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.background-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.login-card {
width: 350px;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
text-align: center;
}
.login-header {
margin-bottom: 20px;
}
.login-title {
color: #333;
font-weight: bold;
margin-bottom: 10px;
}
.el-input {
margin-top: 10px;
}
.el-form-item {
margin-bottom: 15px;
}
.el-button {
width: 100%;
margin-top: 15px;
}
.el-switch {
margin-left: 10px;
}
</style>
是不是一个小案例,就基本上把我们前面学的基础知识基本上都用了一遍。当然代码里还有一些新的知识点,大家就可以让ai给我们解释自己不懂的地方
比如有的样式我们看不懂,直接让ai给我解释即可。
2,多页面开发
我们上面开发好登录页,可以在src下新建一个pages目录,专门用来放我们的页面。
在pages下创建一个Login.vue把上面的登录代码粘贴进来,这样一个正式项目的登录页就创建好了。
创建好,记得在app.vue里引入挂载一下
接下来我们要开发网站首页了,就是登录成功后会跳转到首页,所以提前在pages里创建一个Home.vue。
但是我们如何从登录页跳转到首页呢?
3,vue-router实现页面跳转
我们要想实现登录页跳转到首页,就需要用到vue-router了。还是老规矩,交给ai
提问词:你是资深前端开发,我的pages目录下现在有一个Login.vue页面和Home.vue页面,Login.vue用于登录,已经写好了,我想从Login.vue登录页跳转到Home.vue首页,请你使用vue-router帮我实现这个跳转功能,并配置好App.vue
可以看到ai帮我们生成的详细的步骤,并且还对步骤进行了总结
那我们跟着ai一步一步来
3-1,安装vue-router
如果vue项目在运行,就先ctrl+c然后输入y停止项目
再通过npm install vue-router 安装vue-router
3-2,创建路由配置文件
在 src下创建router 目录,然后在router目录下创建 index.js 文件,并配置路由。
把ai的代码复制到index.js里
3-3,在主应用main.js中引入路由
确保在 main.js 中引入路由并使用它。
3-4,在 Login.vue 中添加跳转逻辑
其实就是在我们Login.vue的登录成功函数里实现页面跳转
主要就是下面三行代码
- 通过import { useRouter } from 'vue-router’引入路由
- 通过const router = useRouter()获取router
- 通过router.push(‘/’)实现跳转到首页
3-5,Home.vue 页面随便写点内容

3-6,更新 App.vue
其实更新 App.vue里更新的代码很简单,
就是为了加入一个router-view
然后我们就去npm run dev重启下vue3项目,看看能不能跳转页面
我们先在网站地址后面加一个/login进入登录页
然后去点击下登录,看登录成功后会不会跳转到首页
可以看到登录后成功的跳转到了首页。
这里有一个问题,正常来说登录页才是我们页面的第一个页面,所以我们在路由配置中稍微改动下即可。
把登录页改为 /这样输入网站地址,就可以直接进入登录页,然后把首页改为 /home,同时登录页登录成功跳转的地方也要改动下。
把router.push(‘/’)改为router.push(‘/home’)就可以了。
再看下登录页的地址
然后点击登录跳转到首页
多页面和页面跳转的功能都实现了,接下来继续实现首页吧
4,首页的开发
页面准备好了,就先来让ai给我们生成页面代码吧。我们向ai提问之前,把问题描述的越详细越好。
提问词:你是资深前端开发,现在用vue3和elementplus帮我开发一个后台管理首页。后台管理首页是pages目录下的Home.vue,项目已经引入vue-router,Home.vue的path路径是/home,请在Home.vue页面的左侧开发一级导航目录包括 用户管理,商品管理,订单管理。只在订单管理目录下有二级菜单 线上订单,线下订单。页面右侧显示对应的导航页面内容,页面尽量美观些,Home.vue的左侧导航栏用深色主题
看下ai的回答还是一如既往的详细
由于element和vue-router我们已经配置过了,所以这里不再配置。直接看后面的步骤。
可以看到路由配置里给我们创建了很多二级页面,我们目前先看首页效果,所以这里在下一节再配置。
可以看到ai已经帮我们生成了首页的代码,我们直接导入使用即可
来看下效果图。是不是和我们正式的管理后台很像了。
接下来就开始开发二级页面
5,创建一级和二级页面并配置路由
我们在前面开发首页的时候,ai给我们生成了很多二级页面,虽然有对应代码,但是页面还是要我们自己创建的,无非页面名要用ai的。
可以看到我们要在pages目录下再创建四个页面
- UserManagement.vue 一级页面用户管理
- ProductManagement.vue 一级页面商品管理
- OnlineOrders.vue 二级页面线上订单
- OfflineOrders.vue 二级页面线下订单
我们就先创建这四个vue
我们router目录下的index.js配置好如下
import { createRouter, createWebHistory } from 'vue-router';
import Login from '../pages/Login.vue';
import Home from '../pages/Home.vue';
// 把一级和二级页面引入router
import UserManagement from '../pages/UserManagement.vue';
import ProductManagement from '../pages/ProductManagement.vue';
import OnlineOrders from '../pages/OnlineOrders.vue';
import OfflineOrders from '../pages/OfflineOrders.vue';
const routes = [
{
path: '/',
name: 'Login',
component: Login,
},
{
path: '/home',
name: 'Home',
component: Home,
children: [
{
path: 'user-management',
name: 'UserManagement',
component: UserManagement
},
{
path: 'product-management',
name: 'ProductManagement',
component: ProductManagement
},
{
path: 'order-management',
name: 'OrderManagement',
children: [
{
path: 'online-orders',
name: 'OnlineOrders',
component: OnlineOrders
},
{
path: 'offline-orders',
name: 'OfflineOrders',
component: OfflineOrders
}
]
}
]
}
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
然后导入ai生成的页面
1,一级页面:UserManagement.vue
2,一级页面:ProductManagement.vue
3,二级页面:OnlineOrders.vue
4,二级页面: OfflineOrders.vue
这样我们点击导航栏就可以加载对应的路径,显示对应的页面

到这里我们最基础的一个管理后台页面就搭建好了,目前有以下6个页面
6,用户管理页的开发
我们接下来就改造用户管理页,还记得我们前面学习分页的时候,有用到用户表格吗,其实我们在用户管理页放一个带分页功能的用户表格就行的。
提问词:你是资深前端开发,我已经用vue3和elementplus开发了一个Home.vue首页,首页左侧导航栏有一个一级导航栏 用户管理,右侧对应加载的页面是UserManagement.vue,请你在UserManagement.vue页面里帮我开发一个带分页的用户表格,模拟4页的数据出来,页面要尽量美观,表格宽度可以占满UserManagement.vue页面
先来看下ai生成代码的效果图
是不是很高大上啊。
我先把完整代码贴出来给到大家,如果你的ai生成的代码不能运行,或者运行出来比较丑,可以直接使用石头哥的ai生成的这段代码。
<template>
<div class="user-management">
<el-table
:data="filteredUsers"
style="width: 100%"
stripe
border
>
<el-table-column
type="index"
label="序号"
width="60"
/>
<el-table-column
prop="id"
label="ID"
width="80"
/>
<el-table-column
prop="name"
label="姓名"
width="120"
/>
<el-table-column
prop="email"
label="邮箱"
width="200"
/>
<el-table-column
prop="role"
label="角色"
width="120"
>
<template #default="{ row }">
<el-tag :type="row.role === '管理员' ? 'success' : 'warning'">{{ row.role }}</el-tag>
</template>
</el-table-column>
<el-table-column
prop="status"
label="状态"
width="120"
>
<template #default="{ row }">
<el-tag :type="row.status === '活跃' ? 'success' : 'danger'">{{ row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column
prop="created_at"
label="创建时间"
width="180"
/>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalUsers.length"
/>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
// 模拟数据
const totalUsers = [
{ id: 1, name: '张三', email: 'zhangsan@example.com', role: '管理员', status: '活跃', created_at: '2023-09-01' },
{ id: 2, name: '李四', email: 'lisi@example.com', role: '普通用户', status: '禁用', created_at: '2023-09-02' },
{ id: 3, name: '王五', email: 'wangwu@example.com', role: '管理员', status: '活跃', created_at: '2023-09-03' },
{ id: 4, name: '赵六', email: 'zhaoliu@example.com', role: '普通用户', status: '禁用', created_at: '2023-09-04' },
{ id: 5, name: '孙七', email: 'sunqi@example.com', role: '管理员', status: '活跃', created_at: '2023-09-05' },
{ id: 6, name: '周八', email: 'zhouba@example.com', role: '普通用户', status: '禁用', created_at: '2023-09-06' },
{ id: 7, name: '吴九', email: 'wujiu@example.com', role: '管理员', status: '活跃', created_at: '2023-09-07' },
{ id: 8, name: '郑十', email: 'zhengshi@example.com', role: '普通用户', status: '禁用', created_at: '2023-09-08' },
// 添加更多数据以模拟4页
...Array.from({ length: 120 }, (_, i) => ({
id: i + 9,
name: `用户${i + 9}`,
email: `user${i + 9}@example.com`,
role: i % 2 === 0 ? '管理员' : '普通用户',
status: i % 2 === 0 ? '活跃' : '禁用',
created_at: `2023-09-${i + 9}`
}))
];
// 分页参数
const currentPage = ref(1);
const pageSize = ref(10);
// 过滤后的数据
const filteredUsers = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return totalUsers.slice(start, end);
});
// 处理每页数量变化
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1;
};
// 处理当前页变化
const handleCurrentChange = (val) => {
currentPage.value = val;
};
</script>
<style scoped>
.user-management {
padding: 20px;
}
.el-table {
margin-bottom: 20px;
}
.el-pagination {
text-align: center;
}
</style>
7,商品管理页的开发
我们接下来就改造商品管理页
提问词:你是资深前端开发,我已经用vue3和elementplus开发了一个Home.vue首页,首页左侧导航栏有一个一级导航栏 商品管理,右侧对应加载的页面是ProductManagement.vue,请你在ProductManagement.vue页面里帮我开发一个带分页的商品表格,操作列有编辑,上架,下架,删除图标按钮。模拟4页的数据出来,页面要尽量美观,表格宽度可以占满页面
先来看下ai生成代码的效果图,比前面用户管理页还有好看
我先把完整代码贴出来给到大家,如果你的ai生成的代码不能运行,或者运行出来比较丑,可以直接使用石头哥的ai生成的这段代码。
<template>
<div class="product-management">
<el-table
:data="filteredProducts"
style="width: 100%"
stripe
border
>
<el-table-column
type="index"
label="序号"
width="60"
/>
<el-table-column
prop="id"
label="ID"
width="80"
/>
<el-table-column
prop="name"
label="名称"
width="200"
/>
<el-table-column
prop="category"
label="分类"
width="120"
/>
<el-table-column
prop="price"
label="价格"
width="120"
>
<template #default="{ row }">
{{ row.price }} 元
</template>
</el-table-column>
<el-table-column
prop="stock"
label="库存"
width="120"
/>
<el-table-column
prop="status"
label="状态"
width="120"
>
<template #default="{ row }">
<el-tag :type="row.status === '上架' ? 'success' : 'danger'">{{ row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="300"
>
<template #default="{ row }">
<el-button type="primary" size="small" icon="Edit" @click="handleEdit(row)"></el-button>
<el-button type="success" size="small" icon="Upload" @click="handlePublish(row)"></el-button>
<el-button type="warning" size="small" icon="Download" @click="handleUnpublish(row)"></el-button>
<el-button type="danger" size="small" icon="Delete" @click="handleDelete(row)"></el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalProducts.length"
/>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { ElMessage } from 'element-plus';
// 模拟数据
const totalProducts = [
{ id: 1, name: '商品1', category: '电子产品', price: 100, stock: 100, status: '上架' },
{ id: 2, name: '商品2', category: '家居用品', price: 200, stock: 50, status: '下架' },
{ id: 3, name: '商品3', category: '电子产品', price: 150, stock: 80, status: '上架' },
{ id: 4, name: '商品4', category: '家居用品', price: 120, stock: 70, status: '下架' },
{ id: 5, name: '商品5', category: '电子产品', price: 90, stock: 90, status: '上架' },
{ id: 6, name: '商品6', category: '家居用品', price: 180, stock: 60, status: '下架' },
{ id: 7, name: '商品7', category: '电子产品', price: 110, stock: 110, status: '上架' },
{ id: 8, name: '商品8', category: '家居用品', price: 190, stock: 40, status: '下架' },
// 添加更多数据以模拟4页
...Array.from({ length: 120 }, (_, i) => ({
id: i + 9,
name: `商品${i + 9}`,
category: i % 2 === 0 ? '电子产品' : '家居用品',
price: Math.floor(Math.random() * 100) + 100,
stock: Math.floor(Math.random() * 100) + 50,
status: i % 2 === 0 ? '上架' : '下架'
}))
];
// 分页参数
const currentPage = ref(1);
const pageSize = ref(10);
// 过滤后的数据
const filteredProducts = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return totalProducts.slice(start, end);
});
// 处理每页数量变化
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1;
};
// 处理当前页变化
const handleCurrentChange = (val) => {
currentPage.value = val;
};
// 操作处理函数
const handleEdit = (row) => {
ElMessage.info(`编辑商品 ${row.name}`);
};
const handlePublish = (row) => {
if (row.status === '上架') {
ElMessage.warning(`商品 ${row.name} 已经上架`);
} else {
ElMessage.success(`上架商品 ${row.name}`);
}
};
const handleUnpublish = (row) => {
if (row.status === '下架') {
ElMessage.warning(`商品 ${row.name} 已经下架`);
} else {
ElMessage.success(`下架商品 ${row.name}`);
}
};
const handleDelete = (row) => {
ElMessage.error(`删除商品 ${row.name}`);
};
</script>
<style scoped>
.product-management {
padding: 20px;
}
.el-table {
margin-bottom: 20px;
}
.el-pagination {
text-align: center;
}
</style>
8,线上订单页
我们接下来就改造线上订单页OnlineOrders.vue
提问词:你是资深前端开发,我已经用vue3和elementplus开发了一个Home.vue首页,首页左侧导航栏有一个二级导航栏 线上订单,右侧对应加载的页面是OnlineOrders.vue,请你在OnlineOrders.vue页面里帮我开发一个带分页的订单表格,操作列有编辑,删除图标按钮,点击编辑的时候可以弹起编辑订单的弹窗,订单状态分为 待配送 已送达 待评价 已完成 已取消。模拟4页的数据出来,页面要尽量美观,表格宽度可以占满页面
先来看下ai生成代码的效果图,比前面用户管理页还有好看
并且点击编辑按钮,可以弹起弹窗进行编辑订单
订单状态还是可以选择的,这里正好用到了我们之前的单选框
我先把完整代码贴出来给到大家,如果你的ai生成的代码不能运行,或者运行出来比较丑,可以直接使用石头哥的ai生成的这段代码。
<template>
<div class="online-orders">
<el-table
:data="filteredOrders"
style="width: 100%"
stripe
border
>
<el-table-column
type="index"
label="序号"
width="60"
/>
<el-table-column
prop="id"
label="订单号"
width="120"
/>
<el-table-column
prop="customerName"
label="客户姓名"
width="120"
/>
<el-table-column
prop="totalPrice"
label="总价"
width="120"
>
<template #default="{ row }">
{{ row.totalPrice }} 元
</template>
</el-table-column>
<el-table-column
prop="orderDate"
label="下单时间"
width="180"
/>
<el-table-column
prop="status"
label="状态"
width="120"
>
<template #default="{ row }">
<el-tag :type="getStatusType(row.status)">{{ row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="200"
>
<template #default="{ row }">
<el-button type="primary" size="small" icon="Edit" @click="handleEdit(row)"></el-button>
<el-button type="danger" size="small" icon="Delete" @click="handleDelete(row)"></el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalOrders.length"
/>
<el-dialog v-model="dialogVisible" title="编辑订单">
<el-form :model="editOrder">
<el-form-item label="订单号" :label-width="formLabelWidth">
<el-input v-model="editOrder.id" disabled></el-input>
</el-form-item>
<el-form-item label="客户姓名" :label-width="formLabelWidth">
<el-input v-model="editOrder.customerName"></el-input>
</el-form-item>
<el-form-item label="总价" :label-width="formLabelWidth">
<el-input v-model="editOrder.totalPrice"></el-input>
</el-form-item>
<el-form-item label="状态" :label-width="formLabelWidth">
<el-select v-model="editOrder.status" placeholder="请选择状态">
<el-option
v-for="item in orderStatusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="handleSave">确 定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { ElMessage, ElDialog } from 'element-plus';
// 模拟数据
const totalOrders = [
{ id: 1, customerName: '张三', totalPrice: 100, orderDate: '2023-09-01', status: '待配送' },
{ id: 2, customerName: '李四', totalPrice: 200, orderDate: '2023-09-02', status: '已送达' },
{ id: 3, customerName: '王五', totalPrice: 150, orderDate: '2023-09-03', status: '待评价' },
{ id: 4, customerName: '赵六', totalPrice: 120, orderDate: '2023-09-04', status: '已完成' },
{ id: 5, customerName: '孙七', totalPrice: 90, orderDate: '2023-09-05', status: '已取消' },
{ id: 6, customerName: '周八', totalPrice: 180, orderDate: '2023-09-06', status: '待配送' },
{ id: 7, customerName: '吴九', totalPrice: 110, orderDate: '2023-09-07', status: '已送达' },
{ id: 8, customerName: '郑十', totalPrice: 190, orderDate: '2023-09-08', status: '待评价' },
// 添加更多数据以模拟4页
...Array.from({ length: 120 }, (_, i) => ({
id: i + 9,
customerName: `客户${i + 9}`,
totalPrice: Math.floor(Math.random() * 100) + 100,
orderDate: `2023-09-${i + 9}`,
status: ['待配送', '已送达', '待评价', '已完成', '已取消'][Math.floor(Math.random() * 5)]
}))
];
// 分页参数
const currentPage = ref(1);
const pageSize = ref(10);
// 过滤后的数据
const filteredOrders = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return totalOrders.slice(start, end);
});
// 处理每页数量变化
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1;
};
// 处理当前页变化
const handleCurrentChange = (val) => {
currentPage.value = val;
};
// 获取状态类型
const getStatusType = (status) => {
switch (status) {
case '待配送':
return 'warning';
case '已送达':
return 'success';
case '待评价':
return 'info';
case '已完成':
return 'success';
case '已取消':
return 'danger';
default:
return '';
}
};
// 编辑订单
const dialogVisible = ref(false);
const editOrder = ref({});
const formLabelWidth = '120px';
const orderStatusOptions = [
{ value: '待配送', label: '待配送' },
{ value: '已送达', label: '已送达' },
{ value: '待评价', label: '待评价' },
{ value: '已完成', label: '已完成' },
{ value: '已取消', label: '已取消' }
];
const handleEdit = (row) => {
editOrder.value = { ...row };
dialogVisible.value = true;
};
const handleSave = () => {
ElMessage.success(`保存订单 ${editOrder.value.id}`);
dialogVisible.value = false;
};
const handleDelete = (row) => {
ElMessage.error(`删除订单 ${row.id}`);
};
</script>
<style scoped>
.online-orders {
padding: 20px;
}
.el-table {
margin-bottom: 20px;
}
.el-pagination {
text-align: center;
}
</style>
9,线下订单页面带搜索框
我们接下来就改造线下订单页OfflineOrders.vue
提问词:你是资深前端开发,我已经用vue3和elementplus开发了一个Home.vue首页,首页左侧导航栏有一个二级导航栏 线下订单,右侧对应加载的页面是OfflineOrders.vue,请你在OfflineOrders.vue页面里帮我开发一个带分页的订单表格,模拟4页的数据出来。在表格上面有搜索框,订单状态选择框可以做相关搜索查询。页面要尽量美观,表格宽度可以占满页面
看下效果图
我们可以搜索订单
可以搜索课后名
还可以根据订单状态筛选订单
我先把完整代码贴出来给到大家,如果你的ai生成的代码不能运行,或者运行出来比较丑,可以直接使用石头哥的ai生成的这段代码。
<template>
<div class="offline-orders">
<el-form :inline="true" class="demo-form-inline">
<el-form-item label="订单号">
<el-input v-model="searchQuery.orderNumber" placeholder="请输入订单号" @keyup.enter="handleSearch"></el-input>
</el-form-item>
<el-form-item label="客户名称">
<el-input v-model="searchQuery.customerName" placeholder="请输入客户名称" @keyup.enter="handleSearch"></el-input>
</el-form-item>
<el-form-item label="订单状态" style="width: 200px;">
<el-select v-model="searchQuery.status" placeholder="请选择状态" >
<el-option label="全部" value=""></el-option>
<el-option label="已完成" value="已完成"></el-option>
<el-option label="处理中" value="处理中"></el-option>
<el-option label="已取消" value="已取消"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
<el-table :data="filteredData" style="width: 100%">
<el-table-column prop="orderNumber" label="订单号" width="180"></el-table-column>
<el-table-column prop="customerName" label="客户名称" width="180"></el-table-column>
<el-table-column prop="amount" label="金额" width="180"></el-table-column>
<el-table-column prop="status" label="状态"></el-table-column>
</el-table>
<el-pagination
background
layout="prev, pager, next"
:total="totalRows"
:page-size="pageSize"
:current-page="currentPage"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
// 模拟数据
const orders = [
{ orderNumber: '123456', customerName: '张三', amount: '¥500', status: '已完成' },
{ orderNumber: '789012', customerName: '李四', amount: '¥1000', status: '处理中' },
{ orderNumber: '345678', customerName: '王五', amount: '¥800', status: '已完成' },
{ orderNumber: '901234', customerName: '赵六', amount: '¥1200', status: '已取消' },
{ orderNumber: '567890', customerName: '钱七', amount: '¥600', status: '处理中' },
{ orderNumber: '123456', customerName: '孙八', amount: '¥700', status: '已完成' },
{ orderNumber: '789012', customerName: '周九', amount: '¥900', status: '已取消' },
{ orderNumber: '345678', customerName: '吴十', amount: '¥1000', status: '处理中' },
{ orderNumber: '901234', customerName: '郑十一', amount: '¥1100', status: '已完成' },
{ orderNumber: '567890', customerName: '王十二', amount: '¥1200', status: '已取消' },
{ orderNumber: '123456', customerName: '李十三', amount: '¥500', status: '处理中' },
{ orderNumber: '789012', customerName: '张十四', amount: '¥600', status: '已完成' },
{ orderNumber: '345678', customerName: '王十五', amount: '¥700', status: '已取消' },
{ orderNumber: '901234', customerName: '赵十六', amount: '¥800', status: '处理中' },
{ orderNumber: '567890', customerName: '钱十七', amount: '¥900', status: '已完成' },
{ orderNumber: '123456', customerName: '孙十八', amount: '¥1000', status: '已取消' },
];
const searchQuery = ref({ orderNumber: '', customerName: '', status: '' });
const pageSize = 5;
const currentPage = ref(1);
const totalRows = orders.length;
// 分页后的数据
const filteredData = computed(() => {
let data = orders.filter(order => {
const matchesOrderNumber = !searchQuery.value.orderNumber || order.orderNumber.includes(searchQuery.value.orderNumber);
const matchesCustomerName = !searchQuery.value.customerName || order.customerName.includes(searchQuery.value.customerName);
const matchesStatus = !searchQuery.value.status || order.status === searchQuery.value.status;
return matchesOrderNumber && matchesCustomerName && matchesStatus;
});
return data.slice((currentPage.value - 1) * pageSize, currentPage.value * pageSize);
});
// 处理分页变化
function handleCurrentChange(val) {
currentPage.value = val;
}
// 处理搜索
function handleSearch() {
currentPage.value = 1; // 搜索后回到第一页
}
</script>
<style scoped>
.demo-form-inline {
margin-bottom: 20px;
}
</style>
到这里我们就把一个基础版的管理系统网站开发好了。无非就是里面显示的数据后面要接入真实数据。页面里的逻辑需要做特殊处理。
我会把这个综合案例的源码放在资料里,有需要的同学评论区留言获取。
七,使用Echarts显示趋势图
7-1,模仿ai自己创建新菜单和页面
我们可以模仿前面ai生成左侧导航菜单栏,自己生成下菜单和对应的页面。
首先在Home页面创建echarts相关的一级和二级菜单。
来看下效果图
接下来创建折线图和柱状图对应的页面
然后在router里注册这俩个页面到路由里
然后两个页面里随便先写一些内容
然后可以看到实现了导航页的路由跳转
接下来我们就来学习Echarts
7-2,引入Echarts
提问词:教我在vue3里引入echarts
我们先通过npm install echarts安装依赖库
7-3,折线图
提问词:我已经在vue3里使用echats,并且创建了一个ChartLine.vue页面,请在ChartLine.vue页面里用折线图显示销售额,样式尽量美观些
我们直接使用ai生成的代码
先看效果图
可以让ai给我们解释下代码
如果觉得简单,可以更详细些。
如果还觉得不够详细,可以让ai重点解释你想要学习的几行代码。
我先把完整代码贴出来给到大家,如果你的ai生成的代码不能运行,或者运行出来比较丑,可以直接使用石头哥的ai生成的这段代码。
ChartLine.vue
<template>
<el-card class="sales-chart">
<div ref="chartRef" class="chart-container"></div>
</el-card>
</template>
<script setup>
import * as echarts from 'echarts';
import { onMounted, onBeforeUnmount, ref } from 'vue';
// 示例销售数据
const salesData = [
{ date: '2023-09-01', sales: 150 },
{ date: '2023-09-02', sales: 200 },
{ date: '2023-09-03', sales: 180 },
{ date: '2023-09-04', sales: 220 },
{ date: '2023-09-05', sales: 250 },
{ date: '2023-09-06', sales: 280 },
{ date: '2023-09-07', sales: 300 },
];
const chartRef = ref(null);
const chartInstance = ref(null);
const initChart = () => {
if (!chartInstance.value) {
chartInstance.value = echarts.init(chartRef.value);
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['销售额'],
textStyle: {
color: '#606266',
fontSize: 14
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: salesData.map(item => item.date),
axisLabel: {
color: '#606266',
fontSize: 14
},
axisLine: {
lineStyle: {
color: '#dcdfe6'
}
}
},
yAxis: {
type: 'value',
axisLabel: {
color: '#606266',
fontSize: 14
},
axisLine: {
lineStyle: {
color: '#dcdfe6'
}
}
},
series: [{
name: '销售额',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 10,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(255, 104, 104, 0.3)' },
{ offset: 1, color: 'rgba(255, 104, 104, 0)' }
])
},
emphasis: {
focus: 'series'
},
data: salesData.map(item => item.sales)
}]
};
chartInstance.value.setOption(option);
}
};
onMounted(() => {
initChart();
});
// 窗口大小变化时更新图表
window.addEventListener('resize', () => {
chartInstance.value?.resize();
});
// 组件销毁前移除事件监听器
onBeforeUnmount(() => {
window.removeEventListener('resize', () => chartInstance.value?.resize());
});
</script>
<style scoped>
.sales-chart {
width: 90%;
margin: 20px auto;
padding: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
border-radius: 8px;
background-color: #fff;
}
.chart-container {
width: 100%;
height: 450px;
}
</style>
7-4,柱状图
提问词:我已经在vue3里使用echats,并且创建了一个ChartBar.vue页面,请在ChartBar.vue页面里用柱状图对比今年和去年的销售额,样式尽量美观些
我们引入代码看下效果图
同样你可以让ai给你解释代码。
我先把完整代码贴出来给到大家,如果你的ai生成的代码不能运行,或者运行出来比较丑,可以直接使用石头哥的ai生成的这段代码。
ChartBar.vue
<template>
<el-card class="sales-chart">
<div ref="chartRef" class="chart-container"></div>
</el-card>
</template>
<script setup>
import * as echarts from 'echarts';
import { onMounted, onBeforeUnmount, ref } from 'vue';
// 示例销售数据
const salesData = {
thisYear: [
{ month: 'Jan', sales: 150 },
{ month: 'Feb', sales: 200 },
{ month: 'Mar', sales: 180 },
{ month: 'Apr', sales: 220 },
{ month: 'May', sales: 250 },
{ month: 'Jun', sales: 280 },
{ month: 'Jul', sales: 300 },
{ month: 'Aug', sales: 270 },
{ month: 'Sep', sales: 290 },
{ month: 'Oct', sales: 320 },
{ month: 'Nov', sales: 350 },
{ month: 'Dec', sales: 380 }
],
lastYear: [
{ month: 'Jan', sales: 120 },
{ month: 'Feb', sales: 180 },
{ month: 'Mar', sales: 160 },
{ month: 'Apr', sales: 200 },
{ month: 'May', sales: 230 },
{ month: 'Jun', sales: 260 },
{ month: 'Jul', sales: 280 },
{ month: 'Aug', sales: 250 },
{ month: 'Sep', sales: 270 },
{ month: 'Oct', sales: 300 },
{ month: 'Nov', sales: 330 },
{ month: 'Dec', sales: 360 }
]
};
const chartRef = ref(null);
const chartInstance = ref(null);
const initChart = () => {
if (!chartInstance.value) {
chartInstance.value = echarts.init(chartRef.value);
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['今年', '去年'],
textStyle: {
color: '#606266',
fontSize: 14
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: salesData.thisYear.map(item => item.month),
axisLabel: {
color: '#606266',
fontSize: 14
},
axisLine: {
lineStyle: {
color: '#dcdfe6'
}
}
},
yAxis: {
type: 'value',
axisLabel: {
color: '#606266',
fontSize: 14
},
axisLine: {
lineStyle: {
color: '#dcdfe6'
}
}
},
series: [
{
name: '今年',
type: 'bar',
barWidth: '40%',
itemStyle: {
normal: {
color: '#5470C6'
}
},
data: salesData.thisYear.map(item => item.sales)
},
{
name: '去年',
type: 'bar',
barWidth: '40%',
itemStyle: {
normal: {
color: '#EE6666'
}
},
data: salesData.lastYear.map(item => item.sales)
}
]
};
// 设置图表选项
chartInstance.value.setOption(option);
}
};
onMounted(() => {
initChart();
});
// 窗口大小变化时更新图表
window.addEventListener('resize', () => {
chartInstance.value?.resize();
});
// 组件销毁前移除事件监听器
onBeforeUnmount(() => {
window.removeEventListener('resize', () => chartInstance.value?.resize());
});
</script>
<style scoped>
.sales-chart {
width: 90%;
margin: 20px auto;
padding: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
border-radius: 8px;
background-color: #fff;
}
.chart-container {
width: 100%;
height: 450px;
}
</style>
我这里只教大家使用最常见的两个,当然了,你可以按照石头哥的方式,去学习下echarts里的其他一些常用的趋势图,比如饼状图,雷达图等。
到这里我们就把一个基础版的管理系统网站开发好了。无非就是里面显示的数据后面要接入真实数据。页面里的逻辑需要做特殊处理。
我会把这个综合案例的源码放在资料里,有需要的同学评论区留言获取。
八,自己手写管理后台代码
我们前面已经使用ai快速的实现了一款vue管理后台,也让ai给我们解释了代码,基本的代码都可以读得懂了。既然有ai这个好师傅教我们如何写vue3的代码了,那么接下来我们再让ai作为好朋友,陪我们一起写代码。效果图如下
如果大家有时间的话,想深入学习下vue3,可以去看下石头哥的《零基础入门vue3》
8-1,手写一个登录页
我们可以再次熟悉下Login.vue里的代码,熟悉完,我们就把代码删除了,自己动手写出一个登录页。接下来石头哥先带着大家手写代码。我们可以自己写出一个不一样的登录页,比如颜色,样式什么的,根据自己的喜好来。
我们先把空白的三剑客写好
然后开始写布局,我们借助element的Layout布局的el-row和el-col 实现左右均分。这样写出来的页面就不用我们自己再大量的写css就可以实现想要的效果。
看下代码和效果图
我们在左侧写一些标题,右侧写登录表单。左右的比例稍微再调整下
页面布局基本上写好了
然后就要写逻辑了。先写校验规则,账号密码不能为空
对应代码如下
绑定数据,获取用户输入的内容。
对应代码如下
点击登录按钮,进行数据提交前,查看检验数据是否通过。
校验通过
到这里我们的登录页功能就开发好了,完整代码贴给大家
<script setup>
import { reactive,ref } from 'vue'
import { ElMessage } from 'element-plus';
// 定义校验规则,账号密码不能为空
const rules = {
username: [
{ required: true, message: '账号不能为空', trigger: 'blur' },
],
password: [
{ required: true, message: '密码不能为空', trigger: 'blur' },
// 密码长度在6-12位
{ min: 6, max: 12, message: '密码长度在6-12位', trigger: 'blur' },
],
}
// 提交表单
const loginRef = ref(null)
const onSubmit = () => {
loginRef.value.validate(valid => {
if (valid) {
alert('校验通过')
} else {
// elementplus 消息弹窗
ElMessage.error('请填写账号和密码')
// return false
}
})
console.log('submit!')
}
// 定义表单数据,获取用户输入的账号密码
const formData = reactive({
username: '',
password: '',
})
</script>
<template>
<div>
<el-row>
<el-col :span="15">
<div class="left">
<h1>编程小石头带你写登录页</h1>
</div>
</el-col>
<el-col :span="9">
<div class="right">
<el-card>
<h1>登录表单</h1>
<el-form label-width="80px" :rules="rules" status-icon :model="formData" ref="loginRef">
<el-form-item label=" 账号" prop="username">
<el-input placeholder="请填写账号" v-model="formData.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input placeholder="请填写密码" v-model="formData.password" type="password" show-password></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" style="width: 100%" @click="onSubmit">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</el-col>
</el-row>
</div>
</template>
<style>
.left {
background-color: #409eff;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 30px;
}
.right {
background-color: whitesmoke;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.el-card {
width: 450px;
height: 300px;
text-align: center;
padding: 15px;
}
</style>
8-2,手写首页左侧导航菜单
我们首页左侧的导航菜单也是用的element的,所以自己写的话,可以去官方文档里找合适的布局。
我们使用Container 布局容器里的左侧分类,顶部标题,右侧内容。下图所示的这个布局。
可以直接把对应的代码复制到我们的首页。由于还没有添加样式,所以还看不出布局。
接下来我们就开始添加样式,稍微加下样式,就可以看出我们想要的布局了。
然后就是左侧导航菜单了,也可以直接使用官方的Menu 菜单
接下来我们稍微改下左侧分类栏的样式和文案,改造后如下
我们这里做了一个动态导航,方便后面做不同用户可以显示不同的左侧导航栏
到这里我们左侧导航栏就写好了,接下来就是配置路由和顶部栏了。
8-3,配置多页面和路由跳转
我们前面已经学过vue-router了。这里直接配置就行。
router的路由配置和我们views页面里的对应起来即可。然后我们在左侧导航栏给每个菜单绑定对应的路由path即可。
到这里我们就可以实现左侧导航栏的路由跳转了。
8-4,手写顶部栏
接下就要开始写我们的顶部栏了。其实可以看到我们的顶部栏就是显示你当前跳到了那个页面。
这里用的是element的面包屑
我们直接复用代码,然后改成自己的即可。
我们这里是通过router的路由配置里读取对应的导航菜单名称进行显示的。所以要记得去router的配置文件里配置。
到这里我们最基础的通用管理后台模板就完成了,你可以直接拿石头哥的模板去开发属于你自己的vue3管理后台
我把源码放在网盘里,需要资料的同学记得评论区见。
8-5,手写商品列表页
我们接下来写商品列表页。我们既然要显示列表,其实就是用的element的Table 表格。
那我们先找一个自己喜欢的,我们先把这个带斑马线的表格引入到项目
我们把布局和数据都引入到商品列表页
运行项目,看下表格可以显示进来
我们把表格标题先改下,改的更像商品。
然后再去模拟一些商品数据。
顺便给表格加几个字段
这样一个简单的商品列表就有了。这里给大家补充一个知识点。
8-5-1,定义一个方法将状态数字转为文本
通常后台给我们返回的商品数据是这样的
商品状态后台不直接给我们返回文本,而是数字,不同数字代表不同状态。我们如果直接显示,会把数字显示出来,这样肯定是不友好的。
所以我们要把数字转换为对应的状态文本。就定义一个函数。来实现转换即可。下面是函数定义和使用。
显示效果如下
8-5-2,排序和筛选
我们可以依据日期进行排序,只需要给对应列加一个sortable即可。是不是觉得element特别强大。
当然也可以根据不同状态进行筛选
8-5-3,根据商品名做模糊搜索
通过之前学习过的,定义一个搜索框和一个搜索按钮
可以根据商品名做模糊搜索
我们主要是通过这段代码实现模糊搜索
当然这只是我们前端自己处理数据,正规的开发流程,搜索应该由后端开发实现,我们调用后端搜索接口。
8-5-4,手写商品分页功能
我们商品数量比较多的时候,一页显示不完,就要使用分页功能。
比如我们由83条商品,就没有办法在一页显示完
这个时候就用Pagination 分页,可以实现分页功能如下。
搜索结果也可以分页
这一步要改动的代码比较多, 我把完整代码贴给大家,大家慢慢自己学习
<script setup>
import { computed, ref } from 'vue';
// status对应字段:-1下架,0预售,1在售
const goodDataOld = [
{
id: 1,
date: '2003-04-01',
name: '无线耳机',
price: 299,
address: '上海市浦东新区',
status: -1
},
{
id: 2,
date: '2003-04-03',
name: '智能手表',
price: 1299,
address: '深圳市福田区',
status: 0
},
{
id: 3,
date: '2003-04-01',
name: '便携充电器',
price: 99,
address: '广州市天河区',
status: 1
},
...Array.from({ length: 80 }, (_, i) => ({
id: i + 4,
date: `2004-09-${i + 4}`,
name: `商品${i + 4}`,
price: Math.floor(Math.random() * 100) + 100,
address: '广州市天河区' + i,
status: [-1, 0, 1][Math.floor(Math.random() * 3)]
}))
]
// 定义一个方法将状态数字转为文本
function statusText(status) {
switch (status) {
case -1:
return '下架';
case 0:
return '预售';
case 1:
return '在售';
}
}
// 筛选函数
function filterTag(value, row) {
return row.status === value;
}
// 搜索相关
const search = ref('');
// 处理搜索,搜索后回到第一页
function handleSearch() {
currentPage.value = 1;
}
/**
* 分页功能
*/
const pageSize = ref(10);
const currentPage = ref(1);
// 切换每页显示多少条数据
function handleSizeChange(val) {
pageSize.value = val;
}
// 点击页码
function handleCurrentChange(val) {
currentPage.value = val;
}
// 分页过滤后的数据
const goodData = computed(() => {
let list = goodDataOld.filter(item => item.name.includes(search.value))
console.log('搜索到的结果', list);
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return list.slice(start, end);
});
const total = computed(() => {
if (search.value) {
return goodData.value.length
} else {
return goodDataOld.length
}
});
</script>
<template>
<!-- 根据el-table里的商品名name字段做模糊搜索功能,并设置el-input的宽度为100 -->
<el-input class="search-input" v-model="search" placeholder="请输入商品名" clearable @keyup.enter="handleSearch"
@clear="handleSearch" />
<!-- 搜索按钮 -->
<el-button class="search-btn" type="primary" @click="handleSearch">搜索</el-button>
<el-table :data="goodData" stripe style="width: 100%;">
<el-table-column prop="id" label="id" width="180" sortable />
<el-table-column prop="date" label="日期" width="180" sortable />
<el-table-column prop="name" label="商品名" width="180" />
<el-table-column prop="price" label="价格" width="180" />
<el-table-column prop="address" label="产地" />
<!-- status对应字段:-1下架,0预售,1在售 -->
<el-table-column prop="status" label="状态" :filters="[
{ text: '下架', value: -1 },
{ text: '预售', value: 0 },
{ text: '在售', value: 1 },
]" :filter-method="filterTag" filter-placement="top">
<template #default="scope">
<el-tag v-if="scope.row.status === -1" type="warning">{{ statusText(scope.row.status) }}</el-tag>
<el-tag v-else-if="scope.row.status === 0" type="success">{{ statusText(scope.row.status) }}</el-tag>
<el-tag v-else type="danger">{{ statusText(scope.row.status) }}</el-tag>
</template>
</el-table-column>
</el-table>
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage"
:page-sizes="[5, 10]" :page-size="pageSize" layout=" sizes, prev, pager, next, jumper ,total" :total="total"
style="text-align: center;margin-top: 10px" />
</template>
<style>
.search-input {
width: 200px;
margin-bottom: 20px;
}
.search-btn {
margin-bottom: 20px;
margin-left: 20px;
}
</style>
8-6,添加和修改分类
我们前面可以显示商品列表了,并且还做了分页功能和搜索功能,接下来我们再已分类为例,实现商品分类的添加和修改。
8-6-1,添加分类
我们添加分类其实就是用的弹窗,那我们去element找下看有没有合适的弹窗。可以使用Dialog 对话框
先引入代码,再改造
先改下布局,把form表单加入进来。可以看到我们用了输入框和开关来控制不同的数据填写。
先看下效果
接下来我们继续定义数据,来获取用户的输入。
这样就可以获取用户输入的数据了
然后我们先自己定义一个数组,用来存用户都添加过那些分类
既然收取到了用户的输入,那我们是不是可以用表格把商品分类列表显示出来了。这样我们直接去回顾下商品列表用表格怎么显示的,再自己重新写下分类的表格就行了。
然后在表格上面增加一个添加分类的按钮即可。
这样就可以愉快的添加新的商品分类啦。细心的同学会发现,是否禁用哪里用true和false显示对用户不太友好。前面讲过,大家可以自己定义一个方法,把布尔值转换为文字,并且用tag显示。
8-6-2,修改数据
我们既然可以添加数据,那么是否也可以修改数据呢?其实大家想一下,添加数据和修改数据的弹窗是不是一样的,无非就是修改和添加的标题不一样。修改里面自动填充数据,添加是没有数据的。那么我们接下来就实现添加功能。
我们增加一行操作列,把点击编辑当前行的数据传递给修改弹窗。
效果如下
这样我们就可以实现修改功能了。
因为修改和添加共有一个弹窗,所以要通过一个字段来区分。
到这里添加和修改商品分类功能都实现了。无非我们先在改的是本地数据,后面有后端接口的话,就可以修改后台数据了。原理基本上都是一样的。
8-6-3,删除数据
我们操作栏有一个删除,那么我们就顺便实现下删除功能吧。通常删除前我们要有一个弹窗进行二次确认
这里使用的是element的ElMessageBox
到这里添加和修改和删除商品分类功能都实现了。无非我们先在改的是本地数据,后面有后端接口的话,就可以修改后台数据了。原理基本上都是一样的。
8-6-4,项目代码
我把商品分类的完整代码给到大家
<script setup>
import { ElMessageBox } from "element-plus";
import { reactive, ref } from "vue";
const dialogVisible = ref(false);
let list = ref([
{ type: "手机", desc: "手机类商品", canUse: true },
{ type: "电脑", desc: "电脑类商品", canUse: true },
{ type: "电视", desc: "电视类商品", canUse: true },
{ type: "耳机", desc: "耳机类商品", canUse: true },
]);
let form = ref({});
let dialogType = ref("add");
function addType() {
// 弹出对话框,让用户添加
dialogVisible.value = true;
dialogType.value = "add";
form.value = {};
}
function changType(row) {
// 弹出对话框,让用户修改
dialogVisible.value = true;
dialogType.value = "chang";
// 将当前行的数据浅拷贝赋值给form
form.value = { ...row };
}
// 删除某条数据
function deleteType(row) {
// 删除之前使用elementplus给个弹窗确认
ElMessageBox.confirm(`此操作将永久删除--${row.type}, 是否继续?`, "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
}).then(() => {
// 删除当前行
list.value.forEach((item, index) => {
if (item.type == row.type) {
list.value.splice(index, 1);
}
});
});
}
// 提交,添加或者修改的分类
function submit() {
dialogVisible.value = false;
if (dialogType.value == "add") {
list.value.push(form.value);
} else {
list.value.forEach((item, index) => {
if (item.type == form.value.type) {
list.value[index] = form.value;
}
});
}
}
</script>
<template>
<!-- 添加分类的按钮 -->
<el-button type="primary" @click="addType" style="margin: 15px 0"
>添加商品分类</el-button
>
<!-- 使用table表格显示分类列表 -->
<el-table :data="list" border stripe>
<el-table-column type="index" width="60" label="序号" />
<el-table-column prop="type" label="商品分类" />
<el-table-column prop="desc" label="分类描述" />
<el-table-column prop="canUse" label="是否禁用">
<template #default="scope">
<el-tag :type="scope.row.canUse ? 'success' : 'danger'"
>{{ scope.row.canUse ? "可用" : "禁用" }}
</el-tag>
</template>
</el-table-column>
<!-- 增加操作列 -->
<el-table-column label="操作">
<template #default="scope">
<el-button
type="primary"
size="small"
icon="edit"
@click="changType(scope.row)"
>编辑</el-button
>
<!-- 修改el-button的大小 -->
<el-button
type="danger"
icon="delete"
size="small"
@click="deleteType(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 使用dialog对话框添加商品 -->
<el-dialog
v-model="dialogVisible"
:title="dialogType == 'add' ? '添加商品分类' : '修改商品分类'"
width="500"
align-center
>
<!-- 添加商品的表单 -->
<el-form :model="form" label-width="80px">
<el-form-item label="商品分类">
<el-input v-model="form.type" />
</el-form-item>
<el-form-item label="分类描述">
<el-input v-model="form.desc" />
</el-form-item>
<el-form-item label="是否禁用">
<el-switch v-model="form.canUse" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submit"> 确定 </el-button>
</div>
</template>
</el-dialog>
</template>
九,Echarts可视化趋势图折线图饼状图等
先给大家看几个echarts的效果图


是不是很炫酷,假如我们的vue3管理后台,接入这些,是不是瞬间九高大上了。接下来带大家学习echarts
9-1,引入echarts
我们引入echarts可以看文档,当然,你如果懒得看文档,就直接问ai就行的。
提问词:教我在vue3里引入echarts并提供一个简单的代码示例
ai给的步骤如下
1,安装依赖
npm i echarts
2,在需要使用echarts的页面引入依赖
import * as echarts from ‘echarts’;
3,示例代码
可以看到ai给我们提供了一个简单的示例
<template>
<div ref="chartRef" style="width: 600px; height: 400px;"></div>
</template>
<script setup>
import * as echarts from 'echarts';
// 初始化 ECharts 实例
const chartRef = ref(null);
onMounted(() => {
const chart = echarts.init(chartRef.value);
// 设置图表配置
const option = {
title: {
text: '简单示例'
},
tooltip: {},
legend: {
data: ['数据']
},
xAxis: {
data: ["A", "B", "C", "D", "E"]
},
yAxis: {},
series: [{
name: '数据',
type: 'bar',
data: [80, 50, 30, 40, 120]
}]
};
// 渲染图表
chart.setOption(option);
});
// 监听窗口大小变化重新渲染图表
window.addEventListener('resize', () => {
chart.resize();
});
</script>
看下效果图
这样一个简单的echarts柱状图就搭建好了。接下来带大家深入学习
9-2,折线图
我们可以看官方里的折线图,有喜欢的,直接点击js代码
然后去复制相关代码到我们的项目里即可。
复制到我们的项目里,看下效果图
是不是觉得使用起来特别方便。
当然我们可以让ai给我们解释下代码。
如果你觉得ai讲的不够请求,可以让ai讲的在详细些。
我们再来看下ai的讲解,是不是比石头哥讲的还好。
当然知道代码后,我们可以自己改代码了,比如把英文改为中文。
当然你也可以自己修改。比如我们再改下折线图阴影的颜色
9-3,饼状图
同样我们去官方找饼状图,去拿自己喜欢样式的代码。
同样把代码复制到我们的项目里。看下效果图
当然,你也可以去使用别的
是不是用起来特别简单,目前使用的都是demo数据,后面我们会教大家如何定义自己的数据的。
9-4,柱状图
我们使用可以自定义柱子颜色的demo
先看效果
再学习代码
我们可以给周日设置绿色。
是不是有ai助理,我们学起来事半功倍。
当然你也可以自己课下,试试别的图形
9-5,使用自己的数据
我们就以一开始的折线图为例吧。
可以看到我们需要提供的数据,一共两个
x轴的日期数据,y轴的数值。
我们找到对应的数据,可以自己组合下。
可以看到我们自己组合的数据,看起来更清晰明了。
const list = [
{ day: "周一", num: 820 },
{ day: "周二", num: 932 },
{ day: "周三", num: 901 },
{ day: "周四", num: 934 },
{ day: "周五", num: 1290 },
{ day: "周六", num: 1300 },
{ day: "周日", num: 1320 },
];
比如你想换成每个月的营业额.你只需要修改下list,别的地方不用改动。
const list = [
{ day: "一月", num: 1000 },
{ day: "二月", num: 1200 },
{ day: "三月", num: 901 },
{ day: "四月", num: 3901 },
{ day: "五月", num: 901 },
{ day: "六月", num: 2901 },
{ day: "七月", num: 901 },
{ day: "八月", num: 901 },
{ day: "九月", num: 1901 },
{ day: "十月", num: 901 },
{ day: "十一月", num: 3901 },
{ day: "十二月", num: 901 },
];

可以看到数据没有全部显示出来,是因为我们的宽度太窄了,修改下宽度即可。
到这里我们就可以显示自己的数据了,当然这个数据,你也可以让后台开发给你提供。当然如果还没有后台开发给你提供数据,你可以自己先模拟下后台数据。
9-6,模拟后台数据
我们知道后台返回的数据一般都是json数据,我们先让ai帮我们把数据转换为json格式。
然后在plulic目录里创建一个list.json存转换好的json数据。
因为public里的数据可以让外界直接访问的。
其实这就是一个简易版的后台数据接口了。接下来我们用基础课里学习过的axios来做网络请求。
9-7,axios请求后台数据
我们前面模拟好后台数据了,接下来就用axios来做真实网络请求。假如你忘记了怎么使用axios,可以交给ai
然后做get请求,获取网络数据
可以看到成功获取到了数据,接下来在获取数据成功后使用数据即可。
比如我们后台修改了网络数据,把四月的值从3901改为100
通过折线图可以很明显的观察到变化。
十,请求真实网络接口
应大家的要求,我们这里再加一章真实网络接口的学习。而这个网络接口,我们就提供给大家用户相关的吧,首先是实现用户登录功能,并且用pinia状态管理库全局存储用户相关的信息。然后我们根据不同用户权限去动态的加载首页左侧的分类栏。
10-1,用户分权限
我们通过给用户表加一个role字段来表示不同的权限。
| role值 | 用户类型 | 权限 |
|---|---|---|
| 0 | 普通用户 | 可以进入到管理后台,只可看首页 |
| 1 | 普通管理员 | 可以进入管理后台,可以看首页和订单 |
| 2 | 超级管理员 | 可以进入管理后台,可以管理所有功能 |

可以看到不同的用户有不同的role值,不同的role值就代表各自的权限。
然后我们看下普通管理员和超级管理员进入后台显示的区别。
我也会在视频里仔细给大家演示一遍的。
10-2,运行后台接口服务器
10-2-1,下载并导入node服务器源码
我这里提前给大家准备好了数据后台,使用node.js写的,给大家放到资料里了
我们点击资料–》数据后台接口—》把node.zip下载到桌面,解压好。然后用vscode新建一个窗口打开这个node项目
node项目打开后如下
10-2-3,启动node服务器
我们用户相关的所有接口,都是定义在user.js里,所以我们打开终端执行node user.js
就可以启动后台数据服务器了。
可以看到我们启动后的后台地址,我们可以去浏览器里测试下node服务器是否启动成功。在浏览器里输入
http://localhost:3000/userList

10-2-3,服务器端口被占用

3000记得换成你自己电脑上的,如果你电脑启动是3001,记得你访问数据时也要用3001
10-2-4,接口文档
还有对应的接口文档提供给大家,其实你去公司后,就是这么一个流程了,后台开发人员,给你提供数据后台,然后也会给你接口文档,你根据接口文档请求对应的接口。然后请求数据显示到桌面。
接口文档和node服务器源码在一起
10-3,调用登录接口
首先看下我们的接口文档里登录的接口
我们需要传入的参数有用户名和密码。项目里使用axios做post请求代码如下
可以看到会返回对应的用户信息。

这样我们就登录成功了。接下来我们把用户登录信息存储到pinia里,方便别的页面使用
10-4,使用pinia存储用户信息
不知道pinia是什么的同学可以去看下我们零基础入门vue3,我们这里直接就使用pina来存储登录成功后的用户信息了。包括我们后面做的退出登录,在退出登录的时候要清空下pinia里存的数据的。
10-4-1,存数据
首先看我们pinia里定义了什么
然后在登录成功的时候,存储用户信息
10-4-2,取数据,不同权限加载不同导航栏
在登录成功,进入到首页的时候,从pinia里读取用户信息
根据不同的用户权限,加载不同的导航栏。
10-4-3,退出登录
我这一章还给大家新加了退出登录的功能
点击退出登录,我们会清空pinia里的用户信息,然后跳回到登录页
效果图
10-5,vue-router全局前置守卫
我们前面实现完退出登录,还会有一个问题,就是退出登录,点击返回按钮,还可以再次进入管理后台。这样是不合理的。
所以我们要做下路由的全局前置守卫。就是在退出登录后,不管用户进入到那个页面,都要先检查下登录状态的,如果没有再次登录,就强制跳转回登录页。只需要在router目录的index.js里加入如下代码即可。
代码贴给大家
// 使用全局前置守卫 (beforeEach),如果没有登录就重定向到登录页
router.beforeEach((to, from, next) => {
const userStore = useUserStore()
if (to.path === '/login' || to.path === '/') {
next()
} else {
if (userStore.userInfo.username) {
next()
} else {
next('/login')
}
}
})
10-6,添加用户管理页面
我们使用超级管理员登录的时候可以显示用户管理的菜单的。
10-6-1,创建用户管理页并注册路由
那么我们就来实现这个用户管理页。首先要创建Users.vue页面,然后在router里注册路由。
然后去到首页左侧导航栏,在超级管理员登录成功后,加载这个用户管理导航菜单。普通管理员和普通用户不加载。
10-6-2,添加用户
然后编写用户管理页,首先我们看下,用户管理页和之前学过的商品分类页是不是特别像
所以我们这里不再重写写代码,直接把商品分类页代码拿过来改下就行。首先是添加用户功能。
我们添加用户的时候要调用添加用户的接口
其实我们添加用户接口需要的参数,我们都已经包含在form里了
可以看下监听
添加成功后我们会自动刷新用户列表,给客户添加id
10-6-3,修改用户信息
修改用户其实和添加用户共用的同一个弹窗,无非就是修改的时候,会自动把要修改用户信息填充到弹窗。比如我们修改下刚刚新添加的用户的密码
修改的核心代码如下
可以看到修改是调用了修改用户的接口
我们修改比添加就多了一个id参数。因为我们修改是拿id去先查询到当前用户信息,然后再把自己提交的新用户信息替换老的用户信息。
如果我们提交的新信息和老信息没有任何区别,会提示用户 数据没有做任何修改。
消息提示如下。
这样做的目的,就是为了避免浪费服务器资源。既然没有做任何修改,就不要再去请求服务器了。
10-6-4,删除用户
删除用户前,需要给用户二次确认弹窗,防止用户误删除。
然后用户点确定,会调用删除的接口
删除接口拿到数据后,其实是根据id查询到当前用户如果存在,就把这个id对应的用户删除了。
10-7,axios统一封装
我们到这里其实功能已经全部实现了,但是有个问题,我们调用axios的地方比较分散,也比较多。假如有一天我们正式发布上线了,或者后台开发改了接口地址,我们是不是要一个个去修改。一个个去修改是不是很繁琐,还容易犯错。
我们对axios库的请求数据功能进行封装可以提高代码的可维护性和复用性。为了更好地封装 axios 请求,我们可以创建一个独立的模块来处理所有与 HTTP 请求相关的逻辑。
1. 创建一个 api.js 文件
在项目的 src 目录下创建一个api的目录,然后在api目录里创建一个 api.js 文件,并编写如下代码:
这样我们后面修改接口地址的时候,只需要在这里改一次就行了。
2,在 Vue 组件中使用封装的 API
其实使用也非常简单,就是把之前直接引入axios的地方,改为引入我们的app.js文件
然后使用接口的地方,改成如下。
其实写法上,就是提取了一个接口地址到api.js里方便我们后面修改。其他的地方基本没有变化。
当然你也可以自己把我们之前登录页面用到axios的地方改成封装后的。
我们后面再写新的接口时,记得用我们封装好的api.js就可以了,这样后面改起来特别方便。
当然有些大公司会封装的特别深。
这个其实原理都是一样的,根据你们公司具体情况做具体封装就行。我们初学阶段做一个简单的封装就行了,封装的太深不利于我们学习理解。
到这里我们整个vue3结合Elementplus和Echarts的通用管理后台就学习完了。下一门课给大家使用Springboot开发真实的Java+Mysql数据后台,这样我们的vue3项目就可以使用真实的后台数据啦。敬请期待。。。。。
更多推荐



所有评论(0)