Vue 认知
什么是Vue,它是一套用于构建用户界面
的渐进式框架
。一句简单的介绍中,我们需要重点理解两个词 构建用户界面
和 渐进式框架
。它的特性体现在两个方面
- 数据驱动视图
使用 vue 的页面中,vue 会自动监听数据的变化,从而自行渲染页面的结构。在vue中,无需手动操作 DOM 节点,它会通过一些特殊的 HTML 语法,将 DOM 和数据绑定起来,一旦创建了绑定,DOM 将和数据保持同步,每当变更了数据,DOM 也会相应的更新
- 双向数据绑定
上面说到的数据驱动是 单向绑定
的,但 vue 也支持 双向绑定
的特性,当页面结构的数据发生的时候,可以在不操作 DOM 的条件下,自动把页面的信息同步到 vue 数据中。
MVVM 模型
上面说到两种 vue 的特性其核心原理便是 MVVM
- M:
M
odel ,表示当前页面渲染时做依赖的数据源
- V:
V
iew,表示当前页面所渲染的 DOM 结构
- VM:
V
iewM
odel,表示 vue 的实例,即 MVVM 的核心
通过上图我们解释下 MVVM 的工作原理,其中 viewModel
作为 MVVM 的核心,相当于一个连接的 桥梁
,两头连接的分别是 Model(数据源)
和 View(页面结构)
。其中 View 就是浏览器上可以看到的结构,Model 通常指的就是通过Api 调用获取的数据。
- 当数据源发生变化时候,会被 ViewModel 监听到,便会根据最新的数据源自动更新页面的结构
- 当页面元素的值发生变化的时候,也会被 ViewModel 监听到,便会把变化后的最新值同步到 Model 数据源中
这个是一个非常简单的 Vue 例子,但里面已经包含了 View - ViewModel - Model
三部分的结构
基本使用
Ⅰ、指令
我们先来认识一下什么是 指令
。指令是 vue 为开发者提供的模板语法
,用来辅助开发者渲染页面的基本结构
vue 中的指令按照不同的用途可以分为 6 大类,如下:
1)内容渲染指令
内容渲染指令,就是用来 渲染 DOM 元素中的文本内容
。
1、v-text
两个 h1
标签,一个有默认值,一个无默认值,我们都使用了 v-text
指令,来看结果
值得高兴的是,v-text
如我们所愿生效了,但是又有些许不对劲,第二个 h1
有自己的默认值,却被 v-text
指令替换了,而这也便成为了 v-text
缺点~!
v-text 指令会覆盖元素内默认的值
{{ }}
这个是 vue 提供的语法,专门用来解决 v-text
覆盖默认文本内容值的问题。这种 {{ }}
语法的专业名称叫做 插值表达式,下面来看使用方法:
我们可以通过简单的语法 {{ 值key }}
来获取数据源的值,不会干扰到标签中原有的值,因此 插值表达式 在我们日常开发中会更加常用一点。同时它还支持在指令中使用简单的 Java Script 语法:
但是如果数据源中的某个值,不是常规意义上的value,而是一段 html 片段,那么通过 {{}}
能否成功识别渲染呢?
很遗憾,插值表达式并没有帮我们渲染出 html 片段,那这个时候该如何处理?就需要用到我们接下来要说的指令了~!
v-html
该指令一看就知道是和 html 沾边的,由于 v-text
和 插值表达式
只能帮助我们渲染纯文本内容。如果要把包含 HTML 标签的字符串渲染为页面 HTML 元素,就需要用到这个v-html
指令
2)属性绑定指令
v-bind
如果需要为 元素的属性 动态绑定值,我们就需要用到 v-bind
属性绑定指令
由于 v-bind
在日常开发中使用的频率非常高,因此,vue 官方也提供了简写形式(英文符号的 :
)
同样在 v-bind
中也支持简单的 JS 语法
3)事件绑定指令
vue 中还提供了 v-on
事件绑定指令,用来为 DOM 阶段绑定事件监听,简单语法如下
我们在 data 中定义了数据源,在 methods 中定义了方法,通过 v-on
指令来绑定事件。整体结构清晰明了,当然处理 onclick 事件除外,我们还可以使用 oninput、onkeyup 等原生事件
同样由于 v-on
指令在开发中使用频率非常高,因此,vue 官方同样提供了简写形式 (@
)
我们在上面方法函数中出现了 e
这个参数,不知道细心的小伙伴有没有注意到~
在原生的 DOM 事件绑定中,可以在事件处理函数的形参处,接收事件参数对象
event,同样,在 v-on
指令所绑定的事件处理函数中,我们一样可以通过上述方式获取到 事件参数对象 event
这个时候如果调用函数没有形参还好,但是在存在形参的情况下我们又该如何解决?我们先试一试
可以发现这种方法不得行,我们的事件参数对象被覆盖了!那这就可以说到 vue 为我们提供的一个 特殊变量 $event
,该变量用来表示原生的事件参数对象 event。$event
可以解决事件参数对象 event 被覆盖的问题。
可以看出,该特殊变量已经解决了我们上述遇到的问题!
㈠ 事件修饰符
在 DOM 事件中,有一种经典的问题,那就是事件冒泡
,什么是事件冒泡
呢?
我们要解决这个问题也很简单,可以利用上面说到的事件对象阻止冒泡行为:
通过函数 stopPropagation()
便可以解决事件冒泡问题,但是 Vue 中提供了更加优雅的解决方案~
这种方式在 vue 中称之为 事件修饰符
,用来更加方便的对事件的触发进行控制,以下我们列举 5 个常见的事件修饰符:
事件修饰符 | 说明 |
.prevent | 阻止默认行为(如:a 标签的跳转,表单的提交等) |
.stop | 阻止事件冒泡 |
.capture | 以捕获模式触发当前的事件处理函数 |
.once | 绑定的事件只触发一次 |
.self | 只有在 event.target 是当前元素自身时触发事件处理函数 |
用法皆是通过 @click.名称
的方式
㈡ 按键修饰符
我们在监听 键盘事件 的时候,经常需要判断详细的按键,用来对应不同的按键动作行为。当然 vue 中也为 键盘相关的事件 添加 按键修饰符,例如监听回车键
:(其他按键按需替换 enter
名称即可)
4)双向绑定指令
我们前面已经认识了v-bind / v-text / v-html / {{ }}
等指令,但这些都是 单向绑定指令,页面元素可以从数据源中获取数据,但是数据源无法从页面元素中获取数据。因此,我们这里就说到了 vue 提供的 v-model
双向绑定指令~!
双向绑定指令 的好处便是 不用操作DOM 元素的情况下,可以快速获取表单的数据
我们可以在 input 输入框中更改 username
的值,相应的,页面上{{ username }}
值也会发生变化~!
当我们使用双向绑定处理的时候,为了减少一些不必要的多余操作,如trim, number转换...
,在vue 也已经为我们提供了相应的处理修饰符:
修饰符 | 说明 |
.number | 自动将用户的输入值转为数值类型 |
.trim | 自动过滤用户输入的收尾空白字符 |
.lazy | 在 “change” 时而非 “input” 时更新 |
5)条件渲染指令
条件渲染指令
是用来控制 DOM节点 的显示与隐藏
- v-if
- v-show
以上两个指令都是属于条件渲染指令,使用方式如下:
当满足条件的情况下,两者都会正常显示,当不满足条件的情况下我们来看看两者有什么区别:
我们可以通过 F12 控制台查看页面元素,发现页面元素缺失了 v-if
修饰的 span 元素,因此我们得出结论:
实现原理层面
- v-if 指令会动态地创建或移除 DOM 元素,从而控制元素在页面上的显示或隐藏
- v-show 指令会动态为元素添加或移除
style='display: none;'
样式,从而控制元素在页面上的显示或隐藏
性能消耗层面
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销
- 如果需要频繁的切换,则使用 v-show
- 如果在运行时条件很少改变,则使用 v-if
有 v-if 标签,自然有 v-else-if 和 v-else 标签了~
6)列表渲染指令
前面我们绑定的都是单值元素,当我们遇到数组元素的时候就得使用上 vue 提供的 v-for
标签。该标签是用来 基于一个数组来循环渲染一个列表结构。v-for 指令需要使用 item in items 形式的特殊语法
- items:待循环的数组
- item: 被循环的每一项
除了 item in items
语法,还支持传入 index 作为索引 -> (item, index) in items
这个指令通常搭配的还有一个关键指令 :key
,vue 中使用 key 来维护列表的状态,当列表的数据发生变化时,默认情况下,vue 会尽可能复用已存在的 DOM 元素,从而提升渲染的性能,但这种默认的性能优化策略,会导致有状态的列表无法备正确更新。
为了给 vue 一个提示,以便它能跟踪每个节点的身份,从而在保证有状态的列表被正确更新的前提下,提升渲染的性能。此时,需要为每项提供一个唯一的 key 属性!
关于key 我们需要注意以下几点:
- key 的值只能是
字符串
或者数字
类型
- key 的值必须具有
唯一性
(通常取ID)
- 使用
index
作为 key 的值没有任何意义(index 的值不具有唯一性)
- 建议使用
v-for
指令的是哦户一定要指定 key 的值
Ⅱ、过滤器
上面我们说完了vue 中的 六大类指令,接下来继续聊聊 vue 中的过滤器(Filters)。
过滤器(Filters) 常用于 文本的格式化,可以用来 插值表达式 {{ }} 和 v-bind 中,使用方式如下:
我们以 |
作为 管道符 进行过滤器方法的调用。其中 过滤器方法 写在 filters
节点下。
这种用法可以联想到 Linux 的管道符操作,和 Java 8中的 stream.map 操作
我们上面定义的过滤器是属于 私有过滤器
,何为 私有
?那就是这个过滤器只能在当前的 vm 实例所控制的 el 区域内使用,如果想要在多个 vm 实例之间共享过滤器,则需要定义全局过滤器~!
并且过滤器还支持连续调用多个
同时过滤器还支持传递参数
注意:过滤器仅在
vue 2.x
和1.x
中受支持,在vue 3.x
的版本中剔除了过滤器相关的功能。
Ⅲ、侦听器
什么是侦听器?watch 侦听器可以用来监听数据的变化,从而针对数据的变化做出特定的动作!以下便是简单使用例子:
我们通过监听 data
中的数据源 username,可以获取 username 的最新值,该方式也常用于判断参数值是否可用,快速反馈给使用者提示~!使用侦听器需要注意几点
- 所有的侦听器都应该定义到 watch 节点下
- 侦听器本质上是一个函数,要监听哪个数据发生变化,就把对应数据的名称作为方法名即可
㈠ immediate
在默认情况下,组件在初次加载完毕后不会调用 watch 侦听器,如果想让 watch 侦听器立即被调用,则需要使用 immediate 选项。简而言之,immediate
的作用便是:控制侦听器是否自动触发一次!
使用方式如下:
其中 handler() 是固定写法,当监听值发生变化时,就会自动调用 handler 函数。immediate 表示当页面除此渲染好之后,就立即触发当前 watch 侦听器
这个时候在控制台就可以发现,当初次绑定值的时候就已经触发了侦听器
㈡ deep
当我们监听的值变成一个对象的时候,我们利用以上写法是否还可以监听的到对象的属性值发生改变?
通过控制台我们发现,处理首次监听之外,后面做出的更改都没有触发侦听器!那这个时候就需要用上我们的 deep
属性:
通过加上 deep: true
注解,我们成功监听到了对象属性的变化,如果我们想要通过简写侦听器的方式就需要按照以下写法:
注意:如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
Ⅳ、计算属性
看完了侦听器的使用,我们趁火打劫,呸~ 趁热打铁来了解一下 vue 中的计算属性! 什么是计算属性?计算属性是指通过一系列运算之后,最终得到一个属性值,这个动态计算出来的属性值,可以被模板结构或 methods 使用,简单示例如下:
计算属性本身使用并不复杂,我们需要了解它的几个特点
- 虽然计算属性在声明的时候被定义为
方法
,但是计算属性的本质是一个属性,使用的时候当成普通属性
使用即可
- 计算属性会缓存计算的结果,只有计算属性依赖的
数据变化
时,才会重新进行计算
Ⅴ、总结
咱们这篇简单介绍了 Vue 的基本用法,当然想要掌握 Vue 还有很长的路要走,后续还会持续更新 Vue相关文章!