Vue 简单学习笔记
Vue 官方网站: https://cn.vuejs.org/
Vue 官方教程(v2): https://cn.vuejs.org/v2/guide/
Vue 简介
Vue 是什么?
Vue 是一套用于构建用户界面
的渐进式
JavaScript 框架。
构建用户界面
: 将得到的各种数据变成用户看到的界面。
渐进式
: Vue 可以自底向上逐层应用。简单应用可以只引用一个轻量小巧的核心库,复杂应用可以引入各式各样的 Vue 插件。
谁开发的?
Vue 作者尤雨溪
。
- 2013 年:受到 Angular 框架的启发,尤雨溪开发出一款轻量框架 —— Seed。同年 12 月,Seed 更名为 Vue,版本号
0.6.0
。 - 2014 年:Vue 正式对外发布,版本号
0.8.0
。Taylor otwell
在 Twitter 上发表动态,说自己在学习 Vue.js。 - 2015 年:10 月 27 日,正式发布
Vue 1.0.0 Evangellon
(新世纪福音战士)。 - 2016 年:10 月 1 日,正式发布
Vue 2.0.0 Ghost in the Shell
(攻壳机动队)。 - 2020 年:9 月 18 日,正式发布
Vue 3.0.0 One Piece
(海贼王)。
Vue 的特点
- 采用
组件化
模式,提高代码复用率,让代码更好维护。 声明式
编码,让编码人员无需直接操作 DOM,提高开发效率。
Vue 基础教程
Hello World
首先引入 Vue.js:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> |
准备一个 div 作为容器,然后创建 Vue 实例,传入配置对象
,进行挂载:
<div id='root'> |
注意:
HTML 容器与 Vue 实例之间是一一对应的。
root 容器里的代码被称为Vue 模板
。
真实开发中只有一个 Vue 实例,并且会配合组件一起使用。
一旦 data 中的数据发生改变,页面中用到该数据的地方也会自动更新。
插值表达式
插值表达式可以读取 data 中的所有属性,任何合法的JS表达式,一般用在标签体内。
<p>{{ msg }}abc</p> |
v-bind
v-bind
主要用于元素属性的单向绑定,从 data 自动同步到 view 上。v-bind:class="fl"
可以简写成:class="fl"
。
如果想要实现表达式的拼接,被拼接的字符串一定要用引号包裹,否则会被当成变量解析。
<input type="text" v-bind:value="msg"> |
v-model
v-model
主要用于元素属性的双向绑定
。
在Vue中,只有 v-model 指令实现了数据的双向绑定,其他指令都是单向的。
v-model 主要绑定标签的 value 属性,所以在使用时可以省略 value。
v-model 只能应用在表单元素中。
v-model 的三个修饰符:
lazy: 失去焦点再收集数据。
number: 输入的数据转换成有效数字。
trim: 过滤首尾空格。
<input type="text" v-model:value="msg"> |
el 与 data 的两种写法
el 的两种写法
// 第一种:创建的时候直接指定 el。 |
data 的两种写法
// 第一种:对象式 |
一个重要原则:由 Vue 管理的函数,一定不要写成箭头函数的形式,否则 this 不再是 Vue 实例而是 window,这时将无法访问 Vue 实例里的内容(如 data)。
Object.defineProperty()
使用
Object.defineProperty()
方法可以在对象上定义新的属性:
let person = { |
此外,
Object.defineProperty()
方法在定义新属性时,还可以使用getter
和setter
:
let number = 19 |
Vue 的数据代理
数据代理:通过一个对象代理对另一个对象中的属性的操作(读/写)
Vue 通过 vm 对象来代理 data 对象中属性的操作,可以更方便的操作 data 中的数据。
data === vm._data
基本原理:
let obj = {x: 100} |
v-on
v-on
主要用于元素的事件绑定。v-on:click="method"
可以简写成@click="method"
。
在调用时如果不写参数,则形参第一个参数为 event。
在调用时如果传入数据参数,可以用$event
传入事件参数。
<button v-on:click="show">按钮</button> |
v-cloak
v-cloak
会在页面渲染完成之后移除。
可以通过 CSS 的属性选择器来操作被其修饰的元素,可以避免将未挂载的页面显示给用户。
<style> |
v-pre
v-pre
被其修饰的元素不会被 VUE 编译。
v-text
v-text
会全部替换标签体里的内容,而且内部支持写表达式。
<p v-text="msg"></p> |
v-text 与 插值表达式 的区别:
插值表达式只会插入内容,并不会清除其余内容。而 v-text 则会清除所有内容。
v-html
v-html
会将元素当成HTML标签解析后输出。
<p v-html="msg"></p> |
v-for
我们可以用 v-for
指令基于一个数组来渲染一个列表,推荐只要涉及到 v-for
这种循环,就给循环的每一项都添加 :key
属性。:key
属性只接受 number 或者 string 类型。
<li v-for="item in list" :key="item.id">{{ item }}</li> |
注意:
:key
绑定值为索引时,在列表的最顶端插入数据会造成效率低、数据错乱的问题,这涉及到 Vue 的 Diff 算法。最好是绑定为每一项的 ID 值。
v-if & v-show
v-if
指令和 v-show
指令都用于条件性地渲染一块内容。不同的是带有 v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS property display。
<div id="app"> |
v-if
也可以和 v-else-if
、v-else
来使用,中间不可打断。
<div v-if="n === 1">Angular</div> |
事件修饰符
- 在事件后面加上
.stop
即可防止事件冒泡。
<div id="app"> |
- 在事件后面加上
.prevent
即可阻止事件的默认行为。可以和.stop
连续写。
<div id="app"> |
.capture
添加事件监听器时使用事件捕获模式。.self
只当事件在该元素本身(比如不是子元素)触发时触发回调。.once
事件只触发一次。
键盘事件
<div id='root'> |
Vue 中常用的键盘别名:
enter, delete, esc, space, tab, up, down, left, right
- Vue 中未提供别名的按键,可以使用按键原始的 key 值去绑定,但要注意转换为 kebab-case(短横线命名),如:
@keyup.caps-lock
- 系统修饰键:ctrl, alt, shift, meta(win键)
- 配合 keyup 使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
- 配合 keydown 使用:正常触发事件。
- 也可以使用 keyCode 去指定具体的按键(不推荐),如
@keyup.17
- Vue.config.keyCodes.自定义键名 = 键码, 可以自定义按键别名
- 组合键:
@keyup.ctrl.z
Vue 中使用样式
class 样式
- 数组
<h1 :class="['red', 'thin']"></h1> |
- 三元表达式
<h1 :class="['red', 'thin', isActive?'active':'']"></h1> |
- 数组中嵌套对象
<h1 :class="['red', 'thin', {'active': isActive}]"></h1> |
- 直接使用对象
<h1 :class="{red: true, thin: true, active: isActive}"></h1> |
内联样式
直接在元素上通过 :style 的形式,书写样式对象。
<h1 :style="{color: 'red', 'font-size': '40px'}"></h1> |
Vue 计算属性
- 当要使用的属性为其他属性计算得来时,可以使用计算属性。
- 原理:底层借助了
Object.defineproperty()
方法提供的 getter 和 setter。- get 函数在初次读取时会执行一次,在依赖的数据发生改变时会被再次调用。
- 与 methods 实现相比,内部有缓存机制,效率更高。
- 计算属性最终会出现在 vm 上,可以直接读取使用。
new Vue({ |
Vue 侦听器
- 侦听器可以侦听属性和计算属性
- watch 默认不侦听对象内部值的改变,如需侦听,要配置
deep: true
。
new Vue({ |
Vue 过滤器
概念: Vue.js 允许你自定义过滤器,可以被用作一些常见的文本格式化,过滤器可以用在两个地方:插值表达式和 v-bind 表达式,过滤器应被添加在 JavaScript 表达式的尾部,由管道符指示。
全局过滤器
<p>{{ date | formatDate }}</p> |
局部过滤器
如果全局过滤器和私有过滤器重名了,则会优先使用局部过滤器(就近原则)。
<p>{{ date | formatDate }}</p> |
Vue 自定义指令
简介: 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
指令会在如下两种情况时调用:
1. 指令与元素绑定成功时。
2. 指令所在的模板被重新解析时。
如果指令名称涉及多个单词,定义时可以用减号连接并用引号包裹。
‘big-number’(element, binding){}
在自定义指令的函数中,this 为 window 对象而不是 Vue 实例对象。
全局自定义指令
<input type="text" v-focus> |
局部自定义指令
<input type="text" v-focus> |
钩子函数参数
指令钩子函数会被传入以下参数:
el
: 指令所绑定的元素,可以用来直接操作 DOM。binding
: 一个对象,包含以下 property:name
:指令名,不包括 v- 前缀。value
:指令的绑定值,例如:v-my-directive=”1 + 1” 中,绑定值为 2。oldValue
:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如 v-my-directive=”1 + 1” 中,表达式为 “1 + 1”。arg
:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。oldVnode
:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
钩子函数简写
在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:
<script> |
Vue 监听数据的原理
- Vue 会监视 data 中所有层次的数据。
- Vue 通过 setter 实现监视,且要在 new Vue 时就传入要监视的数据。
- 给对象中追加属性,要用如下两种方式,否则 Vue 不会做响应式处理。
Vue.set(target, propertyName/index, value)
vm.$set(target, propertyName/index, value)- Vue 通过包裹数组更新元素的方法实现数组的监测,所以更新数组时用下列方法,Vue 才会重新渲染页面:
push(), pop(), shift(), unshift(), splice(), sort(), reverse()
Vue.set(), vue.$set()- Vue.set() 和 vue.$set() 不能给 vm 或 vm 的根数据对象添加属性!
Vue 的生命周期
创建阶段
new Vue(): 创建一个Vue的实例
Init Events & Lifecycle
beforeCreate()
Init injections & reactivity: 初始化 data 和 methods
created()
编译模板页面(不放在页面中)。
beforeMount(): 即将渲染(在这个函数中,页面中的DOM元素是原始的)。
将指定的 el 元素替换为编译好的 HTML 结构。
mounted(): 已完成渲染,创建阶段结束,进入运行阶段。
运行阶段
主要工作就是根据最新的 data 值来重新渲染页面。
当 data 更新之后触发一下事件:
beforeUpdate(): 页面渲染之前。
updated(): 页面渲染完毕之后。
销毁阶段
beforeDestroy(): 销毁之前调用。
destroyed(): 销毁之后。
Vue 发送请求
vue-resource
axios
axios.get(url).then(response=>{}); |
Vue 动画
Vue 把一个完整的动画,拆分成了两部分,入场动画 和 出场动画。
入场动画中,包含两个时间点,分别是 进入之前(v-enter) 和 进入之后(v-enter-to)。
v-enter 表示动画入场前的起使状态,v-enter-to 表示动画入场完成之后的终止状态。
v-enter-active 表示入场动画的时间段,在这里可以规定动画的时长、动画效果。
使用 Vue 动画
把要实现动画的元素,用
<transition>
元素包裹起来。要实现动画的元素,必须使用
v-if
或v-show
来进行控制。在
style
里设置.v-enter,.v-leave-to
和.v-enter-active,.v-leave-active
的样式。可以使用钩子函数设置自定义动画。
<style scoped> |
使用现成动画库
- 导入动画css
npm install --save animate.css |
- 设置动画
<p v-show="flag" class="animate__animated animate__bounce animate__faster">动画测试</p> |
列表动画
不知道为啥没效果,可能什么地方不对吧,懒得折腾动画了。
<template> |
Vue 自定义组件
template 属性中,不能单独放一段文本,必须用标签包裹起来。
如果要在 template 中放置多个元素,那么在这些元素外必须有唯一的根元素进行包裹。
全局自定义组件
第一种方式
<div id="app"> |
第二种方式
<div id="app"> |
第三种方式
<!-- 定义一个 template 标签元素 --> |
局部自定义组件
<div id="app"> |
组件中的 data 需要定义成一个 function ,因为每实例化一个组件,就会调用一次 data 的 function 来获取一个新的值,从而保证每个组件的 data 数据都是独立的。
评论例子
<template> |
使用 refs 来获取元素和组件
- 被用来给元素或子组件注册引用信息(id 的替代者)
- 应用在 HTML 标签上获取的是真实 DOM 元素,应用在组件标签上是组件实例对象(VueComponent)
<!-- 在元素加上加上 ref 属性 --> |
使用 props 给子组件传值
父组件传值方式:和属性赋值一样,直接写在子组件的标签中。
<Demo name=""></Demo> |
子组件接受方式:
// 第一种方式:只接受 |
注意:
props 是只读的
,Vue 底层会检测你对 props 的修改,但是会发出警告。若业务需求确实要修改,可以在 data 中定义一个新的变量,赋值为属性的值。
data() { |
Vue mixin(混入)
功能:可以吧多个组件共用的配置提取成一个混入对象。
步骤:创建一个 js 文件存放 mixin 数据,其他组件引入混入数据,即可使用。
注意:如果混合中的 data 与组件中的 data 冲突,则会使用组件中的 data;如果混合数据与组件都有 mounted 生命周期函数,则都会调用。
// mixin.js |
全局混入:调用
Vue.mixin()
函数注册全局混入,其他所有组件都可以直接使用。
// main.js |
Vue 插件
功能:用于增强 Vue
本质:包含 install 方法的一个对象,install 的第一个参数是 Vue,第二个及以后的参数是插件使用者传递的数据。
定义插件:
// plugins.js |
使用插件:
// main.js |
scoped 样式
作用:让样式在局部生效,防止冲突。
<style scoped> |
另外,在 style 标签中也可以指定 CSS 的 lang 属性,可以直接写 less,默认是 css。
<style lang='less' scoped> |