vue新项目初始化
vite构建
# 创建新项目
npm create vue@latest
# 安装依赖
npm install
# 启动项目
npm run dev
# 网络请求模块
npm i axios
# css预处理器 sass
npm i sass
# 安装 elementUI框架
npm install element-plus --save
# 安装 normalize.css 样式初始化文件
npm install normalize.css
#安装 Element Plus 图标集合。
npm install @element-plus/icons-vue
# 数据模拟
npm install mockjs
element-plus 修改css样式的时候 可以直接用
.el-button
去修改.+组件名
的的模式
配置element-plus
无论是全局引入 还是自动导入配置 要把css文件在 main.ts 引入
// main.ts 全局引入
import 'element-plus/dist/index.css'
// main.ts 全局引入
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
初始化快速开始
https://element-plus.gitee.io/zh-CN/guide/quickstart.html
自动导入配置
npm install -D unplugin-vue-components unplugin-auto-import
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
国际化配置中文模式
// main.ts
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
app.use(ElementPlus, {
locale: zhCn,
})
配置 vite项目环境变量
在根目录下新建两个文档
.env.dev
VITE_BASEURL="/api"
# 开发环境的接口
.env.prod
VITE_BASEURL="/api"
# 生产环境的接口
在package.json 修改
"scripts": {
"dev": "vite --mode dev"
}
使用 npm run dev 就会使用 .env.dev 里面配置的环境变量
使用 npm run build 就会使用 .env.prod 里面配置的环境变量
简单初始
删除 不需要的文件
这些文件都不需要
修改 css文件
# 安装 normalize.css 样式初始化文件
npm install normalize.css
# 在main.ts里面导入
import 'normalize.css'
文件后缀修改为scss
base.scss
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition:
color 0.5s,
background-color 0.5s;
line-height: 1.6;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
main.scss
/* 注意修改名称后这里原来的引入路径也要修改 */
@import './base.scss';
#app {
max-width: 1280px;
font-weight: normal;
}
main.ts文件 引入路径名称也要修改
import './assets/main.scss'
配置跨域
在 vite.config.ts 里面配置
// vite.config.ts
server: {
proxy: {
'/api': {
// 配置需要代理的路径 --> 这里的意思是代理http://localhost:80/api/后的所有路由
target: 'http://xxxx.xxxx.xxxx.xxxx:xx', // 目标地址 --> 服务器地址
changeOrigin: true, // 允许跨域,
ws: true, // 允许websocket代理
// 重写路径 --> 作用与vue配置pathRewrite作用相同
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
配置路由懒加载和前置路由守卫
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
redirect: '/home' //让他跳转到 home 页面 输入地址会跳转到home
},
{
path: '/home',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'home',
component: () => import('@/views/AboutView.vue')
// 懒加载模式 进入/about这个地址的时候才会加载这个页面 而不是一开始就加载好
}
]
})
//路由前置守卫,验证用户 身份检查权限
//to 即将进入目标路由对象 包含路由,参数,查询参数等
// from 当前导航正要离开的路由对象 , 从哪里来 包含了当前的路由信息
//next 函数 ,语言控制导航行为,可以接受一个参数 用与指定导航的目录路由
router.beforeEach((to, form, next) => {
//如果登录了就让往下继续走 如果没有登录 跳转到登录页面
if (userLogin) {
next()
} else {
next('/login')
}
})
export default router
封装 axios
// apis/index.ts 文件
import router from '@/router'
import axios, { AxiosError } from 'axios'
import type { AxiosRequestConfig } from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
export const request = axios.create()
// 返回的类型
export type BkResponse = {
data: any
code: number
message: string
succeed: boolean
}
//设置服务器根路径
request.defaults.baseURL = import.meta.env.VITE_BASEURL
//设置相应拦截器
export const $http = async (config: AxiosRequestConfig) => {
const loadingInstance = ElLoading.service()
try {
const axiosResponse = await request<BkResponse>(config)
const bkResponse = axiosResponse.data
if (!bkResponse?.succeed) {
//如果succeed 请求失败
let errTitle: string = 'Error'
if (bkResponse.code === 400) {
//用户为授权
errTitle = 'Unauthorized'
ElMessage.error('未授权') //ui弹出
router.push('/login')
} else if (bkResponse.code === 403) {
errTitle = 'ForBidden'
} else if (bkResponse.code === 9999) {
errTitle = '9999error'
} else if (bkResponse.code === 500) {
errTitle = 'ServeError'
} else {
errTitle = 'UnkownError'
}
// 如果返回有错误信息 没有返回错误信息 用 UnkownError
const err = new Error(bkResponse?.message || 'UnkownError')
err.name = errTitle
// 抛出错误
throw err
}
return bkResponse
} catch (err) {
if (err instanceof AxiosError) {
ElMessage.error('网络错误') //ui弹出
}
throw err
} finally {
//关闭加载动画
loadingInstance.close()
}
}
// apis/login.ts 文件
import { $http } from '.'
/**
* 登录接口
*/
export const loginApi = (data: { password: string; username: string }) => {
return $http({
method: 'post',
url: '/admin/login',
data
})
}
使用 Mock来做拦截模拟数据
// main.ts 文件
// 引入mock文件
import './mock'
// src/mock/index.js 文件
import Mock from 'mockjs'
// import qs from 'qs'
// mock的配置
Mock.setup({
// 随机延时500-1000毫秒
timeout: '500-1000'
})
// 模拟接口,拦截请求
// 拦截请求,
// 第一个参数:url,使用正则去匹配
// 第二个参数:请求方式
// 第三个参数: 生成数据的函数
Mock.mock(/\/admin\/login/, 'post', config => {
// 切分请求体
// const queryString = config.url.split('?')[1]
// 获取请求参数
// const queryObject = qs.parse(queryString)
//设置返回数据
// const items = []
//生成数据
// for (let i = 0; i < +queryObject.pageSize; i++) {
// items.push(Mock.mock({
// id: '@id',
// name: '@ctitle(10,20)',
// desc: '@ctitle(4,10)',
// price: '@float(100,200,2,2)',
// // http://zhoushugang.gitee.io/erabbit-client-pc-static/uploads/clothes_goods_7.jpg
// picture: `http://zhoushugang.gitee.io/erabbit-client-pc-static/uploads/clothes_goods_${Mock.mock('@integer(1,8)')}.jpg`
// }))
// }
return {
data: {'token':'123456789'},
code: 200,
message: '非常完美',
succeed: true
}
})
//生成随机数据
// 单个数据
Mock.mock('@integer(0,7)')
// 对象数据
Mock.mock({
id: '@id',
name: '@ctitle(2,4)'
})
使用flex样式快速布局
<!-- src/views/LoginView.vue 文件 -->
<script setup lang="ts">
import { User, Lock } from '@element-plus/icons-vue'
</script>
<template>
<div id="login">
<div class="login-box">
<div class="logo">
<el-image
src="https://element-plus.gitee.io/images/element-plus-logo.svg"
fit="fill"
:lazy="true"
></el-image>
</div>
<el-form>
<el-form-item>
<el-input class="input" placeholder="请输入账号" :prefix-icon="User"></el-input>
</el-form-item>
<el-form-item>
<el-input class="input" placeholder="请输入密码" :prefix-icon="Lock"></el-input>
</el-form-item>
<div class="btns">
<el-button type="primary" class="btn">登录</el-button>
<div class="btn reset">重置</div>
</div>
</el-form>
</div>
</div>
</template>
<style scoped lang="scss">
#login {
height: 100vh;
background: linear-gradient(to right, #fce38a, #f38181);
display: flex;
justify-content: center;
align-items: center;
.login-box {
width: 360px;
height: 450px;
background-color: #fff;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
.logo {
display: flex;
justify-content: center;
align-items: center;
width: 120px;
height: 120px;
border-radius: 50%;
box-shadow: 0 0 4px 2px #f38181;
margin-bottom: 40px;
//overflow: hidden;
}
.el-form {
width: 90%;
margin-top: 30px;
.input {
height: 40px;
:deep(.el-input__wrapper) {
border-radius: 20px;
border: 3px solid #333;
}
}
.btns {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.btn {
width: 100%;
height: 40px;
border-radius: 22px;
margin-bottom: 20px;
cursor: pointer;
text-align: center;
}
}
}
}
}
</style>
表单数据校验
// src/rules/userinfo.ts 文件
// 表单校验规则
//校验规则对象接口
import type { FormRules } from 'element-plus'
export const rules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 10, message: '长度3-10', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 20, message: '长度6-20', trigger: 'blur' }
]
}
<!-- src/views/LoginView.vue 文件 -->
<script setup lang="ts">
import { User, Lock } from '@element-plus/icons-vue'
//form表单类接口
import type { FormInstance } from 'element-plus'
import { ref } from 'vue'
//引入校验规则
import { rules } from '@/rules/userinfo'
//表单数据接口
interface Form {
username: string
password: string
}
//表单数据
const form = ref<Form>({
username: '',
password: ''
})
//form表单对象
const formRef = ref<FormInstance>()
//清空表单数据
const reset = () => {
formRef.value?.resetFields()
}
// 登录功能
const login = async () => {
const res = await loginApi(form.value)
console.log(res)
}
</script>
<template>
<div id="login">
<div class="login-box">
<!-- 绑定表单对象 表单数据 表单校验规则 -->>
<el-form ref="formRef" :model="form" :rules="rules">
<!-- 绑定表单校验规则名 -->
<el-form-item prop="username">
<el-input
class="input"
v-model="form.username"
placeholder="请输入账号"
:prefix-icon="User"
></el-input>
</el-form-item>
<!-- 绑定表单校验规则名 -->
<el-form-item prop="password">
<el-input
class="input"
v-model="form.password"
placeholder="请输入密码"
:prefix-icon="Lock"
></el-input>
</el-form-item>
<div class="btns">
<el-button type="primary" class="btn" @click="login">登录</el-button>
<div class="btn reset" @click="reset">重置</div>
</div>
</el-form>
</div>
</div>
</template>
封装登录工具函数
// src/stores/userinfo.stor.ts 文件
import { request } from '@/apis'
import router from '@/router'
import { defineStore } from 'pinia'
export const useUserInfoStore = defineStore('userinfo-store', () => {
//设置用户登录信息
const setAuth = (token: string) => {
//设置到请求头里面
request.defaults.headers.common.Authorization = token
localStorage.setItem('token', token)
}
//判断用户是否登录
const authFormLocal = () => {
const token = localStorage.getItem('token')
if (token) {
setAuth(token)
//已登录
return true
}
//没有登录
return false
}
//清除本地用户信息
const removeAuth = () => {
//删除请求头里面的token
delete request.defaults.headers.common.Authorization
//删除本地存储的token
localStorage.removeItem('token')
//跳转到登录页面
router.push('/login')
}
return {
setAuth,
authFormLocal,
removeAuth
}
})
<!-- src/views/LoginView.vue 文件 -->
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { useUserInfoStore } from '@/stores/userinfo.store'
import router from '@/router'
// 登录功能
const login = async () => {
const res = await loginApi(form.value)
//设置登录信息
userInfoStore.setAuth(res.data.token)
//弹窗提示登录成功
ElMessage.success('登录成功')
// 跳转到home页面
router.push('/home')
}
</script>
完善路由前置守卫
import { useUserInfoStore } from '@/stores/userinfo.store'
const usrInfoStore = useUserInfoStore()
// 给 login页面添加一个meta参数 noAth 在在守卫出不进行阻拦
routes: [
{
path: '/login',
name: 'login',
meta: {
//添加的参数
noAuth: true
}
}
]
router.beforeEach((to, form, next) => {
if (to.meta.noAuth || usrInfoStore.authFormLocal()) {
next()
} else {
router.push('login')
}
})
异步引入 pinia 和 router
//main.ts 文件
//异步引入 pinia 和 router 因为 它们两个会互相引入 会报错
async function asyncRegister() {
const createPinia = (await import('pinia')).createPinia
app.use(createPinia())
const router = (await import('@/router')).default
app.use(router)
app.mount('#app')
}
asyncRegister()
主页布局 使用动态组件
<!-- views/HomeView.vue组件 -->
<script setup lang="ts">
import AdminHeader from '@/components/layout/AdminHeader.vue'
import AdminMenu from '@/components/layout/AdminMenu.vue'
</script>
<template>
<div class="home">
<el-container>
<el-header>
<AdminHeader></AdminHeader>
</el-header>
<el-container>
<el-affix>
<el-aside width="200px"><AdminMenu /></el-aside>
</el-affix>
<el-main> </el-main>
</el-container>
</el-container>
</div>
</template>
<style lan="scss" scoped>
#home {
min-height: 100vh;
}
.el-header {
background-color: #1f1f1f;
padding: 0;
}
.el-aside {
background-color: #2b2c44;
min-height: calc(100vh - 60px);
}
</style>
<!-- src\components\layout\AdminMenu.vue -->
<script setup lang="ts">
import type { Component } from 'vue'
import { House, User, Goods } from '@element-plus/icons-vue'
import { ElSubMenu, ElMenuItem } from 'element-plus'
interface MenuItem {
id: number
name: string
index: string
icon?: Component
children?: MenuItem[]
}
//菜单假数据
const menulist: MenuItem[] = [
{
id: 1,
name: '首页',
index: '/home/admin-home',
icon: House
},
{
id: 2,
name: '用户管理',
index: '/home/users',
icon: User
},
{
id: 101,
name: '商品管理',
index: '/prouduct-management',
icon: Goods,
children: [
{
id: 102,
name: '产品列表',
index: '/home/goods'
},
{
id: 103,
name: '品牌列表',
index: '/home/brand'
},
{
id: 104,
name: '类型列表',
index: '/home/type'
},
{
id: 105,
name: '颜色列表',
index: '/home/color'
},
{
id: 106,
name: '尺寸列表',
index: '/home/size'
}
]
}
]
</script>
<template>
<div id="menu">
<el-menu
active-text-color="#fff"
background-color="#2b2c44"
class="el-menu-vertical-demo"
default-active="2"
text-color="#fff"
router
>
<component
:is="item.children ? ElSubMenu : ElMenuItem"
v-for="item in menulist"
:key="item.id"
:index="item.index"
>
<template v-if="item.children" #title>
<el-icon v-if="item.icon">
<component :is="item.icon"></component>
</el-icon>
<span>{{ item.name }}</span>
</template>
<template v-if="!item.children">
<el-icon v-if="item.icon">
<component :is="item.icon"></component>
</el-icon>
<span>{{ item.name }}</span>
</template>
<el-menu-item v-for="subItem in item.children" :key="subItem.id" :index="subItem.index">
{{ subItem.name }}
</el-menu-item>
</component>
</el-menu>
</div>
</template>
<style scoped lang="scss"></style>
<!-- src\components\layout\AdminHeader.vue -->
<script setup lang="ts"></script>
<template>
<div id="header">
<div class="logo-box">adfad</div>
<div class="right-box">
<div class="title">后台管理系统</div>
<div class="avatar-box">
<el-avatar
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
fit="fill"
></el-avatar>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
#header {
background-color: #2b2c44;
color: #fff;
display: flex;
justify-content: space-between;
.logo-box {
width: 200px;
text-align: center;
line-height: 60px;
font-size: 22px;
font-weight: bold;
color: #e73267;
}
.right-box {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 18px;
.el-avatar {
margin-right: 10px;
}
}
}
</style>
用户信息布局
// 给home添加二级路由
{
path: '/home',
name: 'home',
component: HomeView,
children: [
{
path: 'admin-home',
name: 'admin-home',
component: () => import('@/components/home/AdminHome.vue')
},
{
path: 'users',
name: 'users',
component: () => import('@/components/users/UserManagement.vue')
},
{
path: 'goods',
name: 'goods',
component: () => import('@/components/goods/GoodsManagement.vue')
}
]
},
<!-- src\components\home\AdminHome.vue -->
<script setup lang="ts">
import AdminOverview from './adminHome/AdminOverview.vue'
import BarChart from './adminHome/BarChart.vue'
import LineChart from './adminHome/LineChart.vue'
import PieChart from './adminHome/PieChart.vue'
</script>
<template>
<div class="wrap">
<AdminOverview class="item"></AdminOverview>
<bar-chart class="item"></bar-chart>
<line-chart class="item"></line-chart>
<pie-chart class="item"></pie-chart>
</div>
</template>
<style scoped lang="scss">
.wrap {
display: flex;
flex-wrap: wrap;
box-shadow: var(--el-box-shadow-light);
.item {
width: 50%;
height: calc((100vh - 100px) / 2);
min-height: 360px;
border: 1px solid #eee;
box-sizing: border-box;
}
}
</style>
<!-- src\components\home\adminHome\AdminOverview.vue -->
<script setup lang="ts">
import { ref } from 'vue'
interface SingleData {
id: number
name: string
number: string
}
interface OverviewData {
allData: SingleData[]
orderData: SingleData[]
}
const overviewData = ref<OverviewData>({
allData: [
{
id: 1,
name: '总销售额',
number: '836,387'
},
{
id: 2,
name: '总访问量',
number: '1,342,629'
},
{
id: 3,
name: '总支付量',
number: '993,851'
},
{
id: 4,
name: '总收藏量',
number: '1,031,753'
}
],
orderData: [
{
id: 1,
name: '今日订单数',
number: '264'
},
{
id: 2,
name: '累计金额',
number: '3,564'
},
{
id: 3,
name: '本月订单数',
number: '4,523'
},
{
id: 4,
name: '累计金额',
number: '125,551'
}
]
})
</script>
<template>
<div id="overview">
<div class="userinfo">
<el-avatar
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
fit="fill"
></el-avatar>
<span class="username">xxx</span>
</div>
<div class="overview-list">
<div class="overview-item" v-for="item in overviewData.allData" :key="item.id">
<div class="title">{{ item.name }}</div>
<div class="num">{{ item.number }}</div>
</div>
</div>
<div class="overview-list">
<div class="overview-item" v-for="item in overviewData.allData" :key="item.id">
<div class="title">{{ item.name }}</div>
<div class="num">{{ item.number }}</div>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
#overview {
padding: 30px;
.userinfo {
display: flex;
align-items: center;
.username {
margin-left: 10px;
}
}
.overview-list {
margin-top: 40px;
display: flex;
justify-content: space-between;
.overview-item {
width: 22%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-shadow: var(--el-box-shadow-light);
border-radius: 10px;
padding: 20px;
.title {
font-weight: 700;
margin-bottom: 10px;
}
.num {
font-size: 18px;
}
}
}
}
</style>
用户信息展示
<!-- src\components\users\UserManagement.vue -->
<script setup lang="ts">
import { Search } from '@element-plus/icons-vue'
import { ref } from 'vue'
const keyword = ref<string>('')
interface User {
date: string
name: string
address: string
}
const handleEdit = (index: number, row: User) => {
console.log(index, row)
}
interface UserData {
avater: string
createTime: number
email: string
gender: number
id: number
integration: number
isDeleted: 0 | 1
nickname: string
password: string
phoneNumber: string
status: 0 | 1
updateTime: number
username: string
}
const tableData: UserData[] = [
{
avater: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
createTime: Date.now(),
email: '[email protected]',
gender: 0,
id: 1,
integration: 0,
isDeleted: 1,
nickname: '你是最棒的',
password: '123456',
phoneNumber: '123456',
status: 1,
updateTime: Date.now(),
username: '123456'
},
{
avater: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
createTime: Date.now(),
email: '[email protected]',
gender: 0,
id: 2,
integration: 0,
isDeleted: 1,
nickname: '你是最棒的',
password: '123456',
phoneNumber: '123456',
status: 1,
updateTime: Date.now(),
username: '123456'
},
{
avater: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
createTime: Date.now(),
email: '[email protected]',
gender: 0,
id: 3,
integration: 0,
isDeleted: 1,
nickname: '你是最棒的',
password: '123456',
phoneNumber: '123456',
status: 1,
updateTime: Date.now(),
username: '123456'
},
{
avater: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
createTime: Date.now(),
email: '[email protected]',
gender: 0,
id: 4,
integration: 0,
isDeleted: 1,
nickname: '你是最棒的',
password: '123456',
phoneNumber: '123456',
status: 1,
updateTime: Date.now(),
username: '123456'
}
]
</script>
<template>
<div id="users">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
</el-breadcrumb>
<el-card>
<div class="header">
<el-input
v-model="keyword"
style="max-width: 600px"
placeholder="请输入关键词"
class="input-with-select"
>
<template #append>
<el-button :icon="Search" />
</template>
</el-input>
</div>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="id" label="id" width="180"></el-table-column>
<el-table-column prop="username" label="用户名"></el-table-column>
<el-table-column prop="nickname" label="昵称"></el-table-column>
<el-table-column prop="gender" label="性别">
<template #default="scope">
<div style="display: flex; align-items: center">
<span>{{ scope.row.gender === 0 ? '男' : '女' }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="头像" width="180">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-avatar
icon="el-icon-user-solid"
size="large"
shape="circle"
:src="scope.row.avater"
fit="fill"
></el-avatar>
</div>
</template>
</el-table-column>
<el-table-column prop="email" label="邮箱"></el-table-column>
<el-table-column prop="phoneNumber" label="手机号"></el-table-column>
<el-table-column label="状态" width="180">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-switch v-model="scope.row.isDeleted" />
</div>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页数据 -->
<el-pagination small layout="prev, pager, next" :total="10" />
<!-- 可选分页数据 -->
<!-- <el-pagination
v-model:current-page="当前页"
v-model:page-size="页面数据"
:page-sizes="[100, 200, 300, 400]"
layout="total, sizes, prev, pager, next, jumper"
:total="总数据"
@size-change="条目数改变的时候触发"
@current-change="handleCurrentChange"
/> -->
</el-card>
</div>
</template>
<style scoped lang="scss">
#users {
.el-breadcrumb {
margin-bottom: 20px;
}
.header {
.el-input {
width: 30%;
}
}
}
</style>
标签:初始化,vue,const,name,项目,home,import,id
From: https://www.cnblogs.com/henordinary/p/18130098