Web前端笔记-15、Vue-自定义指令、路由、插槽
自定义指令
- 内置指令:v-html、v-if、v-bind、v-on... 这都是Vue给咱们内置的一些指令,可以直接使用
- 自定义指令:同时Vue也支持让开发者,自己注册一些指令。这些指令被称为自定义指令。每个指令都有自己各自独立的功能
概念:自己定义的指令,可以封装一些DOM操作,扩展额外的功能
语法
- 全局注册
//在main.js中
Vue.directive('focus', {
// 获取焦点
"inserted" (ele, binding) {
// 可以对 el 标签,扩展额外功能
ele.focus()
console.log(binding.value) // 123
}
})
<div v-focus="123"></div>
- 局部注册
//在Vue组件的配置项中
directives: {
"指令名": {
inserted () {
// 可以对 el 标签,扩展额外功能
el.focus()
}
}
}
- 使用指令注意:在使用指令的时候,一定要先注册,再使用,否则会报错 使用指令语法: v-指令名。如:
<input type="text" v-focus/>注册指令时不用加v-前缀,但使用时一定要加v-前缀 - inserted:被绑定元素插入父节点时调用的钩子函数
- el:使用指令的那个DOM元素
钩子函数:每一个钩子函数都有两个参数,(ele, obj)。ele是使用指令的那个元素,obj是指令的一些信息,比如指令的值obj.value
bind(){}:只执行一次;DOM渲染之前执行,里面可以进行样式操作
inserted(){}:只执行一次;DOM渲染之后执行,里面可以进行行为操作
update(){}:数据更新后执行
componentUpdated(){}:父子组件都更新后执行
unbind(){}:指令解绑的时候执行
路由
单页面应用程序(英文名:Single Page Application)简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。
单页应用类网站:系统类网站 / 内部网站 / 文档类网站 / 移动端站点
多页应用类网站:公司官网 / 电商类网站
单页面应用程序,之所以开发效率高,性能好,用户体验好
最大的原因就是:页面按需更新
前端路由的概念
前端路由:Hash 地址与组件之间的对应关系。/#/discover
页面效果:在浏览器中访问不同的 Hash 地址,会显示不同的组件。
vue路由(vue-router)是 vuejs 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA项目中组件的切换。
https://v3.router.vuejs.org/zh/
基本导入配置
npm i vue-router@3.5.2
创建路由模块 (src/router/index.js)
分类开来的目的就是为了 更易维护
- src/views文件夹页面组件 - 页面展示 - 配合路由用
- src/components文件夹复用组件 - 展示数据 - 常用于复用
// 导入
import Vue from 'vue'
import VueRouter from 'vue-router'
// 调用Vue.use(),将VueRouter安装为Vue的插件
Vue.use(VueRouter)
// 配置路由规则
const routes = []
// 创建路由实例对象
const router = new VueRouter({
routes,
})
// 导出路由实例对象
export default router
main.js
import Vue from 'vue'
import App from './App.vue'
// 1. 导入路由模块 @表示src
import router from '@/router'
Vue.config.productionTip = false
new Vue({
render: (h) => h(App),
// 2. 挂载路由模块
router,
}).$mount('#app')
使用核心步骤
- 配置路由规则(router/indexjs中)
- 设置路由出口(
<router-view />)(在哪里展示组件,在哪里放它) - 设置超链接(
<router-link to="/discover">发现音乐</router-link>)
点击超链接—->地址栏改变-->匹配路由规则地址—-> 在出口处展示对应组件
// 配置路由规则
const routes = [
{ path: '/discover', component: DisCover },
{ path: '/mymusic', component: MyMusic },
{ path: '/follow', component: Follow },
]
<template>
<div>
<div class="footer_wrap">
<router-link to="/discover">发现音乐</router-link>
<router-link to="/mymusic">我的音乐</router-link>
<router-link to="/follow">关注</router-link>
</div>
<div class="top">
<!-- 展示组件 -->
<router-view></router-view>
</div>
</div>
</template>
嵌套路由
index.js
// 配置路由规则
const routes = [
{
path: '/discover',
component: DisCover,
children: [
// 子规则不用加 / ,会自动拼接
{ path: 'recommend', component: Recommend },
{ path: 'toplist', component: TopList },
{ path: 'artlist', component: ArtList },
],
},
{ path: '/mymusic', component: MyMusic },
{ path: '/follow', component: Follow },
]
DisCover.vue
<template>
<div class="box">
<!-- 发现音乐 -->
<div class="link">
<router-link to="/discover/recommend">推荐</router-link>
<router-link to="/discover/toplist">排行榜</router-link>
<router-link to="/discover/artlist">歌手</router-link>
</div>
<div class="content">
<router-view></router-view>
</div>
</div>
</template>
路由传参
我们可以通过两种方式,在跳转的时候把所需要的参数传到其他页面中
- 查询参数传参
如何传参?<router-link to="/path?参数名=值"></router-link>
跳转后,组件接受参数值固定用法:$router.query.参数名
- 动态路由传参
超链接挂好合适的参数
路由规则改为 {path:'/xxx/:id', component: x}或者{path:'/xxx/:id?', component: x}
3. 跳转后,组件中使用 $route.params.id 获取值
<ul>
<li v-for="item in list" :key="item.id">
<router-link :to="`/discover/toplist/${item.name}`">
{{ item.name }}
</router-link>
</li>
</ul>
{ path: 'toplist/:name?', component: TopList },
<div class="content">
当前浏览的是<span>{{ $route.params.name }}</span
>的歌曲
</div>
重定向
使用场景:页面hash地址是 xx的情况,你希望跳转到yy地址。
比如:页面打开后,hash地址是 /,我希望跳转到 /discover
{path: '/',redirect: '/discover'}
依次类推,注意别写重复了。
历史模式
路由模式有两种,一种为 hash模式(默认),一种为历史模式。
- hash模式--- 地址栏有#号
- 历史模式--地址栏没有#号
如需使用历史模式,在 router/indexjs 中进行配置:
// 创建路由实例对象
const router = new VueRouter({
routes,
mode: 'history',
})
404处理
{ path: '*', component: NotFound },
NotFound.vue
<template>
<div>
<img src="../assets/404.png" alt="">
</div>
</template>
链接高亮router-link
使用 router-link 也会解析为 a 标签,会给当前访问的超链接,自动加两个类名。具有排他效果。
router-link-exact-active--- 精确匹配类名router-link-active —--模糊匹配类名
/a /a/b /a/b/c /a/b/c/d点击/a/b/c/d,它和它的父层/a /a/b /a/b/c都会加上模糊匹配类名,它自己还会加上精确匹配类名。
编程式导航
通过JS代码实现跳转的方式,叫做编程式导航。而不是使用超链接跳转。
比如点击登录按钮进行跳转。
两种语法:
- path 路径跳转 (简易方便)
//简单写法 $router就是index.js导出的router对象
this.$router.push('路由路径')
//完整写法
this.$router.push({
path: '路由路径',
query: { //传递查询参数
id: 4,
}
})
- name 命名路由跳转 (适合 path 路径长的场景,用name给个别名简化)
语法:
路由规则,必须配置name配置项
{ name: '路由名', path: '/path/xxx', component: XXX },
通过name来进行跳转
this.$router.push({
name: '路由名',
params: { // 传递的动态路由参数
id: 5,
},
query: { //传递查询参数
name: '4',
}
})
this.$router.方法名()
this.$router.back() //后退
this.$router.forward() //前进
this.$router.push() //跳转到指定的一个地址,并添加一条历史记录
this.$router.replace() //跳转到指定的一个地址,只替换当前地址,并不会增加历史记录
this.$router.go(n) //前进或后退
插槽
让组件内部的结构 支持 自定义。
在封装组件的时候,将可变的结构设计为插槽(<slot></slot>)
比如,封装一个对话框组件,对话框的内容可能是一句话,可能是一个表单,可能是一个表格。所以,对话框提示的内容不能写死,这时,就把对话框的内容设计为插槽。使用这个组件时,给插槽提供需要的内容。
对话框的内容,不应该写死可以使用 slot 标签占位
- 对话框子组件内需要定制的结构部分,改用<slot></slot>占位
- 父组件使用组件时, <子组件名></子组件名>标签内部, 传入结构替换slot
- 给插槽传入内容时,可以传入纯文本、html标签、组件
后备内容(默认值)
通过插槽完成了内容的定制,传什么显示什么, 但是如果不传,则是空白。
在 <slot> 标签内,放置内容, 作为默认显示内容
具名插槽
一个组件内有多处结构,需要外部传入标签,进行定制。
比如对话框,不只是内容需要插槽,标题,按钮都需要定制。
不同的弹框中有多处不同,但是默认插槽只能定制一个位置,这时候怎么办呢?
多个slot使用name属性区分名字

template配合v-slot:名字来分发对应标签


v-slot写起来太长,vue给我们提供一个简单写法 v-slot —> #
作用域插槽
插槽只有两种 默认插槽、具名插槽,作用域插槽不属于插槽的一种分类。
作用域插槽:定义slot 插槽的同时, 是可以传值的。给 插槽 上可以 绑定数据,将来 使用组件时可以用。
使用步骤:
- 给 slot 标签, 以 添加属性的方式传值
<slot :id="item.id" msg="测试文本"></slot>
- 所有添加的属性, 都会被收集到一个对象中
{ id: 3, msg: '测试文本' }
- 在template中, 通过
v-slot:插槽名="obj"接收,默认插槽名为 default
<MyTable :list="list">
<template #default="item">
<button @click="del(item.id)">删除</button>
</template>
</MyTable>

浙公网安备 33010602011771号