若依前后端分离版学习笔记(十六)——scoped、路由跳转

一、scoped

1.1 scoped作用域

在Vue中,scoped是一种CSS样式封装机制,用于将样式限制在当前组件范围内,防止样式泄露到全局或其他组件中。其原理是:当在Vue组件的<style>标签上添加scoped属性时,Vue会为该组件中的每个元素添加一个唯一的属性(如data-v-12345678),并修改CSS选择器以仅匹配这些带有特定属性的元素。

如下面这个示例组件

javascript 复制代码
<template>
  <div class="container">
    <h1>标题</h1>
    <p>段落内容</p>
  </div>
</template>

<style scoped>
.container {
  background-color: #f0f0f0;
}
h1 {
  color: blue;
}
p {
  font-size: 14px;
}
</style>

Vue会将其编译为类似这样的内容

javascript 复制代码
Html
<div class="container" data-v-12345678>
  <h1 data-v-12345678>标题</h1>
  <p data-v-12345678>段落内容</p>
</div>

Css
.container[data-v-12345678] {
  background-color: #f0f0f0;
}
h1[data-v-12345678] {
  color: blue;
}
p[data-v-12345678] {
  font-size: 14px;
}

这样,样式就只会影响当前组件内的元素,不会影响其他组件。

1.2 scoped样式穿透

scoped样式穿透用于在使用scoped属性的样式中修改子组件的内部样式。通常情况下,Vue的scoped样式只会作用于当前组件的元素,但有时候后我们需要修改子组件的样式,这时就需要进行样式穿透。 上面我们说过当在组件中使用scoped时,Vue会自动为当前组件的所有元素添加一个唯一的属性,同时也会修改CSS选择器以匹配这些元素。这会导致无法直接修改子组件的样式,因为子组件的元素没有这个唯一属性。

1.2.1 如何进行样式穿透

javascript 复制代码
在Vue3中,主要使用:deep()伪类选择器来实现样式穿透
.parent :deep(.child) {
  color: red;
}

这将被编译为:

javascript 复制代码
.parent[data-v-123456] .child {
  color: red;
}

在src→components→RightToolbar→index.vue中

javascript 复制代码
<style lang='scss' scoped>
:deep(.el-transfer__button) {
  border-radius: 50%;
  display: block;
  margin-left: 0px;
}
:deep(.el-transfer__button:first-child) {
  margin-bottom: 10px;
}
:deep(.el-dropdown-menu__item) {
  line-height: 30px;
  padding: 0 17px;
}
.check-line {
  width: 90%;
  height: 1px;
  background-color: #ccc;
  margin: 3px auto;
}
</style>

这里deep()选择器来修改Element Plus组件的内部样式,如.el-transfer__button和.el-dropdown-menu__item。

样式穿透主要用于以下场景: 修改第三方组件库的样式:如Element Plus、Ant Design Vue等 修改子组件的特定样式:当我们需要自定义子组件的外观时 覆盖组件库的默认样式:在不修改组件库源码的情况下改变其外观 注意事项: 谨慎使用:过度使用样式穿透可能会破坏组件封装性 优先使用组件提供的API:许多组件库提供了自定义样式的属性或插槽 避免深度嵌套:尽量只穿透一层,避免对深层嵌套的元素进行样式修改

二 路由

2.1 路由跳转的两种方式

什么是路由跳转? 路由跳转是指在单页应用(SPA)中,通过改变URL地址来切换不同页面内容的过程,而无需重新加载整个页面。Vue Router是Vue.js官方的路由管理器,提供了两种主要的路由跳转方式:声明式和编程式。

2.1.1 声明式路由跳转

声明式路由跳转是通过Vue Router提供的组件来实现的。它通过在模板中声明链接来触发路由跳转。

javascript 复制代码
<router-link to="/path">链接文本</router-link>

在src→layout→components→Navbar.vue中即有声明式路由跳转的使用

javascript 复制代码
<router-link to="/user/profile">
  <el-dropdown-item>个人中心</el-dropdown-item>
</router-link>

其它用法:

  1. 使用对象形式
javascript 复制代码
<router-link :to="{ path: '/user', query: { id: 123 }}">用户</router-link>

query参数会显示在url中,类似于GET请求的查询参数,其生成的URL为:代码会生成URL:/user?id=123,参数可以通过this.$route.query在目标组件中访问

  1. 使用命名路由
javascript 复制代码
<router-link :to="{ name: 'user', params: { id: 123 }}">用户</router-link>

params一般不会显示在url中,需要通过命名路由(name)来使用,必须在路由配置中预先定义。 假设路由配置如下:

javascript 复制代码
{
  path: '/user/:id',
  name: 'user',
  component: UserComponent
}

上面生成的URL为:/user/123,参数可以通过this.$route.params来获取

  1. 带额外属性
javascript 复制代码
<router-link :to="{ path: '/user' }" replace>用户</router-link>

使用replace来导航不会在浏览器历史记录中留下记录,适用于登录成功后跳转到主页的场景

2.1.2 编程式路由跳转

编程式路由跳转是通过JavaScript代码调用Vue Router实例的方法来实现路由跳转。这种方式更加灵活,可以在满足特定条件时进行跳转 基本语法

javascript 复制代码
// 通过router实例进行跳转
this.$router.push('/path')
// 或者在Composition API中
import { useRouter } from 'vue-router'
const router = useRouter()
router.push('/path')

在src→components→HeaderSearch→index.vue中可以看到编程式路由跳转的使用:

javascript 复制代码
function change(val) {
  const path = val.path
  const query = val.query
  if (isHttp(path)) {
    // http(s):// 路径新窗口打开
    const pindex = path.indexOf("http")
    window.open(path.substr(pindex, path.length), "_blank")
  } else {
    if (query) {
      router.push({ path: path, query: JSON.parse(query) })
    } else {
      router.push(path)
    }
  }
}

编程式路由跳转的其他方法:

  1. router.push() - 导航到不同的URL
javascript 复制代码
// 字符串路径
router.push('/users/123')

// 对象形式
router.push({ path: '/users', query: { id: 123 }})
router.push({ name: 'user', params: { id: 123 }})

// 带有查询参数,结果是 /user?id=123
router.push({ path: '/user', query: { id: 123 }})

// 带有hash,结果是 /user#team
router.push({ path: '/user', hash: '#team' })
  1. router.replace() - 导航到不同的URL,但不会向history添加新纪录
javascript 复制代码
router.replace('/users/123')
  1. router.go(n) - 在浏览器历史记录中前进或后退
javascript 复制代码
// 后退一步
router.go(-1)

// 前进一步
router.go(1)

// 后退一步
router.back()

// 前进一步
router.forward()

声明式和编程式路由跳转各有优势:

  • 声明式路由适用于简单的、直接的页面跳转,在模板中就可以清晰地看到跳转目标
  • 编程式路由适用于需要根据条件判断、处理复杂逻辑的跳转场景,提供了更大的灵活性 在实际开发中,我们会根据具体需求选择合适的跳转方式。对于简单的页面链接,使用<router-link>更加直观;对于需要条件判断、动态跳转的场景,编程式跳转更加合适。

2.2 动态路由的跳转方式

动态路由是指在应用运行时根据条件动态添加、删除或修改路由配置,而不是在应用初始化时就固定所有的路由。这种方式允许我们根据用户权限、角色或其他条件来动态决定用户可以访问哪些页面。 动态路由跳转本质上与普通路由跳转没有区别,都是使用声明式或编程式方式进行跳转。关键在于这些路由是在运行时动态生成和注册的。

2.2.1 动态路由跳转实例:

在src→api→menu.js中,通过getRouters接口从后端获取路由配置

javascript 复制代码
// 获取路由
export const getRouters = () => {
  return request({
    url: '/getRouters',
    method: 'get'
  })
}

然后在src→permission.js中处理这些路由配置并动态添加到Vue Router中

javascript 复制代码
usePermissionStore().generateRoutes().then(accessRoutes => {
  // 根据roles权限生成可访问的路由表
  accessRoutes.forEach(route => {
    if (!isHttp(route.path)) {
      router.addRoute(route) // 动态添加可访问路由表
    }
  })
  next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})

动态路由跳转主要特点:

  • 权限控制:用户只能看到和访问其有权限的路由
  • 灵活性:可以根据不同用户显示不同的菜单和页面

在若依中,动态路由的实现主要依赖于:

  1. 后端提供用户权限相关的路由配置
  2. 前端根据权限动态生成和注册路由
  3. 通过Vue Router的addRoute方法动态添加路由
  4. 使用相同的声明式或编程式方式进行路由跳转
相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
wdfk_prog4 小时前
[Linux]学习笔记系列 -- [drivers][input]input
linux·笔记·学习
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
ouliten4 小时前
cuda编程笔记(36)-- 应用Tensor Core加速矩阵乘法
笔记·cuda
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端