3 自定义
约 2409 字大约 8 分钟
2025-05-04
自己定义的指令,可以封装一些dom操作,扩展额外功能
指令的钩子函数有两个:
- inserted会在指令所在元素被插入到页面中时触发
- update会在指令的值修改的时候触发
- 全局注册
Vue.directive()'指令名',{
"inserted"(el){
//可以对 el标签,扩展额外功能
el.focus()
}
})
- 局部注册
directives:{
'指令名":{
inserted () {
//可以对 el标签,扩展额外功能
el.focus()
}
}
}
插槽
让组件内部的一些结构支持自定义
匿名插槽
在定义组件的时候使用<slot></slot>
标签占位 在使用的时候将插入的内容使用自定义的标签报告就会把内容插入到slot的位置了
<MyDialog>内容</MyDialog>
具名插槽
匿名插槽只有一个占位,如果有多个需要插槽的地方可以使用具名插槽 若要定义具名插槽也是使用slot标签,不过需要加上name属性作以区分
<div>
<slot name="a"></slot>
<slot name="b"></slot>
</div>
在使用时需要用template标签包裹内容,并使用v-slot命令表示插入哪个插槽中
<MyDialog>
<template v-slot:a>
大标题
</template>
<template v-slot:a>
内容文本
</template>
</MyDialog>
v-slot可使用#
代替
默认值
要将插槽设置默认值只需要将值放在slot标签内即可
作用域插槽
定义 slot插槽的同时是可以传值的。给插槽上可以绑定数据将来使用组件时可以用
基本使用步骤:
- 给slot标签,以添加属性的方式传值
<slot :id="item.id" msg="测试文本"></slot>
- 所有添加的属性,都会被收集到一个对象中
{ id: 3, msg:测试文本’}
- 在template中,通过E#插槽名="obj"接收,默认插槽名为default
<MyTable :list="list">
<template #default="obj">
<button @click="del(obj.id)">删除</button>
</template>
</MyTable>
路由
修改地址栏路径时,切换显示匹配的组件
需要自己手动下载 vue2对应的时vuerouter3.x,vuex3.x vue3对应的时vuerouter4.x,vuex4.x
配置使用环境
- 下载
npm add [email protected] -g
- 引入
import VueRouter from 'vue-router'
- 安装注册
Vue.use(VueRouter)
- 为组件配置路由规则
- 创建需要的组件(views目录),配置路由规则 创建的路由对象是空的,要想使用还需要添加路由规则
import Find from './views/Find.vue'
import My from './views/My.vue'
import Friend from './views/Friend.vue'
const router = new VueRouter({
routes:[
{path:'/find',component: Find },
{path:'/my',component:My },
{path:'/friend',component:Friend }
]
)
- 配置导航,配置路由出口(路径匹配的组件显示的位置) router-view是一个占位标签,用于加载配置路由的组件
<div class="footer_wrap">
<a href="#/find">发现音乐</a>
<a href="#/my">我的音乐</a>
<a href="#/friend">朋友</a>
</div>
<div class="top">
<router-view></router-view>
</div>
- 注入,将路由对象注入到newVue实例中,建立关联
new Vue({
render: h => h(App)
router:router
}).$mount('#app')
路由的封装抽离
若所有路由规则都配置在main.js中项目大了后就不好维护 可以分类管理路由规则,将路由规则放到router文件夹中,再在main.js中导入
导包路径 可以使用@符代表当前目录的src目录
import Find from '@/views/Find'
声明式导航
vue-router提供了一个全局组件router-link(取代a 标签)
- 能跳转,配置 to 属性指定路径(必须)。本质还是a标签,to 无需#
- 能高亮,默认就会提供高亮类名,可以直接设置高亮样式
<div class="footer_wrap"
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link>
</div>
// 二者是相等的
<div class="footer_wrap">
<a href="#/find">发现音乐</a>
<a href="#/my">我的音乐</a>
<a href="#/part">朋友</a>
</div>
一般使用路由的场景大都会用到高亮显示,vue已经在router-link中封装好了高亮的逻辑,我们只需要提供高亮样式 在设置高亮样式时使用router-link-active
和router-link-exect-active
两个类名都可以
两个高亮类名的区别
- router-link-active模糊匹配(用的多) to="/my" 可以匹配/my /my/a /my/b
- router-link-exact-active精确匹配 to="/my"仅可以匹配/my
自定义高亮类名 可以在VueRouter对象中设置自定义的高亮类名
const router=new VueRouter({
linkActiveClass:'active',
linkExactActiveClass:'exact-active'
})
跳转传参
在跳转路由时,进行传值
查询参数传参
to="/path?参数名=值"
在对应的页面组件中获取参数
$route.query.参数名
动态路由传参
- 配置动态路由
const router = new VueRouter({
routes:[
{
path:'/search/:words',
component:Search
}
]
})
:words是动态参数,跳转到/search下的哪个网页就代表的是那个网页的路由名 可以获取words值解析出对应页面的路由名
- 配置导航链接
to="/path/参数值"
- 对应页面组件接收传递过来的值
$route.params.words
动态路由可选符
配了路由path:"/search/:words"
后跳转到/search路由页面中会未匹配到组件,显示空白 原因是/search/:words
表示,必须要传参数。如果不传参数,也希望匹配,可以加个可选符"?"
{ path: '/search/:words?",component:Search}
重定向
进入到一个路径中后强制跳转到其他路径
//{path:匹配路径,redirect:重定向到的路径},
const router = new VueRouter({
routes:[
{ path:'/',redirect:'/home'},
{path:'/home',component:Home },
{path:'/search/:words',component:Search}
]
})
404
404错误码还是很常见的,主要用于用户进入到没有设置的路径时返回404
404路由要配置在路由的最后面 path:"*"
(任意路径)前面不匹配就命中最后这个
const router = new VueRouter({
routes:[
{ path:'/',redirect:'/home'},
path:'/home',component:Home },
path: '/search/:words?'. component: Search },
path:"*",component:NotFind }
]
})
模式设置
路由的路径看起来不自然,有#,切换成真正路径形式 hash路由(默认)例如:http://localhost:8080/#/home history路由(常用)例如:http://localhost:8080/home(以后上线需要服务器端支持) 只需要将模式设置为history即可
const router = new VueRouter({
routes,
mode: "history"
})
编程式导航
点击按钮实现跳转 用js代码来进行跳转
push跳转
push跳转会保留历史记录 path路径跳转
//简单形式
this.$router.push('路由路径')
//完整形式
this.$router.push({
path:'路由路径'
})
name命名路由跳转
{name:'路由名',path:'/path/xxx',component:xxx}
传参
path路径跳转传参 跳转传参可以手动拼接,也可以使用特定的语法让vue进行拼接后的路径传参
this.$router.push('路由路径?参数名=参数值')
this.$router.push({
path:‘路由路径‘
query:{
参数名:参数值,
参数名:参数值
}
})
获取参数值时通过$route.query.参数名
获取 name命名路由跳转传参
this.$router.push({
name:'路由名'
params:{
参数名:参数值,
参数名:参数值
}
})
获取参数值时通过$route.params.参数名
获取
replace跳转
replace跳转不会保存历史记录
子路由
在一个路由下面还可以配置哪个路由下的子路由 在那个路由下添加children属性,children中路由配置和routes一样
routes: [
{
path: '/',
component: Layout,
children:[
{
path: '/article',
component: Article
},
{
path: '/collect',
component: Collect
}
]
}
]
组件缓存
问题:点击路由地址后跳转到新的路径返回时数据又重新加载;了 原因:路由跳转后,组件被销毁了,返回回来组件又被重建了,所以数据重新被加载了 解决:利用keep-alive将组件缓存下来
keep-alive
keep-alive是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 keep-alive是一个抽象组件:它自身不会渲染成一个DOM元素,也不会出现在父组件链中。
在组件切换过程中把切换出去的组件保留在内存中,防止重复渲染DOM 减少加载时间及性能消耗,提高用户体验性。
使用时只需要使用<keep-alive>
标签将要缓存的标签包裹起来
<template>
<div class="h5-wrapper">
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
</template>
keep-alive默认会将包裹的所有内容都缓存,如果有不需要缓存的地方需要使用它的三个属性来排除
- include : 组件名数组,只有匹配的组件会被缓存
- exclude : 组件名数组,任何匹配的组件都不会被缓存
- max : 最多可以缓存多少组件实例
<template>
<div class="h5-wrapper">
<keep-alive :include="['comp1','comp2']">
<router-view></router-view>
</keep-alive>
</div>
</template>
生命周期
当一个组件被设置缓存后它会多两个生命周期
- actived : 激活时
- deactive : 失活时
路由前置导航守卫
任何路由在跳转前都有经过前置导航守卫 在beforeEach函数中
- to是要跳转到的路径
- from是原本路径
- next是一个函数用于处理放行或不放行 next()是放行 next('路径')是调转到给定路径
const authUrls = ['/pay', '/myOrder']
router.beforeEach((to, from, next) => {
if (!authUrls.includes(to.path)) {
next()
return
}
const token = store.getters.token
if (token) {
next()
} else {
next('/login')
}
})
router4
在vue3中使用的是router4版本,配置和router3版本略有不同
创建路由使用createRouter
函数 createWebHistory
是history模式createHashHistory
是hash模式 传入的参数是基础路径,此路由下的所有路径都是基础路径后面的 meta.env.BASE_URL是vite中配置的基础路径
const router = createRouter({
history:createWebHistory(import.meta.env.BASE_URL),
routes:[]
)
贡献者
版权所有
版权归属:PinkDopeyBug