Vue项目1学习第一篇
- 01. 环境配置介绍和项目搭建
- 02. Router路由配置引入
- 03. ElementPlus引入和按需加载
- 04. layout布局和菜单aside组件创建
- 05. aside样式问题和treeMenu组件拆分
- 06. treeMenu组件递归实现
01. 环境配置介绍和项目搭建
(1)安装node.js
安装完成之后,在vscode命令行输入npm install 20.16.0
,然后重新开启命令行,输入nvm list
来查看当前已下载的依赖。而后,通过nvm use 20.16.0
切换到指定版本20.16.0,切换之后,输入node -v
来查看当前的版本。
(2)创建Vue项目
我们使用Vite来创建。
Vite是一个脚手架工具,优点在于构建项目时速度非常快
输入npm i
下载依赖,这样项目就创建完成了。
02. Router路由配置引入
在当前默认页面中,url地址里面所显示的login
,是其中的一个路由所对应的登陆页面。
点击登录之后,url中的地址login
变为dashboard
这里就涉及到页面跳转。
在Vue当中,页面跳转是使用Vue-Router来帮我们实现的。因此,我们接下来要去下载Vue-Router插件。
在命令行输入上述命令之后,确认版本没问题之后,我们就需要去使用Vue-Router去创建路由和对应页面。
日后路由配置就写入此文件中。
之后,执行如下操作:
(1)创建数组对象
(2)调用createRouer方法
实操如下:
(1)创建数组对象
const routes=[
{
//最开始的数据肯定是'/'
path:'/'
//这个'/'下会匹配当前访问'/'所匹配的页面
//这个页面的属性就是component
//component需要对应我们当前的一个Vue组件
component:
}
]
(接上文代码内容)
所以,我们创建一个Vue组件(Main.vue)来匹配:
并且引入到index.js
中。
(想了解原因可去看我写的【Vue3】第四篇最后一节)
以此类推,创建登陆界面:
然后,我们要创建Router实例
(ps:实例封装了数据和行为)
(2)调用createRouer方法
(createRouter 函数用于创建一个路由器实例)
①引入vue-router插件
②使用router里面的createRouter方法
③通过createRouter,把当前routers这个属性传递进去
注意:createRouer内要写入路由的匹配模式。
路由的匹配模式:
模式有三种,我们这里使用Hash模式
(因为这种模式,在进行路由切换时不需要刷新,直接更换路由,更换界面内容。这种模式下不需要访问后台)
我们使用Hash模式,将其方法引入进来
调用其方法,设置为Hash模式
然后,当前方法会返回一个router实例,我们通过一个变量来接受一下
然后对外进行导出:
导出之后,我们需要在当前的main.js
文件(入口文件)中引入router
然后,把router
挂载在Vue实例上。
这样,我们就完成了路由的挂载。
此时,我们还没有给路由配置对应的显示出口。
比如说,我现在想访问’/',那这里(Layout)所访问的页面到底显示在什么地方,我们还没有定义。
我们这里需要使用Vue的一个组件
结果:
(注意:组件内容我没写入博客中)
①访问’/‘页面:
②访问’/login’页面:
03. ElementPlus引入和按需加载
在实际项目开发中,比较常见的一些UI显示,如button按钮、table数据的展示、分页等,一般都是用市面上比较成熟的UI框架当中的组件帮助我们实现。
我们推荐使用ElementPlus
其优点是:
①开箱即用
②有很多的Js的交互效果是直接内置在组件内的
③所包含的组件非常多
接下来,我们来安装一下它。
(公司中,注意兼容性)
(1)下载
我们这里直接通过npm的方式下载它:
(2)在页面中引入
有两种引入方式:
我们一般是按需引入。
然后重启项目就可以了。
ps:虽然在Vite里面是热更新,当修改页面中内容的时候,它会自动帮助我们打包,然后重新进行构建。但是配置文件它是监测不到的。
所以说,一旦修改了配置文件的内容,都需要把项目进行一个重启。
04. layout布局和菜单aside组件创建
接下来,我们来完成页面的布局。
参考完整版项目,可以看到,页面分为三部分:
然后在UI框架中寻找相符框架:
引入去除默认样式的css:
有了Layout布局之后,我们优先先来实现一下左侧部分。
因为左侧代码复杂,所以我们把它抽成一个组件。
随后,复制UI框架的代码:
可以发现,复制的代码内还定义了一些方法,那么在script里面同样也要把这些方法写出来。
这里我们使用的是Vue3组合式API的写法。
可以直接在scipt内声明一个箭头函数。
最后,在Main.vue
内引入。
效果如下:
拓展:
代码内组件中所对应的属性,可以去官网查看
05. aside样式问题和treeMenu组件拆分
接下来,我们来完成左侧菜单部分的内容。
与完整版项目相比,左侧部分的样式还有些欠缺。
(1)高度不够
首先,设置class
来修改样式:
在实际开发中,实际用的多的工具是less
(重启一下就可以开始使用了)
less的语法很简单,我们可以使用它的一个嵌套结构来编写样式以及控制层级。
回归正题,设置高度:
我们都知道,100%是继承父级的高度,所以还需要给父级增加高度。
但是刷新之后,却发现没有生效。
检查,发现图中这部分也要继承100%
(2)内容
①标题:顶部有类似于标题这样的效果。
②菜单:内容是动态的、可配置的,所以是由数据来渲染的。既然这样的话,那么菜单就会有不同的层级,如控制台有一级,权限管理有二级。
所以说,菜单的逻辑是会有嵌套的场景的,所以,把它抽成一个组件。
06. treeMenu组件递归实现
本小节,我们继续来完成左侧菜单的内容。
左侧菜单的内容,依赖于当前的数据。
对于完整版而言,左侧菜单所展示的内容,都是已经注册的一些路由信息。
所以,现在我们首先要做的,就是在router里面给它把对应的这些路由添加上。
ps:
这个children,代表的是嵌套路由。
这个meta,是我们额外所添加的一些信息,这些信息是必要的一些数据,后面会用到。
接下来,我们把所对应的子路由和components页面 注册一下:
注意:结构部分不能乱写,后续在做权限时,我们需要使用动态路由的显示,这里的层级结构是需要和后面的数据匹配得上的。(※)
(meta属性会带上路径,整个的层级结构和路径是相匹配的)
写到这里,我们的数据已经有了,接下来就是如何去获取这个数据。
ps:数据肯定是由外部传入Aside组件内部,通过props的形式进行传递,因为后面的话,我们考虑到是要改成使用动态数据。(※)
实现方法:
获取路由数据
调用router的一个方法获取实例
(这个vue-router告诉我们,在组合式API中,我们是可以通过一个useRouter
来获取当前router的实例,然后去调用当前的这个数据,然后拿到router实例。)
我们可以来打印一下这个router实例,看看它到底长什么样子:
我们现在需要拿到我们当前配置的数据,那么,在这里面,我们会发现,里面有一个options这个数据,在其之下,有一个routes,在routes下面,第一项就是我们’/‘所需要的数据,我们只需要拿到’/'后面的数据,然后去menu组件内进行渲染即可。
理解了之后,我们开始写代码:
①我们先来创建一个响应式数据(用ref/reactive来创建),然后传递到子组件里面。
(1)这里我们传递的是对象,用reactive来传递会更加合理
(2)直接把reactive解构出来,然后创建一个响应式数据
我们先拿到router.options.routes[0].children
,这就是我们想要的menu数据(子数据)
然后通过父子组件通信的方式传入子组件里面。v-bind:传入数据,子组件defineProps通过数组的形式拿到数据。他会返回一个Props的对象,然后打印出来。
父组件:
子组件:
打印结果:
子组件拿到数据之后,就可以渲染左侧的菜单。
②菜单包含有子菜单和无子菜单的情况。
①有子菜单,层级是我们不确定的(可能根据数据,有两级、三级等等)。所以说,这个复用的逻辑,我们优先考虑到使用递归组件来帮我们完成
我们可以看到,这个多级菜单是通过el-sub-menu
包裹着每一层来实现的
最下面是没有子菜单的,只有一层
我们先把上面的那段代码注册掉。
我们这里既然是按照递归,
那首先,我们要先判断没有子菜单的情况。
我们需要去遍历props的menudata,拿到当前的数据item,以及它的索引index。
拿到数据之后,接下来,我们需要去进行一个判断:
(1)对于有子菜单而言,让他们递归然后复用当前的逻辑
(2)对于没有子菜单而言,我们直接渲染。
如果是没有子菜单,则没有children
接下来,是写index(当前组件必须要我们携带的唯一项)
这里的index不能直接用遍历得到的index索引,因为这里使用的是递归的逻辑。子菜单里的第一项和父菜单里的第一项用index来判断会导致冲突。
所以要用父级的index和当前的index做一个拼接。
结合数据,我们可以观察到,拿到的数据中meta里面有一个id,id表示当前同级别里它是一个唯一的值。然后我们再拼接上父级的index值,就能确保这里的index是一个唯一项了。
写法如下:
解释:
当前的index值由父组件传递进来,子组件通过defineProps获取
父组件:
子组件:
(需要父级传id是因为meta的id不唯一)
key亦是如此。
接下来我们来完成内容:渲染图标和名字
①没有子菜单,直接渲染:
②有子菜单,递归实现:
根据Element-UI源代码,填入上述内容(图标+名称)。
递归组件传入一样的名称,一样的参数。其中第二个参数改为“item.children"
(ps:递归实现index变化):
注意:递归组件可以去网上找视频深入了解。