Vue2+Vue3基础入门到实战项目(五)——课程学习笔记

简介: Vue2+Vue3基础入门到实战项目(五)——课程学习笔记

大家好, Capybara 继续与大家一起学习Vue框架。书读百遍其义自见。

day06

路由进阶

路由模块封装

router/index.js

所抽离内容包括:导入组件、(额外需要)导入Vue、导入VueRouter插件、

创建路由对象、导出路由对象

需要注意路径写法(推荐使用绝对路径 @代表当前src目录)

效果:


使用router-link替代a标签实现高亮

本质渲染还是a标签,to无需#,且能高亮

代码:

<template>
  <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>
</template>
……

效果:

本质是a元素

自带两个可使用高亮类名:

选中时更改背景颜色:

小结:

精确匹配&模糊匹配

关于两个类名

在url后加上one,仍然匹配(router-link-active)

设置 .router-link-active

小结:

自定义匹配的类名

长有长的好处,不容易重名。

配置代码(router/index.js):

import Find from '@/views/Find'
import My from '@/views/My'
import Friend from '@/views/Friend'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
// 创建了一个路由对象
const router = new VueRouter({
  // routes 路由规则们
  // route  一条路由规则 { path: 路径, component: 组件 }
  routes: [
    { path: '/find', component: Find },
    { path: '/my', component: My },
    { path: '/friend', component: Friend },
  ],
  // link自定义高亮类名
  linkActiveClass: 'active', // 配置模糊匹配的类名
  linkExactActiveClass: 'exact-active' // 配置精确匹配的类名
})
export default router

浏览器可看到,类名发送变化:

小结:

声明式导航-跳转传参

传参方式有两种:

1.查询参数传参

点击链接,从首页跳转到搜索页,希望把链接信息传过去

直接跳转

(不带参数)关键字写死

携带查询参数:

在页面获取参数:

页面显示参数:

如果想要基于参数去发送请求?

在哪发?—— created

获取参

数?this.$route.query.key

2.动态路由传参

代码:

(router/index.js)

import Home from '../views/Home.vue'
import Search from '../views/Search.vue'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
// 创建了一个路由对象
const router = new VueRouter({
  routes: [
    { path: '/home', component: Home },
    { path: '/search/:words', component: Search }
  ]
})
export default router

home.vue

<template>
  <div class="home">
    <div class="logo-box"></div>
    <div class="search-box">
      <input type="text">
      <button>搜索一下</button>
    </div>
    <div class="hot-link">
      热门搜索:
      <router-link to="/search/黑马程序员">黑马程序员</router-link>
      <router-link to="/search/前端培训">前端培训</router-link>
      <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
    </div>
  </div>
</template>
<script>
export default {
  name: 'FindMusic'
}
</script>
<style>
.logo-box {
  height: 150px;
  background: url('../assets/logo.jpeg') no-repeat center;
}
.search-box {
  display: flex;
  justify-content: center;
}
.search-box input {
  width: 400px;
  height: 30px;
  line-height: 30px;
  border: 2px solid #c4c7ce;
  border-radius: 4px 0 0 4px;
  outline: none;
}
.search-box input:focus {
  border: 2px solid #ad2a26;
}
.search-box button {
  width: 100px;
  height: 36px;
  border: none;
  background-color: #ad2a26;
  color: #fff;
  position: relative;
  left: -2px;
  border-radius: 0 4px 4px 0;
}
.hot-link {
  width: 508px;
  height: 60px;
  line-height: 60px;
  margin: 0 auto;
}
.hot-link a {
  margin: 0 5px;
}
</style>

效果:

两种传参方式的区别

小结:

动态路由参数可选符

路由重定向

redirect

路由404

添加一个NotFound组件

router/index.js

import Home from '@/views/Home'
import Search from '@/views/Search'
import NotFound from '@/views/NotFound'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
// 创建了一个路由对象
const router = new VueRouter({
  routes: [
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { path: '/search/:words?', component: Search },
    { path: '*', component: NotFound }
  ]
})
export default router

效果(访问 list 无匹配):

路由模式

router/index.js

import Home from '@/views/Home'
import Search from '@/views/Search'
import NotFound from '@/views/NotFound'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
// 创建了一个路由对象
const router = new VueRouter({
  // 注意:一旦采用了 history 模式,地址栏就没有 #,需要后台配置访问规则
  mode: 'history',
  routes: [
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { name: 'search', path: '/search/:words?', component: Search },
    { path: '*', component: NotFound }
  ]
})
export default router

编程式导航

用JS代码来进行跳转

     1. 通过路径的方式跳转

     // (1) this.$router.push('路由路径') [简写]

     // this.$router.push('/search')

     // (2) this.$router.push({     [完整写法]

     //         path: '路由路径'

     //     })

     // this.$router.push({

     //   path: '/search'

     // })

     2. 通过命名路由的方式跳转

       (需要给路由起名字) 适合长路径

     //    this.$router.push({

     //        name: '路由名'

     //    })

router/index.js

import Home from '@/views/Home'
import Search from '@/views/Search'
import NotFound from '@/views/NotFound'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
// 创建了一个路由对象
const router = new VueRouter({
  // 注意:一旦采用了 history 模式,地址栏就没有 #,需要后台配置访问规则
  mode: 'history',
  routes: [
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { name: 'search', path: '/search/:words?', component: Search },
    { path: '*', component: NotFound }
  ]
})
export default router

Home.vue

<template>
  <div class="home">
    <div class="logo-box"></div>
    <div class="search-box">
      <input type="text">
      <button @click="goSearch">搜索一下</button>
    </div>
    <div class="hot-link">
      热门搜索:
      <router-link to="/search/黑马程序员">黑马程序员</router-link>
      <router-link to="/search/前端培训">前端培训</router-link>
      <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
    </div>
  </div>
</template>
<script>
export default {
  name: 'FindMusic',
  methods: {
    goSearch () {
      // 1. 通过路径的方式跳转
      // (1) this.$router.push('路由路径') [简写]
      // this.$router.push('/search')
      // (2) this.$router.push({     [完整写法]
      //         path: '路由路径' 
      //     })
      // this.$router.push({
      //   path: '/search'
      // })
      // 2. 通过命名路由的方式跳转 (需要给路由起名字) 适合长路径
      //    this.$router.push({
      //        name: '路由名'
      //    })
      this.$router.push({
        name: 'search'
      })
    }
  }
}
</script>
<style>
.logo-box {
  height: 150px;
  background: url('@/assets/logo.jpeg') no-repeat center;
}
.search-box {
  display: flex;
  justify-content: center;
}
.search-box input {
  width: 400px;
  height: 30px;
  line-height: 30px;
  border: 2px solid #c4c7ce;
  border-radius: 4px 0 0 4px;
  outline: none;
}
.search-box input:focus {
  border: 2px solid #ad2a26;
}
.search-box button {
  width: 100px;
  height: 36px;
  border: none;
  background-color: #ad2a26;
  color: #fff;
  position: relative;
  left: -2px;
  border-radius: 0 4px 4px 0;
}
.hot-link {
  width: 508px;
  height: 60px;
  line-height: 60px;
  margin: 0 auto;
}
.hot-link a {
  margin: 0 5px;
}
</style>

小结:

编程式导航传参 ( 查询参数传参 & 动态路由传参 )

path路径跳转传参

传入输入框内容:

       两种传参方式:查询参数传参和动态路由传参 都支持

       完整写法更适合多参数情况(不用一个一个拼接)

name命名路由跳转传参

在路由中配置动态路由

使用params传参

在所跳转的组件中,通过 $route.params.参数名 获取传入参数值

代码:

router/index.js

import Home from '@/views/Home'
import Search from '@/views/Search'
import NotFound from '@/views/NotFound'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
// 创建了一个路由对象
const router = new VueRouter({
  // 注意:一旦采用了 history 模式,地址栏就没有 #,需要后台配置访问规则
  mode: 'history',
  routes: [
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { name: 'search', path: '/search/:words?', component: Search },
    { path: '*', component: NotFound }
  ]
})
export default router

Home.vue

<template>
  <div class="home">
    <div class="logo-box"></div>
    <div class="search-box">
      <input v-model="inpValue" type="text">
      <button @click="goSearch">搜索一下</button>
    </div>
    <div class="hot-link">
      热门搜索:
      <router-link to="/search/黑马程序员">黑马程序员</router-link>
      <router-link to="/search/前端培训">前端培训</router-link>
      <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
    </div>
  </div>
</template>
<script>
export default {
  name: 'FindMusic',
  data () {
    return {
      inpValue: ''
    }
  },
  methods: {
    goSearch () {
      // 1. 通过路径的方式跳转
      // (1) this.$router.push('路由路径') [简写]
      //     this.$router.push('路由路径?参数名=参数值')
      // this.$router.push('/search')
      // 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.inpValue}`
      // })
      // 2. 通过命名路由的方式跳转 (需要给路由起名字) 适合长路径
      //    this.$router.push({
      //        name: '路由名'
      //        query: { 参数名: 参数值 },
      //        params: { 参数名: 参数值 }
      //    })
      this.$router.push({
        name: 'search',
        // query: {
        //   key: this.inpValue
        // }
        params: {
          words: this.inpValue
        }
      })
    }
  }
}
</script>
……

小结:

个人总结

路由导航 传参 跳转  三问:

1.哪种路由导航?

2.传参方式是什么?

3.如果是编程式导航,跳转方式是什么?

路由导航的种类有两种:

1.声明式导航——使用router-link组件,点击后跳转  路由跳转的方法:<router-link to=" ">

2.编程式导航——触发事件,用JS代码来进行跳转   路由跳转的方法: this.$router.push()

路由传参方式也有两种:

1.查询参数传参——在路由中拼接查询参数 形式:?key=value

       传过去的参数,通过 this.$route.query.key 获取

2.动态路由传参——在路由中直接拼接参数 形式:/value (前提:在router中配置动态路由 '…/:key' )

       传过去的参数,通过 this.$route.params.key 获取

编程式导航的跳转方式有两种:

path 路径跳转

name 命名路由跳转

传参方式  跳转方式可以两两组合,实现 携带参数的路由跳转

其中$router.push() 方法的实参有两种写法:($router.push()  ——>  编程式导航

        1.简写:$router.push('路由路径')

       ①编程式导航-查询参数传参-path路径跳转

       ②编程式导航-动态路由传参-path路径跳转

       2.完整写法(更适合传参,不用一个一个参数拼接)

       其中,命名路由跳转只能使用完整写法

        ①编程式导航-查询参数传参-path路径跳转

        ②编程式导航-动态路由传参-path路径跳转

       ③编程式导航-查询参数传参-name命名跳转

       ④编程式导航-动态路由传参-name命名跳转

根据查询

声明式导航   也可以使用   命名路由跳转   方式

个人认为:

在元素(router-link)的属性写一个对象(JS代码)阅读性较差,故少用

综合案例:面经基础版

案例分析:

面经基础版-路由配置

一级路由

二级路由(还要准备第二级路由出口)

二级路由出口

高亮,a换成router-link,推荐使用模糊匹配类名,router-link-active

加上高亮样式

效果:

面经基础版-首页请求渲染

步骤:

请求数据:

然后在模板中渲染即可。

面经基础版-传参(查询参数&动态路由)

注册点击事件:

传参方式:

查询参数传参:

地址栏处会带上id:

动态路由传参(单个参数更优雅方便):

配置动态路由

不用写上   id=

修复小bug

回到首页时:

出现空白(因为没有匹配到任何二级路由)

解决办法:重定向

给头部导航的返回小箭头添加返回功能( $router.back() ):

面经基础版-详情页渲染

发送请求获取数据:

插值语法渲染:

有时候出现空白:

有的内容没渲染出来

为什么?发请求需要时间,有一小段时间,article为空。

解决方法:加上v-if,有内容才去渲染

面经基础版-缓存组件

keep-alive

实操:

detail也被缓存了(不需要被缓存)

注意:name优先级更高

使用keep-alive的include属性

被缓存组件多两个生命周期钩子

实操:

进入时:

点击面经进入详情页面后,再返回,created mounted destroyed不会再被触发。

如果希望回到首页有提示等,在哪实现?

提供了actived deactived

小结:

自定义创建项目

1.安装脚手架 (已安装)

npm i @vue/cli -g

2.创建项目

vue create hm-exp-mobile
  • 选项
Vue CLI v5.0.8
? Please pick a preset:
  Default ([Vue 3] babel, eslint)
  Default ([Vue 2] babel, eslint)
> Manually select features     选自定义
  • 手动选择功能

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

  • 选择css预处理

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

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

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

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

  • 等待安装,项目初始化完成

  • 启动项目
cd 
npm run serve

ESLint手动修正代码规范错误

举例:

使用注意:

以 vue create 的文件夹(目录)作为根目录

运行报错:

根据规范说明找错:

理解错误:

ESLint自动修正代码规范错误

设置——>打开设置

相关文章
|
9天前
vue3【实战】语义化首页布局
vue3【实战】语义化首页布局
28 2
|
9天前
|
存储 容器
vue3【实战】来回拖拽放置图片
vue3【实战】来回拖拽放置图片
19 2
|
11天前
|
存储 JavaScript 数据安全/隐私保护
vue实战——登录【详解】(含自适配全屏背景,记住账号--支持多账号,显隐密码切换,登录状态保持)
vue实战——登录【详解】(含自适配全屏背景,记住账号--支持多账号,显隐密码切换,登录状态保持)
16 1
|
11天前
|
JavaScript
vue实战——404页面模板001——男女手电筒动画
vue实战——404页面模板001——男女手电筒动画
17 1
|
9天前
|
JavaScript
vue3 【实战】封装 “心跳“ 组件
vue3 【实战】封装 “心跳“ 组件
17 0
|
9天前
vue3【实战】可撤销重做的 input 输入框
vue3【实战】可撤销重做的 input 输入框
11 0
|
10天前
|
JavaScript 前端开发 程序员
Vue2入门(安装Vue、devtools,创建Vue)以及MVVM分层思想
Vue2入门(安装Vue、devtools,创建Vue)以及MVVM分层思想
9 0
|
2天前
|
JavaScript
|
4天前
|
JavaScript
【vue】el-dialog 内的tinymce弹窗被遮挡的解决办法 及 tinymce打开弹出菜单后直接关闭对话组件,导致该弹出菜单残留
【vue】el-dialog 内的tinymce弹窗被遮挡的解决办法 及 tinymce打开弹出菜单后直接关闭对话组件,导致该弹出菜单残留
16 6
|
1天前
|
存储 缓存 JavaScript
vue代码优化方案
【7月更文挑战第13天】 **Vue.js 优化要点:** 分解大组件以提高复用性和加载速度;利用计算属性与侦听器优化数据处理;使用Object.freeze()减少响应式数据;借助Vuex或Composition API管理状态;实现虚拟滚动和无限加载提升长列表性能;路由懒加载减少初始加载时间;用Vue DevTools检测性能瓶颈;定期代码审查与重构;应用缓存策略;遵循最佳实践与团队规范,提升应用整体质量。
10 2