路由
前端路由:Hash地址(url中#后面的部分)与组件之间的对应关系
页面效果:在浏览器中访问不同的Hash地址时,会显示不同的组件
SPA项目(单页面应用程序,就是Vue项目,最后所有模板都展示在一个html上)
vue路由(vue-router)
1.安装
Vue2要安装3版本的vue-router,vue3使用版本4
npm i vue-router@3.5.2 (这个版本好用)
1.创建路由模块(src/router/index.js)(在创建新项目时可以直接选中配置)
//1.导入所需模块
import Vue from 'vue'
import VueRouter from 'vue-router'
//2.调用Vue.use()函数,将VueRouter安装为Vue插件
Vue.use(VueRouter)
//3.配置路由规则
const routes=[]
//4.创建路由的实例对象
const router=new VueRouter({
//路由的配置
routes
})
//5.导出路由的实例对象
export default router
1.创建并挂载路由模块(main.js)
import router from '@/router'
new Vue({
render:h=>h(App),
//挂载路由模块
router
}).$mount('#app')
以上便是vue-router的基础配置
浏览器访问localhost:8080,如果路径后自动添加了/#/,则基本上配置成功
使用路由的核心步骤
1.配置路由规则(router/index.js中)
2.设置路由出口(<router-view/>)(在哪里展示组件,在那里放它)
3.设置超链接(<router-link to="/discover">发现音乐</router-link>)
组件的变化过程:点击超链接–>地址栏变化–>匹配路由规则地址–>在出口处展示对应组件
一级路由
直接写到routes数组中的路由规则,级别最大,叫做一级路由
一级路由只能展示在App.vue中
嵌套路由
在一级路由组件中嵌套子规则
嵌套子规则
const routes = [
{ path: '/find', component: Find,
//二级路由的path可以不写斜线,二级路由的访问地址会和一级路由拼接
childeren:[{path:'xxx',component:yyy},{...},{....}] },
{ path: '/my', component: My },
{ path: '/friend', component: Friend },]
接下来二级路由的出口放置在对应的子组件中(一级路由出口放置在App.vue中)
子组件的<router-link>写path时要显示出来父子关系
<router-link to="find/xxx"></router-link>
路由传参(可以用参数来发送AJAX请求)
两种方式
/xxx/xxx?id=3&name=xxx-----查询参数传参
/xxx/xxx/3/xxx --------动态路由传参
查询参数传参
在当前页面中传参(vue中,要在属性中使用变量,需要在属性前加:,否则传递的是字符串)
套路:
1.超链接挂好合适的参数(超链接不再跳转,在本页面实现)
2.跳转后使用$route.query.参数名 获取值
动态路由传参
套路:
1.超链接挂好合适的参数
// 必须传id //id后加?表示id可有可无
2.路由规则改为{path:'/xxx/:id',compo...}或者{path:'/xxx/:id?',compo...}
3.跳转后,组件中使用$route.params.id获取值
重定向
在routes中修改
使用场景:页面hash地址是xx的情况,你希望跳转到yy地址
比如,页面打开后,hash地址是/,我希望跳转到/discover
{path:'/',redirect:'/discover'}
路由的模式
两种模式:Hash模式(默认)和历史模式
配好路由规则的时候,url默认增加#为hash模式
历史默认的url没有#
404处理
先准备一个NotFound组件
再在routes最后中增加一个规则
*为通配符,如果之前的理由规则没有匹配上(优先和别的规则匹配),则最后匹配到通配符时展示*
{path:'*',component:NotFound}
连接高亮
router-link也会被解析成a标签,同时会给当前访问的超链接自动加两个类名(用来实现排它效果)(根据hash地址来添加类)
编程式导航(用js实现超链接跳转)
location.herf=‘./xxxx’
this.$router.push()
//写法一(直接写字符串)
this.$router.push('完整路由地址(hash地址)')
//写法二(传入对象,使用name进行跳转)
//需要给routes规则添加name {name:'php',path:'toplist/:name?',component:..}
this.$router.push(
name:'php',//路由规则的name值
params:{ //传递的动态路由参数
name:'xx'
}
)
//写法三(传入对象,使用path进行跳转)(有问题不要用)
this.$nextTick()
methods方法中数据更新(数据是同步更新),页面不会立即更新(页面是异步更新,避免导致多次渲染,浪费不必要的性能),会在下次循环的时候更新页面
语法:
this.$nextTick(()=>{
//数据更新后,等DOM也更新后,这个函数执行
})
使用场景:
1.如果想要在修改数据后立即得到更新后的DOM结构,可以使用this.
n
e
x
t
T
i
c
k
(
)
2.
在
c
r
e
a
t
e
d
声明周期中进行
D
O
M
操作
(
用的少,最早进行
D
O
M
操作的函数是
m
o
u
n
t
e
d
(
)
,想要在
c
r
e
a
t
e
d
(
)
进行
D
O
M
操作要借助
t
h
i
s
.
nextTick() 2.在created声明周期中进行DOM操作(用的少,最早进行DOM操作的函数是mounted(),想要在created()进行DOM操作要借助this.
nextTick()2.在created声明周期中进行DOM操作(用的少,最早进行DOM操作的函数是mounted(),想要在created()进行DOM操作要借助this.nextTick())
插槽 ( <slot><\slot>
)
组件通信父传子用来传数据,插槽用来传HTML结构
作用&场景
1.在封装组件的时候,将可变的结构设计为插槽(<slot><\slot>占位)
2.使用上述组件的时候,可以按需为插槽提供自定义的结构,以达到复用组件且高度自定的结果
比如,封装一个对话框组件,对话框的内容可能是一句话,可能是一个表单,可能是一个表格
所以,对话框的内容不能写死,这时,就把对话框的内容涉及为插槽。使用这个组件时,为插槽提供需要的内容
具名插槽(具有名字的插槽)
如果子组件中有多个插槽,父组件传递html结构时,将会给每个插槽都传递一份
为了提供的HTML结构能放入正确的插槽,需要给插槽加名字进行区分
子组件
<slot name="title"></slot>
<slot></slot> //没有名字的插槽有一个默认的名字name="default"
父组件
将传递给插槽的结构先用template结构包裹起来,使用v-slot:名字。找到对应的slot,没有被template包裹的html结构都传给默认插槽
<template v-slot:title>
//v-slot:title 可以简写为#title
<h3>传递给插槽的内容<h3>
</template>
作用域插槽(只能在template内部使用)
有些时候,子组件在定义插槽的时候,需要向使用者(父组件)传递一些数据,这样的插槽叫作用域插槽