Vue

前言

之前学的 Typescript 愣是给我整放弃了,根本学不动啊,因为工作上又用不到,而且前几天因为写组件卡了好几次,所以想要重新学习 Vue

我写的那个组件算是步骤组件,而且还有权限的校验,异步获取数据等问题,等我过完基础之后再来分析分析


VS Code

Chrome 调试 HTML 的配置

如果 在 VS code 编辑器写一段 html 后,想要用 Chrome 浏览器调试的话,需要 建立 VS codechrome 之间的联系,也就是做搭桥的工作

我平常爱用的是 open in browser ,在插件试场搜一下
在这里插入图片描述

安装完之后,在 html 项目下
在这里插入图片描述
这种是比较方便的,其他调试方式了解即可,调试部分以下的东西了解即可。

默认支持 node 环境的调试

在调试的时候会在 .vscode 文件夹下搜索一个叫 launch.json文件(没有的话自己动手建一个吧),VS code 根据这里的配置去弹出浏览器进行调试。

在这里插入图片描述
相应代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Edge",
"request": "launch",
"type": "pwa-msedge",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
},
{
"name": "Launch Chrome",
"type": "chrome",
"request": "launch",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}/wwwroot"
}
]
}

多浏览器配置,其实就是多写个对象

点击绿色的(跟播放按钮似的)调试按钮,会弹出浏览器,跳转到 url 指定的地址,刚开始应该是 about:blank 这个地址,得稍微等一会(如果你起了服务器的话,反应会很快)

起服务:
可以通过npm install -g http-server 安装全局的 http-server 这个依赖包,然后在你的项目下,终端输入http-server 启动 8080 端口的服务

在这里插入图片描述
说明:

webRoot 字段,说是在 F5 的时候会自动启动本地服务器,但是我配置了也没有用,其中 ${workspaceFolder} 这是个变量,代表以当前目录为根目录去启动服务器,比方说我的就是 DAILYPRACTICE

在这里插入图片描述

VSCode 对于 Vue 的插件

这里介绍两个

一个是 Vetur,这个会将 vue 语法颜色高亮
在这里插入图片描述
另一个是 Vue VSCode Snippets

在这里插入图片描述
这个就是输入简短的命令后,会快速帮我们构建 Vue 文件,例子如下所示

我输入 vbase 后敲击回车,即可帮我们快速搭建 vue 模板的基础

请添加图片描述

Hello Vue,思想

面试必会的好吧,公众号,各种辅导班里天天 bb 的东西

数据与视图之间的双向绑定

先来个 hello vue 代码
请添加图片描述

MVVM 框架就这玩意儿

在这里插入图片描述
MVVM 框架的三要素:响应式、模板引擎及其渲染 ,这里提出三个问题啊,来思考一下:

响应式:vue 如何监听数据变化?
模版:vue 的模版如何编写和解析?
渲染:vue 如何将模板转换为 html

实现这些, vue 做了很多工作,我暂且不展开了,(因为我也不是很会,因为不会,所以好奇啊 hh)

有的人可能会说啊:

响应式就是通过 Object.defineProperties(),以及观察者模式(面试背下来的吧)
模板的话应该是正则匹配
渲染的话就是用 render 渲染成虚拟 dom

我也是这样,面试背下来的,往深了说就凉凉,没啥不耻的,现在就慢慢学吧


模板引擎 以及 渲染函数

模板引擎的东西
这花括号叫做 **mustache**
再来看看渲染函数,我们写的一堆html最后 vue 会怎么处理呢?应该让 vue 变成一个函数了,我为啥这么说呢?来看一场珍贵无比的实验:

在这里插入图片描述
在这里插入图片描述

1
2
3
4
// console.log(app.$options.render); 的输出结果
ƒ anonymous() {
with(this){return _c('div',{attrs:{"id":"app"}},[_c('span',{staticStyle:{"font-size":"300px"}},[_v(_s(title))])])}
}

随后我们再把这么一坨代码写到 render 函数,并且注释掉原先写的 HTML 模板。
在这里插入图片描述

可以看到页面是一毛一样的,嗯嗯这个 render 函数有点东西啊,还是,先不深究,知道有这么个东西就行。
在这里插入图片描述

class 以及 style 属性绑定

还是举例子吧

例子描述:点击 li 列表,修改它的背景色,像如下动图这样

请添加图片描述

康康我怎么实现的,先来个绑定 class

在这里插入图片描述
再来个绑定 style

在这里插入图片描述
总结一下:

  • 绑定 class 的话,我们一般的思路就是:是否给这个元素类名?既然是是和否的关系,那就给他个布尔值呗,(当然实现的思路很多啊,你也可以写三目,无所谓,能实现就行)。
  • 绑定 style 的话,可以用三目来处理

计算属性以及监听器

本来想着把上边绑定 style 的例子改成这个,发现并不好改,因为有 item 这个东西,我觉得上面这个例子改成 methods 更好

二者的区别:

处理数据的场景不同

监听器适合一个数据影响多个数据,计算属性适合一个数据受多个数 据影响

计算属性有缓存性,计算所得的值如果没有变化不会重复执行

监听器选项提供了更通用的方法,适合执行异步操作或较大开销操作的情况


生命周期

直接撸代码吧,反正常用的就那几个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html>
<head>
<title>Vue源码剖析</title>
<script src="vue.js"></script>
</head>
<body>
<div id="demo">
<h1>初始化流程</h1>
<p>{{foo}}</p>
</div>
<script>
// 创建实例
const app = new Vue({
el: '#demo',
data: { foo: 'foo' },
beforeCreate() {
console.log('beforeCreate');
},
created() {
console.log('created ' + this.$el);
},
beforeMount() {
console.log('beforeMount');
},
mounted() {
setTimeout(() => {
this.foo = 'foooooo';
}, 2000);
console.log('mounted ' + this.$el);
},
beforeUpdate() {
console.log('beforeUpdate');
},
updated() {
console.log('updated');
},
});
</script>
</body>
</html>

结论:

三个阶段:初始化、更新、销毁

初始化会执行的生命周期钩子:beforeCreate、created、beforeMount、mounted

更新(指的是组件中的数值等发生变化了):beforeUpdate、updated

销毁:beforeDestroy、destroyed

使用场景总结:

1
2
3
4
5
6
7
8
beforeCreate() {}, // 执行时组件实例还未创建,通常用于插件开发中执行一些初始化任务
created() {}, // 组件初始化完毕,各种数据可以使用,常用于异步数据获取
beforeMounted() {}, // 未执行渲染、更新,dom未创建
mounted() {}, // 初始化结束,dom已创建,可用于获取访问数据和dom元素
beforeUpdate() {}, // 更新前,可用于获取更新前各种状态
updated() {}, // 更新后,所有状态已是最新
beforeDestroy() {}, // 销毁前,可用于一些定时器或订阅的取消
destroyed() {}, // 组件已销毁,作用同上

组件

给组件起名字,建议用羊肉串命名法,就像 e-button 一样,串起来

自定义组件上实现双向绑定

v-model 是个语法糖,它等价于 绑定一个数据,并派发 input 事件进行更新数据。

官方的解释,以及截图如下:
在这里插入图片描述

在这里插入图片描述

sync 修饰符

也是个语法糖,这就是让我们少敲代码而已

不过要知道原理更重要,他也是双向绑定的操作

在这里插入图片描述


插槽

插槽更像是一个占坑的,它可以给组件里传递内容

普通插槽

默认不写的话是有自动添加 v-slot:default 的东西

命名插槽

在这里插入图片描述

插槽作用域

在这里插入图片描述

插槽的传值

在这里插入图片描述


组件间的通信

中央事件总线 Bus

类似这样的过程啊
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// bus.js
class Bus {
constructor() {
this.callback = {};
}
$on(eventName, fn) {
// 监听,相当于添加事件
this.callback[eventName] = this.callback[eventName] || [];
this.callback[eventName].push(fn);
}
$emit(eventName, argu) {
// 发送事件,其实就是执行时间是吧
this.callback[eventName].forEach((item) => {
item(argu);
});
}
}

$parent & $root

$parent/$root 可以拿到父组件的东西,在子组件中使用

$children

在父组件中能够拿到子组件,是个数组,但不保证顺序,因为可能有动态组件

refs

类似根据 id 去拿到子组件,获取子节点引用

1
2
3
4
5
// parent
<HelloWorld ref="hw"/>
mounted() {
this.$refs.hw.xx = 'xxx'
}

provide & inject

能够实现祖先和后代之间传值,用关键字 provide 注射数据,用关键字 inject 注入
在这里插入图片描述

vuex

写到别的地方了:Vuex 统一状态管理:定义变量、获取变量、修改变量、以及较好的实践:模块化,映射方法、派生方法、严格模式、插槽。


总结

组件化是Vue的精髓,

定义: 组件是可复用的 Vue 实例,准确讲它们是VueComponent的实例,继承自Vue

优点: 增加代码的复用性、可维护性和可测试性。

建议:平常写组件的话,尽量写成函数式组件,意思就是,老爹来给组件参数,然后通知老爹修改数据。

组件的本质

vue 中的组件经历如下过程

组件配置 => VueComponent实例 => render() => Virtual DOM=> DOM

所以组件的本质是产生 虚拟 DOM


需要会的 API

数据相关

Vue.set()

这个是作用于响应式对象的

就是如果你在对象中新添加了属性,如果不处理的话页面是不会更新的。就像这样请添加图片描述
此时就可以用 vue 提供的 set 方法来实现修改完数据后更新视图。

1
2
3
// eg.
this.$set(this.num_array[0], "other", "我是其他");
Vue.set(this.num_array[0], "other", "我是其他");

请添加图片描述

Vue.delete()

上面是添加对象数据,这个就是删除了

1
Vue.delete(this.num_array[0], "value");

请添加图片描述

事件相关

首先要注意: vmvue 的一个实例,跟上面 add deletevue 已经不一样了

vm.$on

1
2
3
vm.$on("test", function (msg) {
console.log(msg);
});

vm.$emit

1
vm.$emit("test", "hi");

应用:事件总线

类似这样

请添加图片描述

页面截图如下:

在这里插入图片描述

vm.$once

这个就是只监听一次,触发之后就没用了,跟 on 的用法差不多,监听器就会被移除

1
2
3
vm.$on("test", function (msg) {
console.log(msg);
});

vm.$off

移除自定义事件监听器。

  • 如果没有提供参数,则移除所有的事件监听器;
  • 如果只提供了事件,则移除该事件所有的监听器;
  • 如果同时提供了事件与回调,则只移除这个回调的监听器。
1
2
3
vm.$off(); // 移除所有的事件监听器
vm.$off("test"); // 移除该事件所有的监听器 vm.$off('test', callback) // 只移除这个回调的监听器
vm.$off("test", callback); // 只移除这个回调的监听器

组件或元素引用

ref 和 vm.$refs

全名应该叫 reference参考

在这里插入图片描述

1
2
3
4
5
<!-- vm.$refs.p will be the DOM node -->
<p ref="p">hello</p>

<!-- vm.$refs.child will be the child component instance -->
<child-component ref="child"></child-component>

这里根据官方的例子,自己再写个栗子:

在这里插入图片描述

下面是传值操作的例子

在这里插入图片描述

注意:

  • ref 是作为渲染结果被创建的,在初始渲染时不能访问它们,也就是说,最早也是在 mounted 中能拿到
  • $refs 不是响应式的,不要试图用它在模板中做数据绑定
  • v-for 用于元素或组件时,引用信息将是包含 DOM 节点或组件实例的数组。在这里插入图片描述

写在最后

分页了,写在一章里内容有点长

还有啊

好兄弟们为啥只收藏不点赞啊,为啥啊!!

请添加图片描述