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)

分类开来的目的就是为了 更易维护

  1. src/views文件夹页面组件 - 页面展示 - 配合路由用
  2. 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')

使用核心步骤

  1. 配置路由规则(router/indexjs中)
  2. 设置路由出口(<router-view />)(在哪里展示组件,在哪里放它)
  3. 设置超链接( <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 标签占位

  1. 对话框子组件内需要定制的结构部分,改用<slot></slot>占位
  2. 父组件使用组件时, <子组件名></子组件名>标签内部, 传入结构替换slot
  3. 给插槽传入内容时,可以传入纯文本、html标签、组件

后备内容(默认值)

通过插槽完成了内容的定制,传什么显示什么, 但是如果不传,则是空白。

<slot> 标签内,放置内容, 作为默认显示内容

具名插槽

一个组件内有多处结构,需要外部传入标签,进行定制。

比如对话框,不只是内容需要插槽,标题,按钮都需要定制。

不同的弹框中有多处不同,但是默认插槽只能定制一个位置,这时候怎么办呢?

多个slot使用name属性区分名字

dJDcGXudwiz869RHXAWsE-c29oOf60HhmCmCSFp-0RE=

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

aWeLSJFtbxu22PSyZDWsMxO0ZpBKHu9xc-KDVycpQM0=

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>
posted @ 2025-06-02 18:10  subeipo  阅读(21)  评论(0)    收藏  举报