使用element-plus
element-plus官网: 一个 Vue 3 UI 框架 | Element Plus
-
安装
pnpm install normalize.css
pnpm install element-plus
pnpm install @element-plus/icons-vue
-
在main.ts中引入
...
//全局引入element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'normalize.css'
//全局引入图标
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
//注册element-plus
app.use(ElementPlus)
//注册图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.mount('#app')
-
element-plus中图标的使用
<script setup> </script> <template> <div class="admin"> <!-- 编辑图标 --> <el-icon :size="20"> <Edit /> </el-icon> <el-row> <!-- 在按钮上显示编辑图标 --> <el-button circle type="primary"> <el-icon > <Edit /> </el-icon> </el-button> </el-row> </div> </template>
-
使用动态图标
<script setup> //定义数据 const icons = ref(['edit','CirclePlus','Clock','Position']) const props = defineProps({ item: Object, index: Number }) console.log('index',props.index); </script> <template> <div class="card"> <p >图标: <!-- <el-icon> <Edit /> </el-icon> --> <!-- 通过component动态组件实现 --> <component :is="icons[index]"></component> </p> <p>{{ item.title }}---</p> <p>{{ item.count }}</p> </div> </template> <style lang='scss' scoped> .card { border: 1px solid #000; // !!!!!注意样式用svg标签 svg { width: 20px; height: 20px; } } </style>
-
Menu菜单
<el-menu> <!-- 没有子菜单 --> <el-menu-item index="/dashboard"> <el-icon> <CirclePlus /> </el-icon> <span slot="title">首页</span> </el-menu-item> <!-- 有子菜单,注意标签和插槽的使用 --> <el-sub-menu index="/charts"> <template #title> <el-icon> <CirclePlus /> </el-icon> <span>图表管理</span> </template> <el-menu-item index="/charts/bar"> <el-icon> <CirclePlus /> </el-icon> <span >柱状图</span> </el-menu-item> <el-menu-item index="/charts/pie"> <el-icon> <CirclePlus /> </el-icon> <span>饼图</span> </el-menu-item> </el-sub-menu> </el-menu>
-
Message消息提示
<script lang="ts" setup> ... //引用Message组件 import { ElMessage } from 'element-plus' ... //使用Message ElMessage.success("登录成功");
-
表单-登录页面
注意需要自己解决的ts
let { query: {redirectUrl} } = route; // 深层的解构赋值 if (redirectUrl) { router.replace(redirectUrl); } else { router.replace("/") } ruleFormRef.value?.resetFields();
完整代码如下:
<script lang="ts" setup> import { reactive, ref, nextTick} from 'vue' import { useRouter, useRoute} from 'vue-router' import { ElMessage } from 'element-plus' import { login } from "@/api/http"; const router = useRouter() const route = useRoute() const ruleFormRef = ref() const ruleForm = reactive({ account: '', pw: '', }) const rules = reactive({ account: [ { required: true, message: "不能为空", trigger: "blur" }, { pattern: /^\w{3,5} $/, message: "必须是3-5位的字符", trigger: "blur", }, ], pw: [ { required: true, message: "不能为空", trigger: "blur" }, { pattern: /^\d{3,6}$/, message: "必须是3-6位的纯数字", trigger: "blur", }, ], }) const handleValid = async () => { try { //当数据都有效时,调用后端接口,进行登录验证 let res = await login(ruleForm); let { code, token } = res.data; if (code === 200) { // console.log('login-role',role); //登录成功 数据持久化 sessionStorage.setItem("token", token); ElMessage.success("登录成功"); // 登录的分类讨论: // 1. 首次登录,没有参数redirectUrl, 登录成功后进入首页 // 2. 退出登录后再次登录,有参数redirectUrl,登录成功后进入上一次退出登录的那个路由 let { query: {redirectUrl} } = route; if (redirectUrl) { // as 类型断言 router.replace(redirectUrl); } else { router.replace("/"); } } else { //登录失败 ElMessage.error("登录失败"); ruleFormRef.value?.resetFields(); } } catch (err: any) { if (err.code === 'ERR_NETWORK') { ElMessage.error("网络错误,请重试"); } } } const submitForm = (formEl) => { if (!formEl) return formEl.validate((valid) => { if (valid) { console.log('submit!') handleValid(); } else { console.log('error submit!') return false } }) } const resetForm = (formEl) => { if (!formEl) return formEl.resetFields() } </script> <template> <div class="login"> <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleFormRef" class="form"> <!-- 账号 --> <el-form-item prop="account"> <el-input type="text" placeholder="请输入账号" prefix-icon="el-icon-user-solid" v-model="ruleForm.account" autocomplete="off"></el-input> </el-form-item> <!-- 密码 --> <el-form-item prop="pw"> <el-input type="text" placeholder="请输入密码" prefix-icon="el-icon-lock" v-model="ruleForm.pw" autocomplete="off"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm(ruleFormRef)">提交</el-button> </el-form-item> </el-form> </div> </template> <style lang='scss' scoped> </style>