day06

day06

目录

声明式导航 — 导航链接

需求

  • 实现导航高亮效果
  • 如果使用 a 标签进行跳转的话,需要给当前跳转的导航加样式,同时要移除上一个 a 标签的样式,太麻烦

解决方案

  • vue-router 提供了一个全局组件 router-link (取代 a 标签)

  • 能跳转,配置 to 属性指定路径(必须指定),本质还是 a 标签,写法 to 无需加 #

  • 相比 a 标签的好处就是:能高亮,默认就会提供高亮类名,可以直接设置高亮样式

  • 语法: <router-link to="path的值">xxx</router-link>

    <div>
      <div class="footer_wrap">
        <router-link to="/find">发现音乐</router-link>
        <router-link to="/my">我的音乐</router-link>
        <router-link to="/friend">朋友</router-link>
      </div>
      <div class="top">
        <!-- 路由出口 → 匹配的组件所展示的位置 -->
        <router-view></router-view>
      </div>
    </div>
    
  • 使用 router-link 跳转后,我们 F12 发现。当前点击的实际代码就是 a 标签默认加了两个 class 的值 router-link-exact-activerouter-link-active(用于高亮的类,会自行加删)

  • 我们可以给任意一个 class 属性添加高亮样式即可实现功能

    • 如:

      .footer_wrap a.router-link-active {
        background-color: red;
      }
      

声明式导航 — 两个类名

  • 当我们使用 <router-link></router-link> 跳转时,自动给当前导航加了两个类名:

68249312105

  • 模糊匹配(用的多)

    • to="/my" 可以匹配 /my/my/a/my/b......
  • 只要是以 /my 开头的路径 都可以和 to="/my" 匹配到

  • 使用场景:在主导航栏点击高亮后,次级导航栏再点击高亮时,主导航栏的高亮不会取消

  • 精确匹配
    • to="/my" 仅可以匹配到 /my

声明式导航 — 自定义类名(了解)

问题

  • router-link 的两个高亮类名太长了,能否定制

解决方案

  • 在创建路由对象时,额外配置两个配置项即可: linkActiveClasslinkExactActiveClass
const router = new VueRouter({
  routes: [...],
  linkActiveClass: "类名1",
  linkExactActiveClass: "类名2"
})

68249372945

代码演示

// 创建了一个路由对象
const router = new VueRouter({
  routes: [
    ...
  ], 
  linkActiveClass: 'active', // 配置模糊匹配的类名 active
  linkExactActiveClass: 'exact-active' // 配置精确匹配的类名 exact-active
})
  • 这样再 F12 打开时就会发现是

    • class="exact-active active"

    • css 就是自定义的:

      .footer_wrap a.active {
        background-color: red;
      }
      
      • 即可

声明式导航 — 查询参数传参

  • 在跳转路由时,进行传参
    • 例如:点击了按钮,需要把点击的内容带到详情页

跳转传参

  • 可以通过两种方式,在跳转的时候把所需要的参数传到其他页面中

    • 查询参数传参

    • 动态路由传参

查询参数传参

  • 传参:

    • <router-link to="/path?参数名=值"></router-link>
  • 接受参数固定用法:

    • $route.query.参数名

代码演示

  • Home.vue
<div class="hot-link">
  热门搜索:
  <router-link to="/search?key=xxx">xxx</router-link>
  <router-link to="/search?key=yyy">yyy</router-link>
  <router-link to="/search?key=xyx">xyx</router-link>
</div>
  • Search.vue
<template>
  <div class="search">
    <p>搜索关键字: {{ $router.query.key }}</p>
    <p>搜索结果: </p>
    <ul>
      <li>.............</li>
    </ul>
  </div>
</template>

<script>
export default {
  created () {
    // 在created中,获取路由参数: this.$route.query.参数名
    console.log(this.$route.query.key);
  }
}
</script>

声明式导航 — 动态路由传参

动态路由传参方式

  • 配置动态路由

    • 动态路由后面的参数可以随便起名,但要有语义(如下述的 words)

      const router = new VueRouter({
        routes: [
          ...,
          { path: '/search/:words', component: Search }
        ]
      })
      
  • 配置导航链接

    • to="/path/参数值"
    • 即:<router-link to="/search/xxx">xxx为想传的参数</router-link>
  • 对应页面组件接受参数

    • $route.params.参数名
    • params 后面的参数名要和动态路由配置的参数保持一致(即上述的 words)
    • 即:console.log(this.$route.params.words);

查询参数传参 VS 动态路由传参

  • 查询参数传参(比较适合传多个参数)
    • 跳转:to="/path?参数名=值&参数名2=值"(键值对方式)
    • 获取:$route.query.参数名
  • 动态路由传参(优雅简洁,传单个参数比较方便)
    • 配置动态路由:path: "/path/:参数名"
    • 跳转:to="/path/参数值"
    • 获取:$route.params.参数名
  • 注意:动态路由也可以传多个参数,但一般只传一个

动态路由参数的可选符(了解)

  • /search/:words 表示,必须要传参数,即进入不到 #/search 地址的页面了

  • 如果不传参数,也希望匹配到某页面(即可选的),可以加个可选符 " ?"

    const router = new VueRouter({
      routes: [
     	...
        { path: '/search/:words?', component: Search }
      ]
    })
    

Vue 路由 — 重定向

问题

  • 网页打开时, url 默认是 / 路径,未匹配到组件会出现空白(组件不存在就会出现空白)

解决方案

  • 重定向:匹配 / 后, 强制跳转 /home 路径(也就是显示 /home 所指向的组件)

语法

{ path: 匹配路径, redirect: 重定向到的路径 },
比如:
{ path:'/' ,redirect:'/home' }

代码演示

const router = new VueRouter({
  routes: [
    { path: '/', redirect: '/home'},
 	 ...
  ]
})

Vue 路由 — 404

作用

  • 当路径找不到匹配时,给个提示页面

位置

  • 404 的路由,虽然配置在任何一个位置都可以,但一般都配置在其他路由规则的最后面

语法

  • path: "*"(任意路径)— 前面不匹配就命中最后这个
import NotFind from '@/views/NotFind'

const router = new VueRouter({
  routes: [
    ...
    { path: '*', component: NotFound } //最后一个,*就表示任意,匹配NotFound组件
  ]
})

代码示例

  • NotFound.vue
<template>
  <div>
    <h1>404 Not Found</h1>
  </div>
</template>
  • router/index.js
...
import NotFound from '@/views/NotFound'
...

// 创建了一个路由对象
const router = new VueRouter({
  routes: [
     ...
    { path: '*', component: NotFound }
  ]
})

export default router

Vue 路由 — 模式设置

问题

语法

const router = new VueRouter({
    mode:'histroy', //默认是 hash
    routes:[]
})

编程式导航 — 两种路由跳转方式

  • 点击按钮跳转的实现,就像是点击登录到登录页面一样,这里通常就不会用导航链接了

  • 而是用编程式导航:用 JS 代码来进行跳转

    • 原来都是用 location.href=新链接 来实现,但 vue 这里是跳路由,本质上是在单页中,所以不能在这样用了,有专门的跳转方式

语法

  • 两种语法:

    • path 路径跳转(简易方便)

    • name 命名路由跳转(适合 path 路径长的场景)

path 路径跳转语法

  • 特点:简易方便(直接往路由上跳)
  • 写在按钮之类的方法事件上:
//简单写法:
this.$router.push('路由路径')
// 如:this.$router.push('/search')

//完整写法:
this.$router.push({
  path: '路由路径'
})
  • 完整的写法在之后传参的时候会更适用

name 命名路由跳转语法

  • 特点:适合 path 路径长、层级深的场景

  • 前提:

    • 必须在路由规则中配置 name 配置项

      { name: '路由名', path: '/path/xxx/yyy/zzz', component: XXX },
      
    • 通过 name 来进行跳转

      this.$router.push({
        name: '路由名'
      })
      

编程式导航 — path 路径跳转传参

问题

  • 点击搜索按钮,跳转需要把文本框中输入的内容传到下一个页面

两种传参方式

  • 查询参数
  • 动态路由传参

传参

  • 两种跳转方式,对于两种传参方式都支持:
    • path 路径跳转传参
    • name 命名路由跳转传参

path 路径跳转传参(query 传参)

// 简单写法(参数值可以是${双向绑定的参数值})
this.$router.push('/路径?参数名1=参数值1&参数2=参数值2')

// 完整写法(更适合传参 —— 尤其是多个参数的时候,参数值可以是this.xxx动态)
this.$router.push({
  path: '/路径',
  query: {
    参数名1: '参数值1',
    参数名2: '参数值2'
  }
})
  • 不管哪种,接受参数的方式依然是:$route.query.参数名

path 路径跳转传参(动态路由传参)

  • 注意:前提是路由规则已经配置成动态路由的格式 /xx/:yy?
//简单写法(参数值可以是${双向绑定的参数值})
this.$router.push('/路径/参数值')

//完整写法(参数值可以是${双向绑定的参数值})
this.$router.push({
  path: '/路径/参数值'
})
  • 接受参数的方式依然是:$route.params.动态路由的冒号后的命名yy

编程式导航 — name 命名路由传参

name 命名路由跳转传参(query 传参)

this.$router.push({
  name: '路由名字',
  query: {
    参数名1: '参数值1',
    参数名2: '参数值2'
  }
})
  • 还是 $route.query.参数名

name 命名路由跳转传参(动态路由传参)

  • 注意:前提是路由规则已经配置成动态路由的格式 /xx/:yy?
this.$router.push({
  name: '路由名字',
  params: { // params传params接收
    参数名: '参数值',
  }
})
  • 依旧是 $route.params.动态路由的冒号后的命名yy

总结

  • 编程式导航,如何跳转传参:

  • path路径跳转

    • query传参

      this.$router.push('/路径?参数名1=参数值1&参数2=参数值2')
      this.$router.push({
        path: '/路径',
        query: {
          参数名1: '参数值1',
          参数名2: '参数值2'
        }
      })
      
    • 动态路由传参

      this.$router.push('/路径/参数值')
      this.$router.push({
        path: '/路径/参数值'
      })
      
  • name 命名路由跳转

    • query传参

      this.$router.push({
        name: '路由名字',
        query: {
          参数名1: '参数值1',
          参数名2: '参数值2'
        }
      })
      
    • 动态路由传参 (需要配动态路由)

      this.$router.push({
        name: '路由名字',
        params: {
          参数名: '参数值',
        }
      })
      

面经基础版 — 案例效果分析

功能分析

  • 通过演示效果发现,主要的功能页面有两个,一个是列表页,一个是详情页,并且在列表页点击时可以跳转到详情页
  • 底部导航可以来回切换,并且切换时,只有上面的主题内容在动态渲染

实现思路分析:配置路由 + 功能实现

  • 配置路由

    • 首页和面经详情页两个大页面,两个一级路由

    • 首页内嵌套四个可切换的小页面(嵌套二级路由)

    • 面经详情是单独的一个大页面

  • 实现功能

    • 首页请求渲染

    • 跳转传参到详情页,详情页动态渲染

    • 组件缓存,性能优化

面经基础版 — 一级路由配置

  • 针对 router/index.js 文件进行一级路由配置
...
import newFirst from '@/views/newFirst.vue'
import info from '@/views/info.vue'
...


const router = new VueRouter({
  routes: [
    {
      path: '/',
      component: newFirst
    },
    {
      path: '/info',
      component: info
    }
  ]
})

面经基础版 — 二级路由配置

  • 二级路由也叫嵌套路由,当然也可以嵌套三级、四级 ...

使用场景

  • 当在页面中点击链接跳转,只是部分内容切换时,我们可以使用嵌套路由

语法

  • 在一级路由下,配置 children 属性即可
  • 配置二级路由的出口

举例

  • 在一级路由下,配置 children 属性

    • 注意:一级的路由 path 需要加 / 二级路由的 path 不需要加 /

      ...
      import xxxx from '@/views/xxxx.vue'
      import yyyy from '@/views/yyyy.vue'
      ...
      
      const router = new VueRouter({
        routes: [
          {
            path: '/',
            component: newFirst,
            // 别光记得二级路由,把主的显示忘了(加个重定向 —— 初进默认显示页面)
            redirect: '/xxxx'  
            children:[
              //children中的配置项 跟一级路由中的配置项一模一样 
              {path:'/xxxx',component:Xxxx},
              {path:'/yyyy',component:Yyyy},
            ]
          }
        ]
      })
      
  • 注意配置了二级路由后不要忘了 / 时的显示,否则就是空白 —— 重定向

  • 配置二级路由的出口 <router-view></router-view>

    • 当然此处的 <router-view></router-view> 和对应的 <a href> 写在一起

    • 注意: 配置了嵌套路由,一定配置对应的路由出口,否则不会渲染出对应的组件

  • newFirst.vue

<template>
  <div class="wsad">
    <div class="content">
      <!-- 内容部分 -->
      <router-view></router-view>
    </div>
    <nav class="asdfg">
      <a href="#/xxxx">xxxx显示</a>
      <a href="#/yyyy">yyyy显示</a>
    </nav>
  </div>
</template>

面经基础版 — 二级导航高亮

  • 将 a 标签替换成 <router-link></router-link> 组件,配置 to 属性,不用加 #
  • 结合高亮类名实现高亮效果(推荐模糊匹配:router-link-active)
<nav class="tabbar">
  <router-link to="/article">面经</router-link>
  <router-link to="/collect">收藏</router-link>
  <router-link to="/like">喜欢</router-link>
  <router-link to="/user">我的</router-link>
</nav>

<style>
  // F12 可见渲染后真正样式,和内在真正作用的class
   a.router-link-active { 
      color: orange;
    }
</style>

面经基础版 — 首页请求渲染、获取数据

  • 安装 axios 用来发请求

  • 看接口文档,确认请求方式,请求地址,请求参数

  • created 中发送请求,获取数据,存储到 data 中

  • 页面动态渲染

代码实现

  • 安装 axios

    • yarn add axiosnpm i axios
    • i 就是 install
  • 接口文档

请求地址: https://......
请求方式: get
  • created 中发送请求,获取数据,存储到 data 中
 data() {
    return {
      articelList: [],
    }
 },

 async created() {
		const res = await axios.get('https://......')
		this.articelList = res.data.result.rows
 },
  • 需要的时候调用 articelList 即可

面经基础版 — 查询参数传参

  • 跳转详情页需要把当前点击的文章 id 传给详情页,获取数据(两种方式:)

    • 查询参数传参:this.$router.push('/detail?参数1=参数值&参数2=参数值')

    • 动态路由传参:先改造路由再传参 this.$router.push('/detail/参数值')

查询参数传参实现

  • xxxx.vue
<template>
  ... 
      v-for="item in List" :key="item.id" 
      @click="$router.push(`/detail?id=${item.id}`)">
  ...
</template>
  • xxxxDetail.vue
  created(){
    console.log(this.$route.query.id)
  }

动态路由传参

  • 改造路由
  • 动态传参
  • 在详情页获取参数

代码实现

  • 改造路由
  • router/index.js
...
  {
      path: '/detail/:id',
      component: ArticleDetail
  }
  • Article.vue 发送
<div class="article-item" 
     v-for="item in articelList" :key="item.id" 
     @click="$router.push(`/detail/${item.id}`)">
       ....
 </div>
  • ArticleDetail.vue 接收
  created(){
    console.log(this.$route.params.id)
  }

额外优化功能点 — 点击回退跳转到上一页

  • ArticleDetail.vue
<template>
  <div class="article-detail-page">
    <nav class="nav"><span class="back" @click="$router.back()">&lt;</span> 面经详情</nav>
     ....
  </div>
</template>
  • back() 返回即可

面经基础版 — 缓存组件

问题

  • 从面经列表点到详情页,又点返回,数据重新加载了
  • 现在想要试着、希望回到原来的位置
    • 不再重新加载

原因

  • 当路由被跳转后,原来所看到的组件就被销毁了(会执行组件内的 beforeDestroy 和 destroyed 生命周期钩子),重新返回后组件又被重新创建了(会执行组件内的 beforeCreate,created,beforeMount,Mounted 生命周期钩子),所以数据被重又加载了

解决方案

  • 利用 keep-alive 把原来的组件给缓存下来

关于 keep-alive

  • keep-alive 是 Vue 的内置组件,当它包裹动态组件(也就是这里的 <router-view></router-view>)时,会缓存不活动的组件实例,而不是销毁它们

  • keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件中

  • 优点:

    • 在组件切换过程中把切换出去的组件保留在内存中,防止重复渲染 DOM
    • 减少加载时间及性能消耗,提高用户体验性
  • App.vue

<template>
  <div class="">
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>
  • 存在问题:
    • 上述缓存了所有被切换的组件,很可能会出现错乱

keep-alive 的三个属性(按需所配)

  • include : 组件名数组,只有匹配的组件会被缓存

  • exclude : 组件名数组,任何匹配的组件都不会被缓存

    • 只写了不缓存的,所有一般都配合 max 使用
  • max : 最多可以缓存多少组件实例

  • 结合上述属性,App.vue:

<template>
  <div class="h5-wrapper">
    <keep-alive :include="['LayoutPage']">
<!--  或者是写数组:<keep-alive :include="keepArr">  -->
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

额外的两个生命周期钩子

  • keep-alive 的使用会触发两个生命周期函数
  • activated 当组件被激活(使用)的时候触发 —— 进入这个页面的时候触发
  • deactivated 当组件失活(不被使用)的时候触发 —— 离开这个页面的时候触发
    • 组件缓存后就不会执行组件的 created,mounted,destroyed 等钩子了
  • 所以其提供了 actived 和 deactived 钩子,帮我们实现一些业务需求

VueCli 自定义创建项目

  • 注意,这里的前提是 npm -v 正确显示版本,且 node.js 里有 vue.cmd

    • 一般下载了 node 就顺带安装了 npm(可以理解为一种 node.js 内置的一套包管理工具,就可以 npm xxx 下载依赖包了)
    • 没有 vue.cmd 就 npm install -g vue 安装好 vue
    • 再继续下一步安装脚手架
  • 安装脚手架(已安装)

    npm install -g @vue/cli
    
    • 然后就可以 npm list vue 查看 vue 版本指令
    • vue -v 查看脚手架版本指令
  • 创建项目

vue create 项目名
  • 选项
Vue CLI v5.0.8
? Please pick a preset:
  Default ([Vue 3] babel, eslint)
  Default ([Vue 2] babel, eslint)
> Manually select features     这次选择自定义
  • 手动选择下述四个(空格就是选中)

68294185617

  • 选择vue的版本
  3.x
> 2.x
  • 是否使用 history 模式

image-20201025150602129

  • 选择 css 预处理

image-20220629175133593

  • 选择 eslint 的风格(eslint 代码规范的检验工具,检验代码是否符合规范)
  • 比如:const age = 18; => 报错!多加了分号!后面有工具,一保存,全部格式化成最规范的样子

68294191856

  • 选择校验的时机(直接回车)

68294193579

  • 选择配置文件的生成方式(直接回车)

68294194798

  • 是否保存预设,下次直接使用? => 不保存,输入 N

68294196155

  • 等待安装,项目初始化完成:绿色 success

  • 启动项目

npm run serve

ESlint 代码规范及手动修复

  • 代码规范:一套写代码的约定规则。例如:赋值符号的左右是否需要空格?一句结束是否是要加;?等
  • ESLint:是一个代码检查工具,用来检查你的代码是否符合指定的规则(你和你的团队可以自行约定一套规则)
  • 创建项目时,使用的是 JavaScript Standard Style 代码风格的规则

JavaScript Standard Style 规范说明

  • 建议把:https://standardjs.com/rules-zhcn.html 看一遍,然后在写的时候, 遇到错误就查询解决

  • 下面是这份规则中的一小部分:

    • 字符串使用单引号 — 需要转义的地方除外

    • 无分号

    • 关键字后加空格 — if (condition) { ... }

    • 函数名后加空格 — function name (arg) { ... }

    • 坚持使用全等 === 摒弃 == 一 但在需要检查 null || undefined 时可以使用 obj == null

    • 等等

代码规范错误

  • 如果你的代码不符合 standard 的要求会红色提醒

手动修正

  • 如果不认识命令行中的语法报错是什么意思,可以根据错误代码(func-call-spacing, space-in-parens,.....)去 ESLint 规则列表中查找其具体含义
  • 打开 ESLint 规则表,页面搜索这个代码,查找对该规则的一个释义

68294279221

通过 eslint 插件来实现自动修正

  • eslint 会自动高亮错误显示
  • 通过配置,eslint会自动帮助我们修复错误
  • 安装插件

68294292098

  • 如何配置

    • 左下角设置,点击右上角打开设置:settings.json

    • 在打括号内加入以下语句:

      // 当保存的时候,eslint自动帮我们修复错误
      "editor.codeActionsOnSave": {
          "source.fixAll": true
      },
      // 保存代码,不自动格式化
      "editor.formatOnSave": false
      
  • 注意:eslint 的配置文件必须在根目录下,这个插件才能才能生效。打开项目必须以根目录打开,一次打开一个项目

  • 注意:使用了 eslint 校验之后,把 vscode 带的那些格式化工具全禁用了 Beatify

  • settings.json 参考:

{
    "window.zoomLevel": 2,
    "workbench.iconTheme": "vscode-icons",
    "editor.tabSize": 2,
    "emmet.triggerExpansionOnTab": true,
    // 当保存的时候,eslint自动帮我们修复错误
    "editor.codeActionsOnSave": {
        "source.fixAll": true
    },
    // 保存代码,不自动格式化
    "editor.formatOnSave": false
}
posted @ 2024-02-19 22:51  朱呀朱~  阅读(4)  评论(0编辑  收藏  举报