做网站和推广公司,做网站的如何增加电话量,苏州学习网站建设,网站不备案做seo没用目录 首页 layout 架子 [element-plus 菜单]
基本架子拆解
登录访问拦截
用户基本信息获取渲染
退出功能 [element-plus 确认框]
文章分类页面 - [element-plus 表格]
基本架子 - PageContainer
文章分类渲染
封装API - 请求获取表格数据
el-table 表格动态渲染 …
目录 首页 layout 架子 [element-plus 菜单]
基本架子拆解
登录访问拦截
用户基本信息获取渲染
退出功能 [element-plus 确认框]
文章分类页面 - [element-plus 表格]
基本架子 - PageContainer
文章分类渲染
封装API - 请求获取表格数据
el-table 表格动态渲染
el-table 表格 loading 效果
文章分类添加编辑 [element-plus 弹层]
点击显示弹层
封装弹层组件 ChannelEdit
准备弹层表单
确认提交
文章分类删除 首页 layout 架子 [element-plus 菜单]
基本架子拆解
架子组件列表
el-container el-aside 左侧 el-menu 左侧边栏菜单 el-container 右侧 el-header 右侧头部 el-dropdownel-main 右侧主体 router-view
script setup
import {Management,Promotion,UserFilled,User,Crop,EditPen,SwitchButton,CaretBottom
} from element-plus/icons-vue
import avatar from /assets/default.png
/scripttemplateel-container classlayout-containerel-aside width200pxdiv classel-aside__logo/divel-menuactive-text-color#ffd04bbackground-color#232323:default-active$route.pathtext-color#fffrouterel-menu-item index/article/channelel-iconManagement //el-iconspan文章分类/span/el-menu-itemel-menu-item index/article/manageel-iconPromotion //el-iconspan文章管理/span/el-menu-itemel-sub-menu index/usertemplate #titleel-iconUserFilled //el-iconspan个人中心/span/templateel-menu-item index/user/profileel-iconUser //el-iconspan基本资料/span/el-menu-itemel-menu-item index/user/avatarel-iconCrop //el-iconspan更换头像/span/el-menu-itemel-menu-item index/user/passwordel-iconEditPen //el-iconspan重置密码/span/el-menu-item/el-sub-menu/el-menu/el-asideel-containerel-headerdiv黑马程序员strong小帅鹏/strong/divel-dropdown placementbottom-endspan classel-dropdown__boxel-avatar :srcavatar /el-iconCaretBottom //el-icon/spantemplate #dropdownel-dropdown-menuel-dropdown-item commandprofile :iconUser基本资料/el-dropdown-itemel-dropdown-item commandavatar :iconCrop更换头像/el-dropdown-itemel-dropdown-item commandpassword :iconEditPen重置密码/el-dropdown-itemel-dropdown-item commandlogout :iconSwitchButton退出登录/el-dropdown-item/el-dropdown-menu/template/el-dropdown/el-headerel-mainrouter-view/router-view/el-mainel-footer大事件 ©2023 Created by 黑马程序员/el-footer/el-container/el-container
/templatestyle langscss scoped
.layout-container {height: 100vh;.el-aside {background-color: #232323;__logo {height: 120px;background: url(/assets/logo.png) no-repeat center / 120px auto;}.el-menu {border-right: none;}}.el-header {background-color: #fff;display: flex;align-items: center;justify-content: space-between;.el-dropdown__box {display: flex;align-items: center;.el-icon {color: #999;margin-left: 10px;}:active,:focus {outline: none;}}}.el-footer {display: flex;align-items: center;justify-content: center;font-size: 14px;color: #666;}
}
/style登录访问拦截
需求只有登录页可以未授权的时候访问其他所有页面都需要先登录再访问
// 登录访问拦截
router.beforeEach((to) {const userStore useUserStore()if (!userStore.token to.path ! /login) return /login
})用户基本信息获取渲染
api/user.js封装接口
export const userGetInfoService () request.get(/my/userinfo)stores/modules/user.js 定义数据
const user ref({})
const getUser async () {const res await userGetInfoService() // 请求获取数据user.value res.data.data
}layout/LayoutContainer页面中调用
import { useUserStore } from /stores
const userStore useUserStore()
onMounted(() {userStore.getUser()
})动态渲染
div黑马程序员strong{{ userStore.user.nickname || userStore.user.username }}/strong
/divel-avatar :srcuserStore.user.user_pic || avatar /退出功能 [element-plus 确认框]
注册点击事件
el-dropdown placementbottom-end commandonCommandel-dropdown-menuel-dropdown-item commandprofile :iconUser基本资料/el-dropdown-itemel-dropdown-item commandavatar :iconCrop更换头像/el-dropdown-itemel-dropdown-item commandpassword :iconEditPen重置密码/el-dropdown-itemel-dropdown-item commandlogout :iconSwitchButton退出登录/el-dropdown-item
/el-dropdown-menu添加退出功能
const onCommand async (command) {if (command logout) {await ElMessageBox.confirm(你确认退出大事件吗, 温馨提示, {type: warning,confirmButtonText: 确认,cancelButtonText: 取消})userStore.removeToken()userStore.setUser({})router.push(/login)} else {router.push(/user/${command})}
}pinia user.js 模块 提供 setUser 方法
const setUser (obj) (user.value obj)文章分类页面 - [element-plus 表格]
基本架子 - PageContainer
基本结构样式用到了 el-card 组件
templateel-card classpage-containertemplate #headerdiv classheaderspan文章分类/spandiv classextrael-button typeprimary添加分类/el-button/div/div/template.../el-card
/templatestyle langscss scoped
.page-container {min-height: 100%;box-sizing: border-box;.header {display: flex;align-items: center;justify-content: space-between;}
}
/style考虑到多个页面复用封装成组件 props 定制标题默认插槽 default 定制内容主体具名插槽 extra 定制头部右侧额外的按钮
script setup
defineProps({title: {required: true,type: String}
})
/scripttemplateel-card classpage-containertemplate #headerdiv classheaderspan{{ title }}/spandiv classextraslot nameextra/slot/div/div/templateslot/slot/el-card
/templatestyle langscss scoped
.page-container {min-height: 100%;box-sizing: border-box;.header {display: flex;align-items: center;justify-content: space-between;}
}
/style页面中直接使用测试 ( unplugin-vue-components 会自动注册)
文章分类测试
templatepage-container title文章分类template #extrael-button typeprimary 添加分类 /el-button/template主体部分/page-container
/template文章管理测试
templatepage-container title文章管理template #extrael-button typeprimary发布文章/el-button/template主体部分/page-container
/template文章分类渲染
封装API - 请求获取表格数据
新建 api/article.js 封装获取频道列表的接口
import request from /utils/request
export const artGetChannelsService () request.get(/my/cate/list)页面中调用接口获取数据存储
const channelList ref([])const getChannelList async () {const res await artGetChannelsService()channelList.value res.data.data
}el-table 表格动态渲染
el-table :datachannelList stylewidth: 100%el-table-column label序号 width100 typeindex /el-table-columnel-table-column label分类名称 propcate_name/el-table-columnel-table-column label分类别名 propcate_alias/el-table-columnel-table-column label操作 width100template #default{ row }el-button:iconEditcircleplaintypeprimaryclickonEditChannel(row)/el-buttonel-button:iconDeletecircleplaintypedangerclickonDelChannel(row)/el-button/template/el-table-columntemplate #emptyel-empty description没有数据 //template
/el-tableconst onEditChannel (row) {console.log(row)
}
const onDelChannel (row) {console.log(row)
}el-table 表格 loading 效果
定义变量v-loading绑定
const loading ref(false)el-table v-loadingloading发送请求前开启请求结束关闭
const getChannelList async () {loading.value trueconst res await artGetChannelsService()channelList.value res.data.dataloading.value false
}文章分类添加编辑 [element-plus 弹层]
点击显示弹层
准备弹层
const dialogVisible ref(false)el-dialog v-modeldialogVisible title添加弹层 width30%div我是内容部分/divtemplate #footerspan classdialog-footerel-button clickdialogVisible false取消/el-buttonel-button typeprimary 确认 /el-button/span/template
/el-dialog点击事件
template #extrael-button typeprimary clickonAddChannel添加分类/el-button/templateconst onAddChannel () {dialogVisible.value true
}封装弹层组件 ChannelEdit
添加 和 编辑可以共用一个弹层所以可以将弹层封装成一个组件
组件对外暴露一个方法 open, 基于 open 的参数初始化表单数据并判断区分是添加 还是 编辑
open({ }) 添加操作添加表单初始化无数据open({ id: xx, … }) 编辑操作编辑表单初始化需回显
具体实现
封装组件 article/components/ChannelEdit.vue
script setup
import { ref } from vue
const dialogVisible ref(false)const open async (row) {dialogVisible.value trueconsole.log(row)
}defineExpose({open
})
/scripttemplateel-dialog v-modeldialogVisible title添加弹层 width30%div我是内容部分/divtemplate #footerspan classdialog-footerel-button clickdialogVisible false取消/el-buttonel-button typeprimary 确认 /el-button/span/template/el-dialog
/template通过 ref 绑定
const dialog ref()!-- 弹窗 --
channel-edit refdialog/channel-edit点击调用方法显示弹窗
const onAddChannel () {dialog.value.open({})
}
const onEditChannel (row) {dialog.value.open(row)
}准备弹层表单
准备数据 和 校验规则
const formModel ref({cate_name: ,cate_alias:
})
const rules {cate_name: [{ required: true, message: 请输入分类名称, trigger: blur },{pattern: /^\S{1,10}$/,message: 分类名必须是1-10位的非空字符,trigger: blur}],cate_alias: [{ required: true, message: 请输入分类别名, trigger: blur },{pattern: /^[a-zA-Z0-9]{1,15}$/,message: 分类别名必须是1-15位的字母数字,trigger: blur}]
}准备表单
el-form:modelformModel:rulesruleslabel-width100pxstylepadding-right: 30px
el-form-item label分类名称 propcate_nameel-inputv-modelformModel.cate_nameminlength1maxlength10/el-input/el-form-itemel-form-item label分类别名 propcate_aliasel-inputv-modelformModel.cate_aliasminlength1maxlength15/el-input/el-form-item
/el-form编辑需要回显表单数据需要初始化
const open async (row) {dialogVisible.value trueformModel.value { ...row }
}基于传过来的表单数据进行标题控制有 id 的是编辑
:titleformModel.id ? 编辑分类 : 添加分类确认提交
api/article.js 封装请求 API
// 添加文章分类
export const artAddChannelService (data) request.post(/my/cate/add, data)
// 编辑文章分类
export const artEditChannelService (data) request.put(/my/cate/info, data)页面中校验判断提交请求
el-form refformRefconst formRef ref()
const onSubmit async () {await formRef.value.validate()formModel.value.id? await artEditChannelService(formModel.value): await artAddChannelService(formModel.value)ElMessage({type: success,message: formModel.value.id ? 编辑成功 : 添加成功})dialogVisible.value false
}通知父组件进行回显
const emit defineEmits([success])const onSubmit async () {...emit(success)
}父组件监听 success 事件进行调用回显
channel-edit refdialog successonSuccess/channel-editconst onSuccess () {getChannelList()
}文章分类删除
api/article.js封装接口 api
// 删除文章分类
export const artDelChannelService (id) request.delete(/my/cate/del, {params: { id }})页面中添加确认框调用接口进行提示
const onDelChannel async (row) {await ElMessageBox.confirm(你确认删除该分类信息吗, 温馨提示, {type: warning,confirmButtonText: 确认,cancelButtonText: 取消})await artDelChannelService(row.id)ElMessage({ type: success, message: 删除成功 })getChannelList()
}