vue核心技术2

130 阅读2分钟

vue核心技术与实战2

路由入门

单页应用程序

  • 单页面应用(SPA):所有功能在一个html页面上实现
  • 具体实例:网易云音乐
开发分类实现方式页面性能开发效率用户体验学习成本首屏加载ESO
单页一个html页面按需更新性能高非常好
多页多个html页面整页更新性能低中等一般中等

单页面应用:系统类网站/内部网站/文档类网站/移动端站点

多页面应用:公司官网/电商类官网

之所以开发效率高,性能高,用户体验好,最大的原因是页面按需更新,按需更新,首先需要明确的就是:访问路径和组件的对应关系,就需要学习路由

路由概念

生活中的路由:设备和ip之间的映射关系

image.png

vue中的路由:路径 和 组件 的映射关系

image.png

image.png

根据路由就能知道不同路径应该匹配渲染那个组件

VueRouter

目标:认识插件VueRouter,掌握VueRouter的基本使用步骤

作用:修改地址栏路径时,切换显示匹配的组件

说明:是Vue官方的一个路由插件,是一个第三方包

官网:官网链接

VueRouter的基本使用(5+2)

5个基础步骤(固定)

  1. 下载:下载VueRouter模块到当前工程,版本3.6.5

yarn add vue-router@3.6.5

  1. 引入

import VueRouter from 'vue-router'

  1. 安装注册

Vue.use(VueRouter)

  1. 创建路由对象 const router=new VueRouter()

  2. 注入,将路由对象注入到new Vue实例中,建立关联

new Vue({ render:h =>h(App), router }).$mount('#app')

2个核心步骤

  1. 创建需要的组件(views目录),配置路由规则
import Vue from 'vue'
//路由的使用步骤 5+2
//1. 下载v3.6.5版本
//2.引入
//3. 安装注册 Vue.use
//4. 创建路由对象
//5. 注入到new Vue中,建立关联


//两个核心步骤
// 1. 建组件(view目录),配规则
// 2. 准备导航链接,配置路由出口(匹配的组件展示的位置)
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import Friend from '@/views/Friend.vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)  //进行插件初始化
const router= new VueRouter({
  //routes路由规则们
  //route 一条路由规则{path:路径,component:组件}
routes:[
  {path:'/find',component:Find},
  {path:'/my',component:My},
  {path:'/friend',component:Friend}
  ],
  linkActiveClass:  'active',
  linkExactActiveClass:'Eactive'

})

export default router
  1. 配置导航,配置路由出口(路径匹配的组件显示的位置)
 <!-- 路由出口,匹配的组件所展示的位置 -->
      <router-view></router-view>

组件存放目录问题

路由相关的组件,为什么放在views目录呢?

组件分类:.vue文件分为两类页面组件复用组件 ---注意都是vue组件(本质无区别)

image.png

分类开来更容易维护

  • src/views文件夹

页面组件-页面展示-配合路由用

  • src/components文件夹

复用组件-展示数据-常用于复用

路由进阶

路由模块封装

路由配置在main.js中不利于维护,所以将路由模块从main.js中抽离出来拆分模块,利于维护

以后如何快速引入组件? 基于 @ 指代 src 目录,从 src 目录出发找组件

声明式导航&导航高亮

需求:实现导航高亮效果 image.png

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

  1. 能跳转,配置to属性指定路径(必须配置),本质还是a标签,其一样的作用,to配置的路径不用加#键
  2. 能高亮,默认就会提供高亮类名,可以直接设置高亮样式(自带激活时的类名)
  <div class="footer_wrap">
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
      <router-link to="/friend">朋友</router-link>
    </div>

自带的类名写的样式

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

两个类名-精确匹配&模糊匹配

image.png 说明:router-link的两个高亮类名太长了,我们希望能定制

如何自定义 router-link 的 两个高亮类名?

  1. linkActiveClass 模糊匹配 类名自定义
  2. linkExactActiveClass 精确匹配 类名自定
Vue.use(VueRouter)  //进行插件初始化
const router= new VueRouter({
  //routes路由规则们
  //route 一条路由规则{path:路径,component:组件}
routes:[
  {path:'/find',component:Find},
  {path:'/my',component:My},
  {path:'/friend',component:Friend}
  ],
  linkActiveClass:  'active',
  linkExactActiveClass:'Eactive'

})

声明式导航传参

目标:在跳转路由时,进行传值

  1. 查询参数传参
  • 语法格式如下:to="/path?参数名=值"
  • 对应页面组件接受传递过来的值:$route.query.参数值
  1. 动态路由传参
  • 配置动态路由
const router= new Vuerouter({
routes:[
...,
{
     path:'/search/:words',
     component:Search
}
]
})
  • 配置导航链接

to="/path/参数值"

  • 对应页面组件接收传递过来的值

$route.params.参数名

两种传参方式的区别: image.png

动态路由参数可选符

配了路由path:"/search/words"按照下面步骤操作,不传参数时,会显示空白,所以/search/words表示,必须要穿参数,如果不传参数,也希望匹配,可以加个可选符”?“

路由重定向

问题:网页刚打开时,url默认是/路径,未匹配到组件时,会出现空白

说明:重定向-->匹配path后,强制跳转path路径

语法:{path:匹配路径,redirect:重定向到的路径}

// 创建了一个路由对象
const router = new VueRouter({
  //一旦采用了history模式,地址栏就没有了#,需要后台配置访问规则
  mode:'history',
  routes: [
    { path :'/', redirect:'/Home'  },
    { path: '/home', component: Home },
    { name:'search',path: '/search', component: Search },
    { path:'*', component:NotFound}
  ]
})

vue路由404

作用:当路径找不到匹配时,给提示页面

位置:配在路由最后

语法:path:" * "(任意路径)-前面不匹配就匹配最后这个 { path:'*', component:NotFound}

Vue路由模式设置

问题:路由的路径看起来不自然,有#,能否切换成正常的路径形式?

mode:'history',

编程式导航

问题:点击按钮跳转如何实现?

编程式导航:用js代码来进行跳转

 1. 通过path路径的方式跳转
      (1)【简写】
      静态跳转传参
      this.$router.push('路由路径?参数名=参数值')
      动态路由传参
      this.$router.push('/路由路径')
     静态跳转传参     
     this.$router.push(`/search?key=${this.inpValue`) --
     动态路由传参     this.router.push(`/search/${this.inpValue}`) --
      (2)【完整写法】更适合传参
      静态跳转传参
      this.$router.push({
        path:'路由路径'
        query:{
          参数名:参数值,
          参数名:参数值
        }
      })
静态跳转传参示例:
    this.$router.push({
    path:'/search'
    query:{
    key:this.inpValue
    }
    })
    动态路由传参示例:
    this.$router.push({
      path:`/search/${this.inputValue}`
    })
    */
    /* 
       2.通过命名路由的方式跳转(需要在index中给相应的路由路径起名字name:xxx)
        然后使用
       this.$router.push({
       name:'起的名字'
       query:{参数名:参数值},用query.key接收
       params:{参数名:参数值},用params.words(words是自定义的)接收
       示例:
       this.$router.push({
      name:'search',
      params:{
        word:this.inpValue
      }
       })

两种语法:

  1. path路径跳转(简易方便)

this.$router.push('路由路径')

this.$router.push({
    path:'路由路径'
})
  1. name命名跳转(适合path路径长的场景)
this.$router.push({
name:'路由名'
})
{name:'路由名',path:'/path/xxx',component:xxx}

编程式导航传参

问题:点击搜索按钮:跳转需要传参如何实现?

两种传参方式:查询参数+动态路由传参

两种跳转方式:对于两种传参方式都支持

  1. path路径跳转传参 query传参 image.png

动态路由params传参

image.png

  1. name命名路由跳转传参 query传参

image.png 动态路由传参

image.png

总结:

通过命名路由的方式跳转(需要在index中给相应的路由路径起名字name:xxx)
        然后使用
       this.$router.push({
       name:'起的名字'
       query:{参数名:参数值},用query.key接收
       params:{参数名:参数值},用params.words(words是自定义的)接收
       })
   例如:
    this.$router.push({
      name:'search',
      params:{
        word:this.inpValue
      }
    })

综合案例:面经基础版

image.png

案例分析:

  1. 配路由
  • 首页和面经详情,两个一级路由(首页显示-一级路由)
  • 内嵌四个可切换页面(点击切换-二级路由)
  1. 实现功能
  • 首页请求渲染
  • 跳转传参到详情页,详情页渲染
  • 组件缓存,优化性能

二级路由

const router = new VueRouter({
  routes: [//一级路由
    {
      path:'/',
      component:Layout,
      redirect:'/article',
      children:[//二级路由
        {
          path:'/article',
          component:Article
        },
        {
          path:'/collect',
          component:Collect
        },
        {
          path:'/like',
          component:Like
        },
        {
          path:'/user',
          component:User
        }
      ]
    },
    {//一级路由
      path:'/detail/:id',
      component:ArticleDetail
    }
  ]
})

导航高亮

导航内容,二级路由出口,首页内容细节都在首页Layout

<template>
  <div class="h5-wrapper">
    <div class="content">
      <!-- 二级路由出口 -->
      <router-view>

      </router-view>
      
    </div>
    <nav class="tabbar">
      <!-- 导航高亮
            1.将a标签替换成routerlink(to)
            2.结合高亮类名实现高亮效果
      -->
      <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>
  </div>
</template>

<script>
export default {
  //组件名(如果没有配置name,才会找文件名作为组件名)
  name: 'LayoutPage',
  activated (){
    alert('你好,欢迎回到首页')
  }
}
</script>

//导航高亮样式
    a.router-link-active{
      color: orangered;
    }


请求渲染

路由开始跳转时发送请求,渲染页面

<span @click="$router.back()" class="back">&lt;</span>返回上一页

<template>
  <div class="article-page">
    <div
    v-for="item in articles" :key="item.id"
    @click="$router.push(`/detail/${item.id}`)"
      class="article-item">
      <div class="head">
        <img :src=item.creatorAvatar alt="" />
        <div class="con">
          <p class="title">{{item.stem}}</p>
          <p class="other">{{item.creatorName}} | {{item.createdAt}}</p>
        </div>
      </div>
      <div class="body">
        {{ item.content }}
      </div>
      <div class="foot">点赞 {{item.likeCount}} | 浏览 {{item.views}}</div>
    </div>
  </div>
</template>
<script>
//首页请求渲染
//1. 安装axios
//2. 看接口文档,确认请求方式,请求地址,请求参数
//                请求地址:https://mock.boxuegu.com/mock/3083/articles
//                请求方式:get
//3. created中发请求,获取数据,存起来
//4. 页面动态渲染


//跳转详情页传参
//1. 查询参数传参 (适合多个参数传参)
//    ?参数=参数值     =>this.$route.query.参数名
//2. 动态路由传参 (单个参数传参更优雅方便)
//    改造路由 =>/路径/:参数  => this.$route.params.参数名
//    (1). 访问/重定向到/article(redirect)
//    (2). 返回上一页   =>添加点击事件$router.back()

import axios from 'axios'
export default {
  name: 'ArticlePage',
  data(){
    return{
      articles:[]
    }
  },
 async created(){
      const res=await axios.get('https://mock.boxuegu.com/mock/3083/articles')
      // console.log(res)
      this.articles=res.data.result.rows
    }
};
</script>

路由传参

复习路由跳转传参知识

//跳转详情页传参
//1. 查询参数传参 (适合多个参数传参)
//    ?参数=参数值     =>this.$route.query.参数名
//2. 动态路由传参 (单个参数传参更优雅方便)
//    改造路由 =>/路径/:参数  => this.$route.params.参数名
//    (1). 访问/重定向到/article(redirect)
//    (2). 返回上一页   =>添加点击事件$router.back()

动态路由传参

@click="$router.push(’/detail/${item.id}‘)"动态路由传参

接收参数,使用其信息发送请求

async created(){
    console.log(this.$route.params.id)
    const id=this.$route.params.id
    const {data}=await axios.get(`https://mock.boxuegu.com/mock/3083/articles/${id}`)
    console.log(data)
    this.articlemsg=data.result
  }

路由配置

{
      path:'/detail/:id',
      component:ArticleDetail
    }

组件缓存Keep-alive

问题:从面经 点到 详情页,返回的时候发现数据被重新加载了,如果希望回到原来的位置,就需要缓存特定的组件

原因:路由跳转后,组件被销毁了,返回回来之后组件又被重建了,所以数据被重新加载了

解决:利用keep-alive将组件缓存下来

image.png

  1. keep-alive是什么?

keep-alive是Vue的内置组件,当他包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们。keep-alive是一个抽象组件,它自身不会渲染成一个DOM元素,也不会出现在父组件链中

  1. keep-alive的优点

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

  1. keep-alive的三个属性

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

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

max:最多可以缓存多少组件实例

image.png

  1. keep-alive的使用会触发两个生命周期函数

image.png

//页面激活--进入页面时执行的函数
 activated (){
    alert('你好,欢迎回到首页')
  }
<!-- 包裹了keep-alive以及路由匹配的组件都会被缓存
layout组件(被缓存)多两个生命周期钩子
--active 激活时,组件被看到时触发
--deactived 失活时,离开页面组件看不见时触发
articleDetailPage组件(未被缓存)

需求:只希望Layout被缓存,incloude配置
:include=“组件名数组”-->
    <keep-alive :include="keepArr">
      <router-view></router-view>
    </keep-alive>
    
    
    <script>
export default {
  name: 'h5-wrapper',
  data(){
    return{
      //缓存组件名的数组
      keepArr:['LayoutPage']
    }
  },
  
}
</script>