0


vue工程项目案例(图书管理+用户管理) vue-router + element ui Plus

提示:文章有点长,请各位小伙伴耐心观看

文章目录


效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、准备工作

1、创建vue3的工程文件

npm init vue@latest
Attention!!!:一步一步按照老师教的来、值得注意的事我并未选择eslint校验工具,因为在日常开放中会很麻烦。

1、创建对应目录文件

在这里插入图片描述

主页!!!!!!:只要是上面没有的文件全部删除

然后直接跳到 第三步的1、编写index.js(可以直接复制,前提是以上一、二步骤完成或者上面目录对应创建)

2、修改全局样式

1、删除src下的assets下的样式文件 只保留svg文件
2、在src下的main.js中注释掉 import ‘./assets/main.css’
// import './assets/main.css'import{ createApp }from'vue'import{ createPinia }from'pinia'import App from'./App.vue'import router from'./router'const app =createApp(App)

app.use(createPinia())
app.use(router)

app.mount('#app')
3、删除app.vue里面的style以及其他不必要组件
<scriptsetup>import{ RouterLink, RouterView }from'vue-router'</script><template><RouterView/></template><stylescoped></style>

2、安装element ui Plus

(1)、进入element官网element ui Plus
(2)、点击指南找到安装中的使用包管理器

npm install element-plus --save

(3)、全局引入 element ui

// main.jsimport{ 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')

二、开始编写基本页面

1、头部导航编写

使用element ui组件库搭建更快哟

(1)在src文件夹下的component文件夹下新建BarComponent.vue文件
(2)编写

这里我们使用的是vue3.2的写法

1.1、创建3.2vue模版

<template></template><scriptsetup>//在script 标签上加入 setup 语法糖</script><stylescoped>/*在style上加伤scoped 防止样式干扰*/</style>

1.2、在BarComponent.vue文件中使用 element ui Plus 的 Navigation 导航 中的 Menu 组件

在官网点击组件 在侧边导航栏找到 Navigation 导航 再找到 Menu

在这里插入图片描述
将以上源代码全部复制到 BarComponent.vue 中

<template><el-menu:default-active="activeIndex"class="el-menu-demo"mode="horizontal":ellipsis="false"@select="handleSelect"><el-menu-itemindex="0">LOGO</el-menu-item><divclass="flex-grow"/><el-menu-itemindex="1">Processing Center</el-menu-item><el-sub-menuindex="2"><template#title>Workspace</template><el-menu-itemindex="2-1">item one</el-menu-item><el-menu-itemindex="2-2">item two</el-menu-item><el-menu-itemindex="2-3">item three</el-menu-item><el-sub-menuindex="2-4"><template#title>item four</template><el-menu-itemindex="2-4-1">item one</el-menu-item><el-menu-itemindex="2-4-2">item two</el-menu-item><el-menu-itemindex="2-4-3">item three</el-menu-item></el-sub-menu></el-sub-menu></el-menu></template><scriptlang="ts"setup>import{ ref }from'vue'const activeIndex =ref('1')consthandleSelect=(key: string,keyPath: string[])=>{
  console.log(key, keyPath)}</script><style>.flex-grow{flex-grow: 1;}</style>

·注意:这里面的script标签没有

lang = 'ts'

因为我们并未下载 typescript 的解析因此不能使用它

注意 !!!:毫无疑问会报错,因为这是使用的 typescript 的类型校验写法 因此我们需要对他进行改动

在这里插入图片描述

1.3、修改报错部分

删除类型教研即可

<script setup>consthandleSelect=(key, keyPath)=>{
  console.log(key, keyPath)}</script>

1.4、改造模版

因为他自己的模版是和我们的有差距因此我们需要改一下

<divclass="bar"><el-menu:default-active="activeIndex"class="el-menu-demo"mode="horizontal":ellipsis="false"@select="handleSelect"><el-menu-itemindex="0"><el-avatar>LOGO</el-avatar></el-menu-item><divclass="flex-grow"/><el-menu-itemindex='1'>登陆</el-menu-item><el-menu-itemindex='2'>注册</el-menu-item><el-menu-itemindex='3'>首页</el-menu-item><el-menu-itemindex='4'>退出登陆</el-menu-item></el-menu></div>

1.5、加入跳转效果

这里我们需要在 menu 上加上 :router=‘true’,这样导航栏就有了router跳转的功能,其中index就是跳转的地址

<divclass="bar"><el-menu:default-active="activeIndex"class="el-menu-demo"mode="horizontal":ellipsis="false"@select="handleSelect":router='true'><el-menu-itemindex="0"><el-avatar>LOGO</el-avatar></el-menu-item><divclass="flex-grow"/><el-menu-itemindex='1'>登陆</el-menu-item><el-menu-itemindex='2'>注册</el-menu-item><el-menu-itemindex='3'>首页</el-menu-item><el-menu-itemindex='4'>退出登陆</el-menu-item></el-menu></div>

现在的导航基本完成

2.注册页面编写

(1)在src目录下的view目录下新建RegisterView.vue文件
(2)编写
(2.1)这里的输入框以及按钮我也是使用的element UI

<template><divclass="content"><div><divstyle="color:aliceblue"><h2>welcome to Register</h2></div><div><!-- element UI 组件库的input输入框--><el-inputv-model="username"placeholder="Please input"clearable/></div><divstyle="margin: 10px 0;"><!-- element UI 组件库的input密码框--><el-inputv-model="password"type="password"placeholder="Please input password"show-password/></div><div><!-- element UI 组件库的按钮--><el-button@click="Login()"type="primary">Register</el-button></div></div></div></template><scriptsetup>import{ ref }from'vue';//改良一下可以使用 类的方式书写let username =ref('')let password =ref('')let user =ref({})//用户对象let userArray =ref([])//用户数组 存储所有的用户functionLogin(){
    user.value.name = username.value
    user.value.password = password.value
    //本地存储不过多解释// 需要注意的是 存数组或对象 要把他们转化成字符串 取的时候又要把字符串还原if(JSON.parse(localStorage.getItem('userA'))!=null){
        userArray.value =JSON.parse(localStorage.getItem('userA'))}
    userArray.value.push(user.value)
      localStorage.setItem('userA',JSON.stringify(userArray.value))}</script><stylescoped>.content{/* width: 500%; */background-size: 500%;height: 90vh;display: flex;justify-content: center;align-items: center;background:linear-gradient(125deg,#29c55b,#328be5,#6130e6,#b831e1);animation: bcColor 1s linear infinite;}@keyframes bcColor{0%{background-position: 0% 50%;};
    50%{background-position: 100% 50%;};
    100%{background-position: 0% 50%;}}.content >div>div{display: flex;justify-content: center;}.content>div>div>button{height: 34px;width: 230px;text-align: center;/* color: aliceblue; */font-size: 18px;margin: 5px 0;}button:hover{letter-spacing: 3px;}</style>

3.登陆页面编写

(1)在src目录下的view目录下新建LoginView.vue文件
(2)编写
(2.1)这里的输入框以及登陆按钮我也是使用的element UI

<template><divclass="content"><div><divstyle="color:aliceblue"><h2>welcome to login</h2></div><div><!-- element UI 组件库的input输入框--><el-inputv-model="username"placeholder="Please input"clearable/></div><divstyle="margin: 10px 0;"><!-- element UI 组件库的input密码框--><el-inputv-model="password"type="password"placeholder="Please input password"show-password/></div><div><!-- element UI 组件库的按钮--><el-button@click="Login()"type="primary">Login</el-button></div></div></div></template><scriptsetup>import{ ref }from'vue';import{ useRouter, useRoute }from'vue-router'//引入路由const router =useRouter()const route =useRoute()let username =ref('')let password =ref('')functionLogin(){//得到本地存储的 user 数组let user =JSON.parse(localStorage.getItem('userA'))//遍历 user 数组
    user.forEach(el=>{// 比较数组中是否有我登陆的信息 有就登陆成功if(el.name == username.value && el.password == password.value){
            localStorage.setItem('token',`${username.value}/${password.value}`)// 跳转到主页面// router.push({//    path:'main'// })}});}</script><stylescoped>.content{/* width: 500%; */background-size: 500%;height: 90vh;display: flex;justify-content: center;align-items: center;background:linear-gradient(125deg,#29c55b,#328be5,#6130e6,#b831e1);animation: bcColor 1s linear infinite;}@keyframes bcColor{0%{background-position: 0% 50%;};
    50%{background-position: 100% 50%;};
    100%{background-position: 0% 50%;}}.content >div>div{display: flex;justify-content: center;}.content>div>div>button{height: 34px;width: 210px;text-align: center;/* color: aliceblue; */font-size: 18px;margin: 5px 0;}button:hover{letter-spacing: 3px;}</style>

4.主页面编写

(1)在src目录下的view目录下新建MainView.vue文件
(2)编写
(2.1)这里的输入框以及按钮我也是使用的element UI
代码如下(示例):

<template><divclass="content"><!--element ui tab组件--><el-tabs:tab-position="tabPosition"style="height: 90vh"class="demo-tabs"><el-tab-panelabel="图书管理"><BookCViewVue></BookCViewVue></el-tab-pane><el-tab-panelabel="用户管理"><UserCViewVue></UserCViewVue></el-tab-pane></el-tabs></div></template><scriptsetup>import{ ref }from'vue'import BookCViewVue from'./ControlView/BookCView.vue'import UserCViewVue from'./ControlView/UserCView.vue'const tabPosition =ref('left')</script><stylescoped>.demo-tabs > .el-tabs__content{padding: 32px;color: #6b778c;font-size: 32px;font-weight: 600;}.el-tabs--right .el-tabs__content,
  .el-tabs--left .el-tabs__content{height: 100%;}</style>

5.home页面的编写

(1)在src目录下的view目录下新建HomeView.vue文件
(2)编写
(2.1)这里的输入框以及按钮我也是使用的element UI

<template><divclass="content"><!--头部导航--><el-affix:offset="0"><divclass="bar"><BarCmpVue></BarCmpVue></div></el-affix><!-- 导航对应内容部分--><div><RouterView></RouterView></div></div></template><scriptsetup>import{ RouterView}from'vue-router'import BarCmpVue from'../components/BarComponent.vue'</script>

该处使用的url网络请求的数据。


三、开始编写路由

1、编写index.js(可以直接复制,前提是以上一、二步骤完成)

import{ createRouter, createWebHistory }from'vue-router'import HomeView from'../views/HomeView.vue'const router =createRouter({history:createWebHistory(import.meta.env.BASE_URL),routes:[{path:'/',name:'home',component: HomeView,redirect:'/login',children:[{// 当 /user/:id/profile 匹配成功// UserProfile 将被渲染到 User 的 <router-view> 内部path:'main',component:()=>import('../views/MainView.vue'),},{// 当 /user/:id/profile 匹配成功// UserProfile 将被渲染到 User 的 <router-view> 内部path:'login',component:()=>import('../views/LoginView.vue'),},{// 当 /user/:id/profile 匹配成功// UserProfile 将被渲染到 User 的 <router-view> 内部path:'register',component:()=>import('../views/Register.vue'),}]},{path:'/about',name:'about',// route level code-splitting// this generates a separate chunk (About.[hash].js) for this route// which is lazy-loaded when the route is visited.component:()=>import('../views/AboutView.vue')},{path:'/look',name:'look',// route level code-splitting// this generates a separate chunk (About.[hash].js) for this route// which is lazy-loaded when the route is visited.component:()=>import('../views/LookBookView.vue')},]})
router.beforeEach(async(to,from)=>{if(to.path ==='/login')return;if(to.path ==='/register')return;//获取tokenconst tokenStr = localStorage.getItem('token')if(!tokenStr || tokenStr =='null')return'/login'// next()})exportdefault router

2、编写头部导航的路由对应关系

<template><divclass="bar"><!--
         :default-active 默认显示的页面路由
         @select="handleSelect" 选择导航时出发的事件
    --><el-menu:default-active="activeIndex"class="el-menu-demo"mode="horizontal":ellipsis="false"@select="handleSelect":router="true"style="height: 10vh;"><el-menu-itemindex="0"><!--头像组件--><el-avatar> {{ userTitle[0] }} </el-avatar></el-menu-item><divclass="flex-grow"/><!--这里我们使用v-for循环的方式--><el-menu-itemv-for="(p,index) in path":index="p.path":key="index">{{ p.name }}</el-menu-item><el-menu-item@click="logout()">退出登陆</el-menu-item></el-menu></div></template><scriptsetup>import{ onMounted, ref }from'vue'import{ useRouter, useRoute }from'vue-router'const router =useRouter()const route =useRoute()const path =ref([{name:'登陆',path:'login'},{name:'注册',path:'register'},{name:'首页',path:'main'},])constlogout=()=>{
    localStorage.setItem('token',null)
    router.push({path:'login'})}const userTitle =ref('')const activeIndex =ref('login')//组件对应的方法consthandleSelect=(key, keyPath)=>{
        activeIndex.value = key
        localStorage.setItem('path',activeIndex.value)}onMounted(()=>{
        activeIndex.value = localStorage.getItem('path')
        userTitle.value = localStorage.getItem('token')if(userTitle.value =='null'){
            router.push({path:'login'})}})</script><stylescoped>.flex-grow{flex-grow: 1;}</style>

在这里插入图片描述

四、开始编写主页对应关系页面

以下部分有难度的

element ui官方文档
在 view目录下新建ControlView目录并在目录下新建BookCView.vue / UserCView.vue文件

1、编写BookCView.vue文件(图书管理)

<template><!--使用的是element ui里main的table组件--><el-table:data="filterTableData"style="width: 100%;":stripe="true":border="true"><el-table-columnalign="center"label="添加时间"prop="date"/><el-table-columnalign="center"label="书名"prop="bookName"/><!-- <el-table-column align="center" label="详情" prop="textarea" /> --><el-table-columnalign="center"label="作者"prop="authorName"/><el-table-columnalign="center"><template#header><divstyle="display: flex;justify-content: space-around;"><el-button@click="addBook()">添加图书</el-button><el-inputv-model="search"size="small"placeholder="查找图书"style="margin-left: 10px;"/></div></template><template#default="scope"><el-buttonsize="small"@click="handleEdit(scope.$index, scope.row)"type="primary">编辑信息</el-button><el-buttonsize="small"@click="gotolook(scope.$index, scope.row)"type="success">查看图书</el-button><el-buttonsize="small"type="danger"@click="handleDelete(scope.$index, scope.row)">删除图书</el-button></template></el-table-column></el-table><el-dialogv-model="dialogVisible"title="图书添加"width="80%"style="height: 500px;"><el-inputv-model="bookName"placeholder="输入书名"clearablestyle="margin-bottom: 10px;"/><el-inputv-model="textarea":rows="13"type="textarea"placeholder="输入内容"/><template#footer><spanclass="dialog-footer"><el-button@click="dialogVisible = false">Cancel</el-button><el-buttontype="primary"@click="add()">
            Confirm
            </el-button></span></template></el-dialog><el-dialogv-model="dialogVisible11"title="图书编辑"width="80%"style="height: 500px;"><el-inputv-model="bookName"placeholder="输入书名"clearablestyle="margin-bottom: 10px;"/><el-inputv-model="textarea":rows="13"type="textarea"placeholder="输入内容"/><template#footer><spanclass="dialog-footer"><el-button@click="dialogVisible11 = false">Cancel</el-button><el-buttontype="primary"@click="change()">
            Confirm
            </el-button></span></template></el-dialog></template><scriptsetup>import{ useRouter, useRoute }from'vue-router'import{ computed, onMounted, ref }from'vue'import{ ElMessage }from'element-plus'constopen2=()=>{ElMessage({message:'操作成功',type:'success',})}constopen4=()=>{
        ElMessage.error('操作失败')}const dialogVisible =ref(false)const dialogVisible11 =ref(false)const search =ref('')//查找let bookName =ref('')//书名let textarea =ref('')//内容let bookMsg =ref({})//空书信息let tableData=[]let indexxx =nullconsthandleEdit=(index, row)=>{
    dialogVisible11.value =true
    bookName.value = row.bookName
    textarea.value = row.textarea
    indexxx = index
  }const router =useRouter()const route =useRoute()constgotolook=(index,row)=>{
      router.push({path:'look',query:{id:index},})}// 编辑图书constchange=()=>{
    tableData[indexxx].bookName = bookName.value
    tableData[indexxx].textarea = textarea.value
    localStorage.setItem('bookA',JSON.stringify(tableData))
    dialogVisible11.value =falseopen2()}// 删除图书consthandleDelete=(index, row)=>{
    console.log(index, row)
    tableData.splice(index,1)
    localStorage.setItem('bookA',JSON.stringify(tableData))okk()}constaddBook=()=>{
    dialogVisible.value =true}//   添加图书constadd=()=>{if( bookName.value !=''&& textarea.value !=''){
       bookMsg.value.date =newDate
       bookMsg.value.bookName = bookName.value
       bookMsg.value.textarea = textarea.value
       bookMsg.value.authorName = localStorage.getItem('token').split('/')[0]
       tableData.push(bookMsg.value)
       localStorage.setItem('bookA',JSON.stringify(tableData))open2()
       dialogVisible.value =false}else{open4()}}//判断是否有//搜索let filterTableData  =ref([])if(localStorage.getItem('bookA')!=null){
    tableData =JSON.parse(localStorage.getItem('bookA'))
    filterTableData =computed(()=>
    tableData.filter((data)=>!search.value ||
        data.bookName.toLowerCase().includes(search.value.toLowerCase())))}</script><stylescoped></style>

2、编写UserCView.vue文件(用户管理)

<template><div><tablestyle="border-collapse:collapse;"><trclass="title"><td>序号</td><td>姓名</td><td>密码</td><td>操作</td></tr><trv-for="(u,index) in dataUser":key="index"><td>{{ index+1 }}</td><td>{{ u.name }}</td><td>{{ u.password }}</td><tdstyle="font-weight: 400;"><el-buttonstyle="font-weight: 400;"size="small"type="primary"@click="change(u,index)">编辑</el-button><el-buttonstyle="font-weight: 400;"size="small"type="success"@click="show(u)">查看</el-button><el-buttonstyle="font-weight: 400;"size="small"type="danger"@click="del(index)">删除</el-button></td></tr></table></div><el-dialogv-model="dialogVisible"title="用户信息"width="70%"><el-descriptions:title="user.name"><el-descriptions-itemlabel="name">{{ user.name }}</el-descriptions-item><el-descriptions-itemlabel="password">{{ user.password }}</el-descriptions-item><el-descriptions-itemlabel="sex">{{ user.sex }}</el-descriptions-item><el-descriptions-itemlabel="address">{{ user.address }}</el-descriptions-item></el-descriptions></el-dialog><el-dialogv-model="dialogVisible11"title="编辑信息"width="50%"><el-descriptions:title="user.name"><el-descriptions-itemlabel="name"><el-inputv-model="user.name"placeholder="Please input"clearable/><!-- {{ user.name }} --></el-descriptions-item><el-descriptions-itemlabel="password"><el-inputv-model="user.password"placeholder="Please input"clearable/><!-- {{ user.password }} --></el-descriptions-item><el-descriptions-itemlabel="sex"><el-inputv-model="user.sex"placeholder="Please input"clearable/><!-- {{ user.sex }} --></el-descriptions-item><el-descriptions-itemlabel="address"><el-inputv-model="user.address"placeholder="Please input"clearable/><!-- {{ user.address }} --></el-descriptions-item></el-descriptions><el-buttontype="primary"@click="okk()">提交</el-button></el-dialog></template><scriptsetup>import{ onMounted ,ref}from"vue";let dataUser =ref([])let user =ref({})onMounted(()=>{
    dataUser.value =JSON.parse(localStorage.getItem('userA'))
    console.log(dataUser.value)})constdel=(index)=>{
    dataUser.value.splice(index,1)
    localStorage.setItem('userA',JSON.stringify(dataUser.value))}constshow=(u)=>{
    dialogVisible.value =true
    user = u
}let indexxx 
constchange=(u,index)=>{
    dialogVisible11.value =true
    user = u
    indexxx = index
}constokk=()=>{
    dataUser.value[indexxx]= user
    localStorage.setItem('userA',JSON.stringify(dataUser.value))}const dialogVisible =ref(false)const dialogVisible11 =ref(false)</script><stylescoped>input{width: 100px;}.title{/* font-weight: 450; */color: #909399;}table{width: 100%;}tr{text-align: center;border: #f2f2f2 1px solid;}td{width: 200px;color: #909399;height:35px;border: #f0f0f0 1px solid;padding:0;margin: 0;}tr:hover{background:#f6f6f6;}tr:nth-child(even){background:#f6f6f6;}</style>

3、编写LookBookView.vue文件(图书查看)

在view目录下新建LookBookView.vue文件

<template><divclass="book"><div><h1>{{ data['bookName'] }}</h1><span>作者:{{ data['authorName'] }}</span><br><span>发布时间:{{ data['date'] }}</span><divv-html="data['textarea']"style="margin-top: 20px;"></div></div></div></template><scriptsetup>import{ useRouter, useRoute }from'vue-router'import{ onMounted ,ref}from"vue";const router =useRouter()const route =useRoute()let data =ref({})onMounted(()=>{
    data.value =JSON.parse(localStorage.getItem('bookA'))[route.query['id']]
    console.log(data.value)// console.log(route.query['id'])})</script><stylescoped>.book{display: flex;width: 100%;height: 100vh;padding: 10px;justify-content: center;align-items: center;}.book>div{width: 80%;height: 100vh;background-color: #ebebeb;}span{font-weight: 550;}</style>

总结+源码地址

有些难度、不懂得如果留言达到50出视屏讲解
地址:源码地址

标签: vue.js ui javascript

本文转载自: https://blog.csdn.net/qczzc/article/details/130837899
版权归原作者 卑微前端在线挨打 所有, 如有侵权,请联系我们删除。

“vue工程项目案例(图书管理+用户管理) vue-router + element ui Plus”的评论:

还没有评论