2024年前端最新Vue2(7),数据库开发面试自我介绍怎么说

css

1,盒模型
2,如何实现一个最大的正方形
3,一行水平居中,多行居左
4,水平垂直居中
5,两栏布局,左边固定,右边自适应,左右不重叠
6,如何实现左右等高布局
7,画三角形
8,link @import导入css
9,BFC理解

js

1,判断 js 类型的方式
2,ES5 和 ES6 分别几种方式声明变量
3,闭包的概念?优缺点?
4,浅拷贝和深拷贝
5,数组去重的方法
6,DOM 事件有哪些阶段?谈谈对事件代理的理解
7,js 执行机制、事件循环
8,介绍下 promise.all
9,async 和 await,
10,ES6 的 class 和构造函数的区别
11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式,
12,介绍一下rAF(requestAnimationFrame)
13,javascript 的垃圾回收机制讲一下,
14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

}
})


#### 6.2.使用 watch 检测用户名是否可用


监听 username 值的变化,并使用 axios 发起 Ajax 请求,检测当前输入的用户名是否可用


代码示例:



<script src="./lib/vue-2.6.12.js"></script>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

<script>

const vm = new Vue({
el: “#app”,

data: {
username: ‘’
},

// 所有的侦听器都应该被定义到 watch 节点下
watch: {
// 侦听器本质上是一个函数,要监听哪个数据的变化,就把数据名作为方法即可
// 新值在前,旧值在后
username(newVal) {
if(newVal===‘’){
return ;
}
// 1.调用 JQ 中的 ajax 发起请求,判断 newVal 是否被占用
$.get(‘http://localhost:9090/user/EixtUserName/’+newVal,function(result){
console.log(result);
})
}
}
})


#### 6.3.immediate 选项


​ 默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使


用 `immediate` 选项。


代码示例:



<script src="./lib/vue-2.6.12.js"></script>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

<script>

const vm = new Vue({
el: “#app”,

data: {
username: ‘admin’
},

// 所有的侦听器都应该被定义到 watch 节点下
watch: {
// 定义对象格式的侦听器
username: {
handler(newVal) {
if (newVal === ‘’) {
return;
}
// 1.调用 JQ 中的 ajax 发起请求,判断 newVal 是否被占用
$.get(‘http://localhost:9090/user/EixtUserName/’ + newVal, function (result) {
console.log(result);
})
},

// immediate 选项的默认值是 false
// immediate 的作用是:控制侦听器是否自动触发一次
immediate: true
}
}
})


#### 6.4.deep 选项


​ 如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选


项。


代码示例:



<script src="./lib/vue-2.6.12.js"></script>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

<script>

const vm = new Vue({
el: “#app”,

data: {
// 用户信息对象
info: {
username: ‘admin’
}
},

// 所有的侦听器都应该被定义到 watch 节点下
watch: {
info: {
handler(newVal) {
const userName = newVal.username
if (userName === ‘’) {
return;
}
// 1.调用 JQ 中的 ajax 发起请求,判断 newVal 是否被占用
$.get(‘http://localhost:9090/user/EixtUserName/’ + userName, function (result) {
console.log(result);
})
},

// 开启深度监听,只要对象中任何一个属性变化了,都会触发对象的侦听器
deep: true,

immediate: true
}
}
})


#### 6.5.监听对象单个属性的变化


如果只想监听对象中单个属性的变化,则可以按照如下的方式定义 watch 侦听器。


代码示例:



<script src="./lib/vue-2.6.12.js"></script>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

<script>

const vm = new Vue({
el: “#app”,

data: {
// 用户信息对象
info: {
username: ‘admin’
}
},

// 所有的侦听器都应该被定义到 watch 节点下
watch: {
// 如果要监听的是对象的子属性的变化,则必须包裹一层单引号
‘info.username’(newVal) {
if (newVal === ‘’) {
return;
}
// 1.调用 JQ 中的 ajax 发起请求,判断 newVal 是否被占用
$.get(‘http://localhost:9090/user/EixtUserName/’ + newVal, function (result) {
console.log(result);
})
},

immediate: true
}
})


### 7.计算属性


#### 7.1.什么是计算属性


计算属性指的是通过一系列运算之后,最终得到一个属性值。


这个动态计算出来的属性值可以被模板结构或 methods 方法使用。


#### 7.2.计算属性的特点


1. 虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性
2. 计算属性会缓存计算的结果,只有计算属性依赖的数据变化时,才会重新进行运算


代码示例:



Document
R:

// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: ‘#app’,
data: {
// 红色
r: 0,
// 绿色
g: 0,
// 蓝色
b: 0
},
methods: {
// 点击按钮,在终端显示最新的颜色
show() {
console.log(this.rgb)
}

},

// 所有的计算属性都要定义到 computed 节点下
// 计算属性在定义的是时候,要定义成 方法格式
computed: {

// rgb 作为一个计算属性,被定义成了方法格式
// 最终,在这个方法中要返回一个生成好的 rgb(x,y,z) 的字符串
rgb() {
return rgb(${this.r},${this.g},${this.b});
}
}
});


### 8.axios



> 
> axios 是一个专注于网络请求的库!
> 
> 
> 


#### 8.1.axios 的基本使用


##### 8.1.1.发起 GET 请求:


代码示例:



<script>

// 1.调用 axios 方法得到的返回值是 Promise 对象
axios({
// 请求方式
method:‘GET’,
// 请求地址
url:‘http://localhost:9090/user/AllUser’
}).then(function(result){
console.log(result.data);
})


代码示例(传参):



<script>

// 1.调用 axios 方法得到的返回值是 Promise 对象
axios({
// 请求方式
method: ‘GET’,
// 请求地址 http://localhost:9090/user/selectUserById?id=1
url: ‘http://localhost:9090/user/selectUserById’,
// URL 中的查询参数
params: {
id : 1
},
// 请求体参数
data: {}
}).then(function (result) {
console.log(result.data);
})


简化1:



发起GET请求

<script src="./lib/axios.js"></script>
<script>

document.querySelector(‘#btnGet’).addEventListener(‘click’, async function () {
// 如果调用某个方法的返回值是 Promise 示例,则前面可以添加 await
// await 只能用在被 async 修饰的方法中
const { data } = await axios({
// 请求方式
method: ‘GET’,
// 请求地址
url: ‘http://localhost:9090/user/AllUser’,
})

console.log(data);
})


简化2:



发起GET请求

<script src="./lib/axios.js"></script>
<script>

document.querySelector(‘#btnGet’).addEventListener(‘click’, async function () {
// 解构赋值的时候,使用 : 进行重命名
// 1.调用 axios 之后,使用 async / await 进行简化
// 2.使用解构赋值,从 axios 封装的大对象中,把 data 属性解构出来
// 3.把解构出来的 data 属性,使用 冒号 进行重命名,一般都重命名为 {data: res}
const { data: res } = await axios({
// 请求方式
method: ‘GET’,
// 请求地址
url: ‘http://localhost:9090/user/AllUser’,
})

console.log(res.data);
})


##### 8.1.2.发起 POST 请求:



发起POST请求

<script src="./lib/axios.js"></script>
<script>

document.querySelector(‘#btnPost’).addEventListener(‘click’, function () {
axios({
// 请求方式
method: ‘POST’,
// 请求地址
url: ‘http://localhost:9090/user/register’,

// 请求体参数
data: {
userName:‘post测试’,
nickName:‘post测试’,
password:‘123456’,
email:‘123456@qq.com’
}
}).then(function (result) {
console.log(result);
})
})


简化:



发起POST请求

<script src="./lib/axios.js"></script>
<script>

document.querySelector(‘#btnPost’).addEventListener(‘click’, async function () {
// 如果调用某个方法的返回值是 Promise 示例,则前面可以添加 await
// await 只能用在被 async 修饰的方法中
const { data } = await axios({
// 请求方式
method: ‘POST’,
// 请求地址
url: ‘http://localhost:9090/user/register’,

// 请求体参数
data: {
userName: ‘post测试111’,
nickName: ‘post测试111’,
password: ‘123456’,
email: ‘123456111@qq.com’
}
})

console.log(data);
})


##### 8.1.3.基于axios.get和axios.post发起请求


代码示例:



<button id="btnGet">GET</button>

<button id="btnPost">POST</button>

<script src="./lib/axios.js"></script>

<script>

document.querySelector(‘#btnGet’).addEventListener(‘click’, async function () {

const { data: res } = await axios.get(‘http://localhost:9090/user/selectUserById’, {
// get参数
params: {
id: 1
}
})
console.log(res);
})

// ---------------------------------

document.querySelector(‘#btnPost’).addEventListener(‘click’, async function () {

const { data: res } = await axios.post(‘http://localhost:9090/user/register’,
{userName: ‘post测试222’,nickName: ‘post测试222’,password: ‘123456’,email: ‘123456222@qq.com’})
console.log(res);
})


### 9.vue-cli


#### 9.1.什么是 vue-cli


vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化的 Vue 项目的过程。


引用自 vue-cli 官网上的一句话:


程序员可以专注在撰写应用上,而不必花好几天去纠结 webpack 配置的问题。


中文官网:https://cli.vuejs.org/zh/


#### 9.2.安装和使用


vue-cli 是 npm 上的一个全局包,使用 npm install 命令,即可方便的把它安装到自己的电脑上:



npm install -g @vue/cli


基于 vue-cli 快速生成工程化的 Vue 项目:



vue create 项目的名称


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WStiaBRC-1671884043149)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219153759222.png)]](https://img-blog.csdnimg.cn/b65fb56ead24498595c6b1440ee43f05.png)


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UB2eMXi2-1671884043149)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219154337721.png)]](https://img-blog.csdnimg.cn/64772803a73842dabe2a8b48d8d493b6.png)


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XycJq9xB-1671884043149)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219154412743.png)]](https://img-blog.csdnimg.cn/7cd2e42abef140799dedf58a27e2b1c8.png)


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oxwWpHJI-1671884043149)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219154458700.png)]](https://img-blog.csdnimg.cn/225ad455fa864ec386f57c8389a002cc.png)


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v47Ivlfp-1671884043150)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219154614244.png)]](https://img-blog.csdnimg.cn/702f879f7c5049708fa746d63749e6c4.png)


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-joMgoMwp-1671884043150)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219154934029.png)]](https://img-blog.csdnimg.cn/a199c2befd25492aa9dbe4e97f55e30a.png)


#### 9.3.vue 项目的运行流程


​ 在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。


其中:


1. App.vue 用来编写待渲染的模板结构
2. index.html 中需要预留一个 el 区域
3. main.js 把 App.vue 渲染到了 index.html 所预留的区域中


#### 9.4.vue 项目中 src 目录的构成



assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源
components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下
main.js 是项目的入口文件。整个项目的运行,要先执行 main.js
App.vue 是项目的根组件。


### 10.vue 组件


#### 10.1.什么是组件化开发


组件化开发指的是:根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护。


#### 10.2.vue 中的组件化开发


vue 是一个支持组件化开发的前端框架。


vue 中规定:组件的后缀名是 .vue。之前接触到的 App.vue 文件本质上就是一个 vue 的组件。


#### 10.3.vue 组件的三个组成部分


每个 .vue 组件都由 3 部分构成,分别是:


1. template -> 组件的模板结构
2. script -> 组件的 JavaScript 行为
3. style -> 组件的样式


其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分。 **组件的三个组成部分**


##### 10.3.1.template


vue 规定:每个组件对应的模板结构,需要定义到 节点中。


`注意:`


1. template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素
2. template 中只能包含唯一的根节点


##### 10.3.2.script


vue 规定:开发者可以在 



> 
> .vue 组件中的 data 必须是函数
> 
> 
> 


vue 规定:.vue 组件中的 data 必须是一个函数,不能直接指向一个数据对象。


##### 10.3.3.style


vue 规定:组件内的 



> 
> 让 style 中支持 less 语法
> 
> 
> 


在 


代码示例:



这是用户自定义的 Test.vue --- {{ username }}


#### 10.4.组件之间的父子关系


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3KZy5tH-1671884043150)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219173217217.png)]](https://img-blog.csdnimg.cn/55845cf1ac4543548a9aac061d37b6ca.png)


`组件在被封装好之后,彼此之间是相互独立的,不存在父子关系` 


`在使用组件的时候,根据彼此的嵌套关系,形成了父子关系、兄弟关系`


##### 10.4.1.使用组件的三个步骤


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tAQJdoNK-1671884043151)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219173657680.png)]](https://img-blog.csdnimg.cn/f121d3600f8848a285ffadaea6156f76.png)


代码示例:



App 根组件


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <!-- 以标签的形式使用注册好的组件 -->
  <Left></Left>
  <Right></Right>
</div>

具体代码查看 day4/code/demo-1 文件



> 
> 在VScode中配置@路径提示的插件
> 
> 
> 


##### 10.4.2.通过 components 注册的是私有子组件


例如:


在组件 A 的 components 节点下,注册了组件 F。


则组件 F 只能用在组件 A 中;不能被用在组件 C 中。


##### 10.4.3.注册全局组件


在 vue 项目的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件。


代码示例:



// 导入需要全局注册的组件
import Count from ‘@/components/Count.vue’

// 参数1:字符串格式,表示组件的 注册名称
// 参数2:需要被全局注册的那个组件
Vue.component(‘MyCount’, Count)


#### 10.5.组件的 props


props 是组件的自定义属性,在封装通用组件的时候,合理地使用 props 可以极大的提高组件的复用性!


可以用于存放从其他组件传递过来的数据


##### 10.5.1.props 是只读的


​ vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props 的值。否则会直接报错:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zuMB3ht4-1671884043151)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219200846462.png)]](https://img-blog.csdnimg.cn/41562cf9543948c88232dea01bd49eb9.png)


要想修改 props 的值,可以把 props 的值转存到 data 中,因为 data 中的数据都是可读可写的!


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-110njx4Q-1671884043151)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219200854222.png)]](https://img-blog.csdnimg.cn/e6fc938949a64735b9c9540b0135e3f1.png)


##### 10.5.2.props 的 default 默认值


在声明自定义属性时,可以通过 default 来定义属性的默认值。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u52aTUkT-1671884043151)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219200924472.png)]](https://img-blog.csdnimg.cn/0da0bf06d55548cbb87e81bbaaa354d4.png)


##### 10.5.3.props 的 type 值类型


在声明自定义属性时,可以通过 type 来定义属性的值类型。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jOcOcfnO-1671884043152)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219200952077.png)]](https://img-blog.csdnimg.cn/0f076871a25b46c188de6e216927cc68.png)


##### 10.5.4.props 的 required 必填项


​ 在声明自定义属性时,可以通过 required 选项,将属性设置为必填项,强制用户必须传递属性的值。示例代


码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XZZWX3o2-1671884043152)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219201020541.png)]](https://img-blog.csdnimg.cn/88a2926af514420192ab8a196734ff47.png)


代码示例:



Count 组件

count 的值是:{{ count }}


#### 10.6.组件之间的样式冲突问题


​ 默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。


导致组件之间样式冲突的根本原因是:


1. 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的
2. 每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素


##### 10.6.1.解决组件样式冲突的问题


为每个组件分配唯一的自定义属性,在编写组件样式时,通过属性选择器来控制样式的作用域,示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5RWVKxiD-1671884043152)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219231928868.png)]](https://img-blog.csdnimg.cn/ff3401f0a18a4f89938a6effe8c1f3f1.png)


##### 10.6.2.style 节点的 scoped 属性


为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped 属性,从而防止组件之间的样式冲突问题:




##### 10.6.3./deep/ 样式穿透


​ 如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样


式对子组件生效,可以使用 /deep/ 深度选择器。


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Two5yoK-1671884043153)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221219232507746.png)]](https://img-blog.csdnimg.cn/ead7ebaf24414345a37d952d994a05cc.png)


代码示例:




### 11.组件的生命周期


#### 11.1.生命周期 & 生命周期函数


​ 生命周期(Life Cycle)是指一个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段。


生命周期函数:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行。


注意:生命周期强调的是时间段,生命周期函数强调的是时间点。


#### 11.2.组件生命周期函数的分类


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhKEamkX-1671884043153)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221220212013958.png)]](https://img-blog.csdnimg.cn/550dc352e60a43cf96300c45f9493f27.png)


#### 11.3.生命周期图示


可以参考 vue 官方文档给出的“生命周期图示”,进一步理解组件生命周期执行的过程:


https://cn.vuejs.org/v2/guide/instance.html#生命周期图示


代码示例:



Test.vue 组件 --- {{ users.length }} 个用户

    <p id="ppp">message 的值是: {{ message }}</p>
    <button @click="message += '~'">修改 message 的值</button>
</div>

### 12.组件之间的数据共享


#### 12.1.组件之间的关系


在项目开发中,组件之间的最常见的关系分为如下两种:


1. 父子关系
2. 兄弟关系


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MkJ6vABP-1671884043153)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221220221145129.png)]](https://img-blog.csdnimg.cn/c5332db62a1f4821912f77cfc8923f5e.png)


#### 12.2.父子组件之间的数据共享


父子组件之间的数据共享又分为:


1. 父 -> 子共享数据
2. 子 -> 父共享数据


##### 12.2.1.父组件向子组件共享数据


父组件向子组件共享数据需要使用自定义属性。示例代码如下:


父组件:App.vue



App 根组件


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <Left :msg="message" :user="userinfo"></Left>

</div>

子组件:Left.vue



Left 组件

msg 的值是:{{ msg }}

user 的值是:{{ user }}


##### 12.2.2.子组件向父组件共享数据


子组件向父组件共享数据使用自定义事件。示例代码如下:


子组件:Right.vue



Right 组件 --- {{ count }}


父组件:App.vue



App 根组件 --- {{ countFromSon }}


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <Right @numchange="getNewCount"></Right>
</div>

##### 12.2.3.兄弟组件之间的数据共享


在 vue2.x 中,兄弟组件之间数据共享的方案是 EventBus。


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FjZa6vJZ-1671884043153)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221220221322704.png)]](https://img-blog.csdnimg.cn/b69350ceb79b4647a55e914cb4847619.png)


###### 12.2.1.1.EventBus 的使用步骤


1. 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象
2. 在数据发送方,调用 bus.$emit(‘事件名称’, 要发送的数据) 方法触发自定义事件
3. 在数据接收方,调用 bus.$on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件


代码示例:


Left.vue



Left 组件


eventBus.js



import Vue from ‘vue’

export default new Vue()


Right.vue



Right 组件

{{ msgFromLeft }}


### 13.ref 引用


#### 13.1.什么是 ref 引用


ref 用来辅助开发者在不依赖于 jQuery 的情况下,获取 DOM 元素或组件的引用。


每个 vue 的组件实例上,都包含一个 $refs 对象,里面存储着对应的 DOM 元素或组件的引用。默认情况下,


组件的 $refs 指向一个空对象。


#### 13.2.使用 ref 引用 DOM 元素


如果想要使用 ref 引用页面上的 DOM 元素,则可以按照如下的方式进行操作:


代码示例:



App 根组件


#### 13.3.使用 ref 引用组件实例


如果想要使用 ref 引用页面上的组件实例,则可以按照如下的方式进行操作:


代码示例:


Left.vue



Left 组件 --- {{ count }}

<button @click="count += 1">+1</button>
<button @click="resetCount">重置</button>

App.vue



App 根组件

<button @click="onReset">重置 Left 的 count 值为 0</button>
<hr />

<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <!-- 使用 ref 拿到 Left.vue 组件的实例对象,依次来操作 Left.vue 组件里边的内容 -->
  <Left ref="comLeft"></Left>
</div>

#### 13.4.控制文本框和按钮的按需切换


通过布尔值 inputVisible 来控制组件中的文本框与按钮的按需切换。


代码示例:



App 根组件

<hr />

<input type="text" v-if="inputVisible" @blur="showButton" />
<button v-else @click="showInput">展示输入框</button>

<hr>

<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
</div>

##### 13.4.1.this.$nextTick(cb) 方法


​ 组件的 $nextTick(cb) 方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行。通俗的理解是:等组件的


DOM 更新完成之后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素。


代码示例:



App 根组件

<hr />

<input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"/>
<button v-else @click="showInput">展示输入框</button>

<hr>

<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->

</div>

### 14.购物车案例


### 15.动态组件


#### 15.1.什么是动态组件


动态组件指的是动态切换组件的显示与隐藏。


#### 15.2.如何实现动态组件渲染


vue 提供了一个内置的 组件,专门用来实现动态组件的渲染。


代码示例:



App 根组件


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <!-- 1.component 标签是 vue 内置的,作用:组件的占位符 -->
  <!-- 2.is 属性的值表示要渲染的组件的名字 -->
  <component :is="comName"></component>
</div>

#### 15.3.动态切换组件的展示与隐藏


代码示例:



App 根组件


<button @click="comName='Left'">展示 Left</button>
<button @click="comName='Right'">展示 Right</button>


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <!-- 1.component 标签是 vue 内置的,作用:组件的占位符 -->
  <!-- 2.is 属性的值表示要渲染的组件的名字 -->
  <component :is="comName"></component>
</div>

#### 15.4.keep-alive


##### 15.4.1.使用 keep-alive 保持状态


​ 默认情况下,切换动态组件时无法保持组件的状态。此时可以使用 vue 内置的 组件保持动态组


件的状态。


代码示例:



App 根组件


<button @click="comName = 'Left'">展示 Left</button>
<button @click="comName = 'Right'">展示 Right</button>


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <!-- 1.component 标签是 vue 内置的,作用:组件的占位符 -->
  <!-- 2.is 属性的值表示要渲染的组件的名字 -->

  <!-- keep-alive 可以把内部的组件进行缓存,而不是销毁组件 -->
  <keep-alive>
    <component :is="comName"></component>
  </keep-alive>
</div>

##### 15.4.2.keep-alive 对应的生命周期函数


当组件被缓存时,会自动触发组件的 deactivated 生命周期函数。


当组件被激活时,会自动触发组件的 activated 生命周期函数。


代码示例:



Left 组件 --- {{ count }}


##### 15.4.3.keep-alive 的 include 和 exclude 属性


include 属性用来指定:只有名称匹配的组件会被缓存。多个组件名之间使用英文的逗号分隔


exclude 属性用来指定:名称匹配的组件不会被缓存。多个组件名之间使用英文的逗号分隔


`注意:include 和 exclude 不能同时使用`


代码示例:



App 根组件


<button @click="comName = 'Left'">展示 Left</button>
<button @click="comName = 'Right'">展示 Right</button>


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <!-- 1.component 标签是 vue 内置的,作用:组件的占位符 -->
  <!-- 2.is 属性的值表示要渲染的组件的名字 -->

  <!-- keep-alive 可以把内部的组件进行缓存,而不是销毁组件 -->
  <!-- include 表示只缓存字符串的组件 多个组件用英文逗号分隔 -->
  <!-- exclude 排除项, 注意 include 和 exclude 不能同时使用 -->
  <keep-alive include="Left">
    <component :is="comName"></component>
  </keep-alive>
</div>

#### 15.5.了解组件注册名称和组件声明时name的区别


代码示例:


Right.vue



Right 组件


App.vue



App 根组件


<button @click="comName = 'Left'">展示 Left</button>
<button @click="comName = 'Right'">展示 Right</button>


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <!-- 1.component 标签是 vue 内置的,作用:组件的占位符 -->
  <!-- 2.is 属性的值表示要渲染的组件的名字 -->

  <!-- keep-alive 可以把内部的组件进行缓存,而不是销毁组件 -->
  <!-- include 表示只缓存字符串的组件 多个组件用英文逗号分隔 -->
  <!-- exclude 排除项, 注意 include 和 exclude 不能同时使用 -->
  <keep-alive exclude="MyRight">
    <component :is="comName"></component>
  </keep-alive>
</div>

### 16.插槽


#### 16.1.什么是插槽


​ 插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的


部分定义为插槽。


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XkJF6gjn-1671884043154)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221222162515056.png)]](https://img-blog.csdnimg.cn/b7228099a0e54a46ab72cea81e69016d.png)


​ 可以把插槽认为是组件封装期间,为用户预留的内容的占位符。


#### 16.2.体验插槽的基础用法


在封装组件时,可以通过 元素定义插槽,从而为用户预留内容占位符。


代码示例:


App.vue



App 根组件


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <Left>
    <p>这个在 Left 组件的内容区域声明的 p 标签</p>
  </Left>
</div>

Left.vue



Left 组件

<hr>

<!-- 声明一个插槽区域 -->
<slot></slot>

**没有预留插槽的内容会被丢弃**


如果在封装组件时没有预留任何 插槽,则用户提供的任何自定义内容都会被丢弃。


#### 16.3.v-slot


代码示例:


Left.vue



Left 组件

<hr>

<!-- 声明一个插槽区域 -->
<!-- vue 官方规定:每一个插槽都要有一个 name 名称 -->
<!-- 如果省略 slot 的 name 属性,则有个默认名称为 default -->
<slot name="defualt"></slot>

App.vue



App 根组件


<div class="box">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <Left>
    <!-- 默认的情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽之中 -->
    <!-- 1.如果要把内容填充到指定名称的插槽中,需要使用 v-slot:名称 这个指定-->
    <!-- 2.v-slot: 后面要跟上插槽的名称 -->
    <!-- 3.v-slot: 指定不能直接用在元素身上,必须用到 template 标签-->
    <!-- 4.template 这个标签,它是一个虚拟的标签,只起到包裹性质的作用,不会被渲染为任何实质性的 html 元素 -->
    <!-- 5.v-slot:指定的简写形式是 # -->
    <template #defualt>
      <p>这个在 Left 组件的内容区域声明的 p 标签</p>
    </template>
  </Left>
</div>

#### 16.4.后备内容


​ 封装组件时,可以为预留的 插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何


内容,则后备内容会生效。


代码示例:


Left.vue



Left 组件

<hr>

<!-- 声明一个插槽区域 -->
<!-- vue 官方规定:每一个插槽都要有一个 name 名称 -->
<!-- 如果省略 slot 的 name 属性,则有个默认名称为 default -->
<!-- 如果这个插槽被使用,则不会显示插槽中的文字 -->
<slot name="defualt">这是 default 插槽的默认内容</slot>

#### 16.5.具名插槽


​ 如果在封装组件时需要预留多个插槽节点,则需要为每个 插槽指定具体的 name 名称。这种带有具体


名称的插槽叫做“具名插槽”。


代码示例:


Article.vue



    <!-- 文章的标题 -->
    <div class="header-box">
        <slot name="title"></slot>
    </div>

    <!-- 文章的内容 -->
    <div class="content-box">
        <slot name="content"></slot>
    </div>

    <!-- 文章的作者 -->
    <div class="footer-box">
        <slot name="author"></slot>
    </div>


</div>

App.vue



App 根组件


  <Article>
      
    <template #title>
      <h2>震惊!...</h2>
    </template>

    <template #content>
      <div>
        <p>某高校一男子...</p>
        <p>荣获...</p>
        <p>牛逼...</p>
      </div>
    </template>

    <template #author>
      <div>作者:彬锅果</div>
    </template>

  </Article>

#### 16.6.为具名插槽提供内容


​ 在向具名插槽提供内容的时候,我们可以在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的


形式提供其名称。


代码示例:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OYrexqjC-1671884043154)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221222171417004.png)]](https://img-blog.csdnimg.cn/c9dafce0526e434192fe4fc0771cf75d.png)


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ncd1z68w-1671884043155)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221222171426579.png)]](https://img-blog.csdnimg.cn/34957d5270a343b79e75af628b1eb6e4.png)


#### 16.7.作用域插槽的解构赋值


代码示例:


Article.vue



    <!-- 文章的标题 -->
    <div class="header-box">
        <slot name="title"></slot>
    </div>

    <!-- 文章的内容 -->
    <div class="content-box">
        <!-- 在封装组件时,为预留的 <slot> 提供属性对应的值,
            这种用法叫做 作用域插槽 -->
        <slot name="content" msg="Hello Article.vue" :user="userinfo"></slot>
    </div>

    <!-- 文章的作者 -->
    <div class="footer-box">
        <slot name="author"></slot>
    </div>


</div>

App.vue



App 根组件


<Article>
  <template #title>
    <h2>震惊!...</h2>
  </template>

  <template #content="{ msg, user }">
    <div>
      <p>某高校一男子...</p>
      <p>荣获...</p>
      <p>牛逼...</p>
      <p>{{ msg }}</p>

      <p>{{ user.name }}</p>
      <p>{{ user.age }}</p>
    </div>
  </template>

  <template #author>
    <div>作者:彬锅果</div>
  </template>

</Article>

<div class="box" style="display:none;">
  <!-- 渲染 Left 组件和 Right 组件 -->
  <Left>
    <!-- 默认的情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽之中 -->
    <!-- 1.如果要把内容填充到指定名称的插槽中,需要使用 v-slot:名称 这个指定-->
    <!-- 2.v-slot: 后面要跟上插槽的名称 -->
    <!-- 3.v-slot: 指定不能直接用在元素身上,必须用到 template 标签-->
    <!-- 4.template 这个标签,它是一个虚拟的标签,只起到包裹性质的作用,不会被渲染为任何实质性的 html 元素 -->
    <!-- 5.v-slot:指定的简写形式是 # -->
    <template #defualt>
      <p>这个在 Left 组件的内容区域声明的 p 标签</p>
    </template>
  </Left>
</div>

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LMSGiWhZ-1671884043155)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221222171934551.png)]](https://img-blog.csdnimg.cn/87fec9bf89dc4a7ebad32adeb7a31330.png)


### 17.自定义指令


#### 17.1.什么是自定义指令


vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令。除此之外 vue 还允许开发者自定义指令。


#### 17.2.自定义指令的分类


vue 中的自定义指令分为两类,分别是:


私有自定义指令


全局自定义指令


##### 17.2.1.私有自定义指令


在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令。


代码示例:



App 根组件



###### 17.2.1.1.通过 binding 获取指令的参数值


在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值


代码示例:



App 根组件

测试



###### 17.2.1.2.update 函数


​ bind 函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更新时 bind 函数不会被触发。 update 函


数会在每次 DOM 更新时被调用。


代码示例:



App 根组件

测试

<button @click="color='green'">改变 color 的颜色值</button>
<hr />

###### 17.2.1.3.函数简写


如果 bind 和update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-thKYm7Be-1671884043155)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221222204725907.png)]](https://img-blog.csdnimg.cn/9967360c5e44410585a25b661ce932e9.png)


##### 17.2.2.全局自定义指令


全局共享的自定义指令需要通过“Vue.directive()”进行声明


代码示例:


main.js



import Vue from ‘vue’
import App from ‘./App.vue’

Vue.config.productionTip = false

// 全局自定义指令
/* Vue.directive(‘color’, {
bind(el, binding) {
el.style.color = binding.value
},

update(el, binding) {
el.style.color = binding.value
}
}) */

Vue.directive(‘color’, function (el, binding) {
el.style.color = binding.value
})

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


Article.vue



    <h3 v-color="'red'">Article 组件</h3>

    <!-- 文章的标题 -->
    <div class="header-box">
        <slot name="title"></slot>
    </div>

    <!-- 文章的内容 -->
    <div class="content-box">
        <!-- 在封装组件时,为预留的 <slot> 提供属性对应的值,
            这种用法叫做 作用域插槽 -->
        <slot name="content" msg="Hello Article.vue" :user="userinfo"></slot>
    </div>

    <!-- 文章的作者 -->
    <div class="footer-box">
        <slot name="author"></slot>
    </div>


</div>

### 18.路由


#### 18.1.前端路由的概念与原理


##### 18.1.1.什么是路由


路由(英文:router)就是对应关系。


##### 18.1.2.SPA 与前端路由


​ SPA 指的是一个 web 网站只有唯一的一个 HTML 页面,所有组件的展示与切换都在这唯一的一个页面内完成。


此时,不同组件之间的切换需要通过前端路由来实现。


结论:在 SPA 项目中,不同功能之间的切换,要依赖于前端路由来完成!


##### 18.1.3.什么是前端路由


通俗易懂的概念:Hash 地址与组件之间的对应关系。


##### 18.1.4.前端路由的工作方式


1. 用户点击了页面上的路由链接
2. 导致了 URL 地址栏中的 Hash 值发生了变化
3. 前端路由监听了到 Hash 地址的变化
4. 前端路由把当前 Hash 地址对应的组件渲染都浏览器中


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lu7I60Dw-1671884043155)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223161106984.png)]](https://img-blog.csdnimg.cn/e81b80c67dee4602a366d5a1109b7833.png)


`结论:前端路由,指的是 Hash 地址与组件之间的对应关系!`


##### 18.1.4.实现简易的前端路由


步骤1:通过 标签,结合 comName 动态渲染组件。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IqzJ4wif-1671884043156)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223162440530.png)]](https://img-blog.csdnimg.cn/569434011228414c86e26a4cd46d814f.png)


步骤2:在 App.vue 组件中,为 链接添加对应的 hash 值:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YZzSeGC0-1671884043156)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223162500684.png)]](https://img-blog.csdnimg.cn/3d4c22dd63fc464095cfcb31f1522d56.png)


步骤3:在 created 生命周期函数中,监听浏览器地址栏中 hash 地址的变化,动态切换要展示的组件的名称:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x5d7Jg50-1671884043156)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223162512808.png)]](https://img-blog.csdnimg.cn/74d6a6e0781d45daa7051f076ac46adb.png)


#### 18.2.vue-router 的基本使用


##### 18.2.1.什么是 vue-router


​ vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目


中组件的切换。


vue-router 的官方文档地址:https://router.vuejs.org/zh/


##### 18.2.2.vue-router 安装和配置的步骤


1. 安装 vue-router 包
2. 创建路由模块
3. 导入并挂载路由模块
4. 声明路由链接和占位符


###### 18.2.2.1. 在项目中安装 vue-router


在 vue2 的项目中,安装 vue-router 的命令如下:



npm install vue-router@3.5.2 -S


###### 18.2.2.2.创建路由模块


在 src 源代码目录下,新建 router/index.js 路由模块,并初始化如下的代码:



// src/router/index.js 就是当前项目的路由模块

// 1.导入 Vue 和 VueRouter 的包
import Vue from ‘vue’
import VueRouter from ‘vue-router’

// 2.调用 Vue.use() 函数,把 VueRouter 安装为 Vue 项目的插件
// Vue.use() 用来为 vue项目安装插件
Vue.use(VueRouter)

// 3.创建路由的实例对象
const router = new VueRouter()

// 4.向外共享路由实例对象
// 只要在外使用 import 导入该路由模块就可以拿到此路由实例对象
export default router


###### 18.2.2.3.导入并挂载路由模块


在 src/main.js 入口文件中,导入并挂载路由模块。示例代码如下:



import Vue from ‘vue’
import App from ‘./App.vue’

// 导入路由模块,目的:拿到路由的实例对象
// 在进行模块化导入的时候,如果给定的是文件夹,则默认导入这个文件夹下 名字叫做 index.js 的文件
import router from “@/router/index.js”

// 导入 bootstrap 样式
import ‘bootstrap/dist/css/bootstrap.min.css’
// 全局样式
import ‘@/assets/global.css’

Vue.config.productionTip = false

new Vue({
render: h => h(App),
// 在 vue 项目中,要想把路由用起来,必须把路由实例对象,通过下面的方式进行挂载
// router: 路由的实例对象
// 属性值和属性名一致,可简写
// router: router
router
}).$mount(‘#app’)


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTrrrSc9-1671884043156)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223164249752.png)]](https://img-blog.csdnimg.cn/6b3ad8588a9242688eef05cc7f3d388c.png)


###### 18.2.2.4.声明路由链接和占位符


​ 在 src/App.vue 组件中,使用 vue-router 提供的 和 声明路由链接和占位符:



> 
> 未使用路由链接:
> 
> 
> 


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2qYqFNWP-1671884043157)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223165917018.png)]](https://img-blog.csdnimg.cn/82b1f0c87e7d494c867ee9e2c23f5681.png)



App2 组件

<a href="#/home">首页</a>
<a href="#/movie">电影</a>
<a href="#/about">关于</a>
<hr/>

<!-- 只要在项目中安装和配置了 vue-router,就可以使用 router-view 这个组件了 -->
<!-- 它的作用:占位符 -->
<!-- 接着就到 src/route/index.js 中定义 "hash地址" 与 "组件" 之间的对应关系 -->
<router-view></router-view>


> 
> 使用路由链接
> 
> 
> 



App2 组件

<!-- 当安装了配置了 vue-router 后,就可以使用 router-link 来代替普通的 a 链接了 -->

<router-link to="/home">首页</router-link>
<router-link to="/movie">电影</router-link>
<router-link to="/about">关于</router-link>
<hr/>

<!-- 只要在项目中安装和配置了 vue-router,就可以使用 router-view 这个组件了 -->
<!-- 它的作用:占位符 -->
<!-- 接着就到 src/route/index.js 中定义 "hash地址" 与 "组件" 之间的对应关系 -->
<router-view></router-view>

###### 18.2.2.5.声明路由的匹配规则


在 src/router/index.js 路由模块中,通过 routes 数组声明路由的匹配规则。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rBxEfT5r-1671884043157)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223165819581.png)]](https://img-blog.csdnimg.cn/b242108fb1af48cd9bb18986a3169e08.png)



// src/router/index.js 就是当前项目的路由模块

// 1.导入 Vue 和 VueRouter 的包
import Vue from ‘vue’
import VueRouter from ‘vue-router’

// 导入需要的组件
import Home from ‘@/components/Home.vue’
import Movie from ‘@/components/Movie.vue’
import About from ‘@/components/About.vue’

// 2.调用 Vue.use() 函数,把 VueRouter 安装为 Vue 项目的插件
// Vue.use() 用来为 vue项目安装插件
Vue.use(VueRouter)

// 3.创建路由的实例对象
const router = new VueRouter({
// routes 是一个数组,作用:定义 “hash地址” 与 “组件” 之间的对应关系
routes: [{
path: ‘/home’,
component: Home
},
{
path: ‘/movie’,
component: Movie
},
{
path: ‘/about’,
component: About
},
]
})

// 4.向外共享路由实例对象
// 只要在外使用 import 导入该路由模块就可以拿到此路由实例对象
export default router


###### 18.2.2.6.路由重定向 redirect


​ 路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。


通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向:



const router = new VueRouter({
// routes 是一个数组,作用:定义 “hash地址” 与 “组件” 之间的对应关系
routes: [

// redirect 路由重定向,当用户访问 / 的时候,通过 redirect 属性跳转到 /home 对应的路由规则
{
  path: '/',
  redirect: '/home'
},
// 路由规则
{
  path: '/home',
  component: Home
},
{
  path: '/movie',
  component: Movie
},
{
  path: '/about',
  component: About
},

]
})


#### 18.3.vue-router 的常见用法


##### 18.3.1.嵌套路由


通过路由实现组件的嵌套展示,叫做嵌套路由。


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MwaZ6t3A-1671884043157)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223172127377.png)]](https://img-blog.csdnimg.cn/227e74456fc447a78762c4a2de54729e.png)


###### 18.3.1.1.声明子路由链接和子路由占位符


在 About.vue 组件中,声明 tab1 和 tab2 的子路由链接以及子路由占位符。示例代码如下:



About 组件

<!-- 子级路由链接 -->
<router-link to="/about/tab1">tab1</router-link>
<router-link to="/about/tab2">tab2</router-link>


<hr>
<!-- 子级路由占位符 -->
<router-view></router-view>

###### 18.3.1.2.通过 children 属性声明子路由规则


在 src/router/index.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CdwiUgi4-1671884043157)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223172626229.png)]](https://img-blog.csdnimg.cn/0ef913b9096449679abd7a8777a51a90.png)


###### 18.3.1.3.默认子路由



> 
> 使用 redict 方式
> 
> 
> 


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-choigdMk-1671884043157)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223172846308.png)]](https://img-blog.csdnimg.cn/c7a669cd654b48febf9ea12683654b8d.png)



> 
> 使用默认子路由
> 
> 
> 


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-27mkrEAR-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223173244031.png)]](https://img-blog.csdnimg.cn/141cdfd5b6a1443cbe9746eb31d9f227.png)


##### 18.3.2.动态路由


###### 18.3.2.1. 动态路由匹配


思考:有如下 3 个路由链接:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxHlsnQc-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223174529588.png)]](https://img-blog.csdnimg.cn/d46f4e468cc245188b08f022f910ef66.png)


定义如下 3 个路由规则,是否可行?


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UxuPZrKJ-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223174544043.png)]](https://img-blog.csdnimg.cn/afca7b8432eb4af6b4c8d9606c0ac5d6.png)


缺点:路由规则的复用性差。


###### 18.3.2.2.动态路由的概念


​ 动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。


在 vue-router 中使用英文的冒号(**:**)来定义路由的参数项。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02wF6n69-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223174620622.png)]](https://img-blog.csdnimg.cn/ffbf0ad02d804415b8f3e1e50dfcc5bb.png)


###### 18.3.2.3.$route.params 参数对象


在动态路由渲染出来的组件中,可以使用 this.$route.params 对象访问到动态匹配的参数值。



Movie 组件 --- {{ this.$route.params.id }}

<button @click="showThis">打印 this</button>

###### 18.3.2.4.使用 props 接收路由参数


为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJfGfES6-1671884043159)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223175148782.png)]](https://img-blog.csdnimg.cn/4c08cf68ff664f9ca793491937fffc04.png)


##### 18.3.3.声明式导航 & 编程式导航


在浏览器中,点击链接实现导航的方式,叫做声明式导航。例如:


* 普通网页中点击 链接、vue 项目中点击 都属于声明式导航


在浏览器中,调用 API 方法实现导航的方式,叫做编程式导航。例如:


* 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航


###### 18.3.3.1.vue-router 中的编程式导航 API


vue-router 提供了许多编程式导航的 API,其中最常用的导航 API 分别是:


* this.$router.push(‘hash 地址’)


	+ 跳转到指定 hash 地址,并增加一条历史记录
* this.$router.replace(‘hash 地址’)


	+ 跳转到指定的 hash 地址,并替换掉当前的历史记录
* this.$router.go(数值 n)


	+ 实现导航历史前进、后退
> 
> $router.push
> 
> 
> 

 调用 this.$router.push() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cv945lCD-1671884043159)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223202746823.png)]](https://img-blog.csdnimg.cn/7e89d3530a3c42c68c72190d7392ee22.png)



> 
> $router.replace
> 
> 
> 


调用 this.$router.replace() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。


push 和 replace 的区别:


1. push 会增加一条历史记录
2. replace 不会增加历史记录,而是替换掉当前的历史记录



> 
> $router.go
> 


### 总结

为了帮助大家更好温习重点知识、更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。



包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

![](https://img-blog.csdnimg.cn/img_convert/d74f8b42f4a63c76b18efc6a818147df.png)

![](https://img-blog.csdnimg.cn/img_convert/6deb905d9655a3f0f54b8920686e1970.png)

**前端面试题汇总**

![](https://img-blog.csdnimg.cn/img_convert/42728594459506983a38ca2b86545fc6.png)

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

**JavaScript**

![](https://img-blog.csdnimg.cn/img_convert/7796de226b373d068d8f5bef31e668ce.png)

**性能**

![](https://img-blog.csdnimg.cn/img_convert/d7f6750332c78eb27cc606540cdce3b4.png)



**linux**

![](https://img-blog.csdnimg.cn/img_convert/ed368cc25284edda453a4c6cb49916ef.png)



将图片保存下来直接上传(img-27mkrEAR-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223173244031.png)]](https://img-blog.csdnimg.cn/141cdfd5b6a1443cbe9746eb31d9f227.png)


##### 18.3.2.动态路由


###### 18.3.2.1. 动态路由匹配


思考:有如下 3 个路由链接:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxHlsnQc-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223174529588.png)]](https://img-blog.csdnimg.cn/d46f4e468cc245188b08f022f910ef66.png)


定义如下 3 个路由规则,是否可行?


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UxuPZrKJ-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223174544043.png)]](https://img-blog.csdnimg.cn/afca7b8432eb4af6b4c8d9606c0ac5d6.png)


缺点:路由规则的复用性差。


###### 18.3.2.2.动态路由的概念


​ 动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。


在 vue-router 中使用英文的冒号(**:**)来定义路由的参数项。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02wF6n69-1671884043158)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223174620622.png)]](https://img-blog.csdnimg.cn/ffbf0ad02d804415b8f3e1e50dfcc5bb.png)


###### 18.3.2.3.$route.params 参数对象


在动态路由渲染出来的组件中,可以使用 this.$route.params 对象访问到动态匹配的参数值。



Movie 组件 --- {{ this.$route.params.id }}

<button @click="showThis">打印 this</button>

###### 18.3.2.4.使用 props 接收路由参数


为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJfGfES6-1671884043159)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223175148782.png)]](https://img-blog.csdnimg.cn/4c08cf68ff664f9ca793491937fffc04.png)


##### 18.3.3.声明式导航 & 编程式导航


在浏览器中,点击链接实现导航的方式,叫做声明式导航。例如:


* 普通网页中点击 链接、vue 项目中点击 都属于声明式导航


在浏览器中,调用 API 方法实现导航的方式,叫做编程式导航。例如:


* 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航


###### 18.3.3.1.vue-router 中的编程式导航 API


vue-router 提供了许多编程式导航的 API,其中最常用的导航 API 分别是:


* this.$router.push(‘hash 地址’)


	+ 跳转到指定 hash 地址,并增加一条历史记录
* this.$router.replace(‘hash 地址’)


	+ 跳转到指定的 hash 地址,并替换掉当前的历史记录
* this.$router.go(数值 n)


	+ 实现导航历史前进、后退
> 
> $router.push
> 
> 
> 

 调用 this.$router.push() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。示例代码如下:


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cv945lCD-1671884043159)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20221223202746823.png)]](https://img-blog.csdnimg.cn/7e89d3530a3c42c68c72190d7392ee22.png)



> 
> $router.replace
> 
> 
> 


调用 this.$router.replace() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。


push 和 replace 的区别:


1. push 会增加一条历史记录
2. replace 不会增加历史记录,而是替换掉当前的历史记录



> 
> $router.go
> 


### 总结

为了帮助大家更好温习重点知识、更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。



包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

![](https://img-blog.csdnimg.cn/img_convert/d74f8b42f4a63c76b18efc6a818147df.png)

![](https://img-blog.csdnimg.cn/img_convert/6deb905d9655a3f0f54b8920686e1970.png)

**前端面试题汇总**

![](https://img-blog.csdnimg.cn/img_convert/42728594459506983a38ca2b86545fc6.png)

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

**JavaScript**

![](https://img-blog.csdnimg.cn/img_convert/7796de226b373d068d8f5bef31e668ce.png)

**性能**

![](https://img-blog.csdnimg.cn/img_convert/d7f6750332c78eb27cc606540cdce3b4.png)



**linux**

![](https://img-blog.csdnimg.cn/img_convert/ed368cc25284edda453a4c6cb49916ef.png)



  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值