若依前后端分离版学习笔记(十六)——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. 使用相同的声明式或编程式方式进行路由跳转
相关推荐
qaqxiaolei2 小时前
高效办公利器:前端实现表格导出excel格式 + 自定义水印的完整方案
前端·javascript
叫我詹躲躲2 小时前
为什么Bun.js能在3秒内启动一个完整的Web应用?
前端·javascript·bun
Olrookie2 小时前
若依前后端分离版学习笔记(十七)——ruoyi开发规范&流程,请求流程,依赖引入,组件注册&通信
前端·笔记
Keepreal4962 小时前
谈谈对闭包的理解以及常见用法
前端·javascript
luckymiaow2 小时前
告别环境配置地狱!UniApp Android 本地 一键打包神器
前端
Keepreal4962 小时前
JS加载时机
前端·javascript
itslife2 小时前
从头看 vite 源码 - 调试
前端
叫我詹躲躲2 小时前
ES2025:10个让你眼前一亮的JavaScript新特性
前端·javascript
乐~~~2 小时前
解决avue-input-tree组件重置数据不回显/重置失败
前端·javascript·vue.js