Vue 根底
邂逅 Vuejs
1. 意识 Vuejs
-
Vue 是一个 <font color=’red’> 渐进式框架 </font>, 什么是渐进式的呢?
- 申明式渲染→组件零碎→客户端路由→集中式状态治理→我的项目构建
- 渐进式意味着你能够将 Vue 作为你 <font color=’red’> 利用的一部分 </font> 嵌入其中,带来更丰盛的交互体验。
-
Vue 有很多特点和 Web 开发中常见的高级性能
- 解耦视图和数据
- 可复用的组件
- 前端路由技术
- 状态治理
- 虚构 DOM
2.Vue 初体验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1、导入 Vue 的包 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<!-- 这个 div 区域就是 MVVM 中的 View-->
<div id="app">
{{message}}
</div>
</body>
<script>
// 2、创立一个 Vue 的实例
var app = new Vue({
el: '#app', // 用于挂载要治理的元素
data: {// 定义数据
message: '学习 Vue.js'
}
});
</script>
</html>
3.Vue 中的 MVVM
-
View 层
- <font color=’red’> 视图层 </font>
- 前端开发中, 通常就是 DOM 层
- 次要的作用是给用户展现各种信息
-
Model 层
- <font color=’red’> 数据层 </font>
- 数据可能是咱们固定的死数据, 更多的是来自咱们的服务器, 从网络上申请下来的数据
-
VueModel 层
- <font color=’red’> 视图模型层 </font>
- 视图模型层是 View 和 Model 沟通的桥梁
- 一方面它实现了 Data binding, 也就是数据绑定, 将 Model 的扭转实时的反馈到了 View 中
- 另一方面它实现了 DOM Listener,也就是 DOM 监听,当 DOM 产生一些事件 (点击、滚动、touch 等) 时,能够监听到,并在须要的状况下扭转对应的 Data。
4.Vue 实例传入的 options
- 目前把握
属性名 | 类型 | 作用 | |
---|---|---|---|
el |
<font color=’blue’> 类型: string \ | HTMLElement</font> | 决定 Vue 实例会治理哪一个 DOM |
data |
<font color=’blue’> 类型: Object \ | Function (组件当中 data 必须是一个函数)</font> | Vue 实例对应的数据对象 |
methods |
<font color=’blue’> 类型: {[key: string]: Function }</font> | 定义属于 Vue 的一些办法, 能够再其余中央调用, 也能够在指令中应用 |
5.Vue 生命周期
插值指令
1.Mustache
- 插值表达式 {{}}
数据绑定最常见的模式就是应用“Mustache”语法(双大括号)的文本插值。例如:
<span>Message: {{msg}}</span>
Mustache 标签将会被代替为对应数据对象上 msg 属性(msg 定义在 data 对象中)的值。
无论何时,绑定的数据对象上 msg 属性产生了扭转,插值处的内容都会自动更新。
语法 | {{}} JavaScript 表达式反对 |
---|---|
一般表达式 | {{number + 1}} |
三元表达式 | {{ok ? ‘YES’ : ‘NO’}} |
三元表达式 | {{name == ‘smyhvae’ ? ‘true’ : ‘false’}} |
调用办法 | {{message.split(”).reverse().join(”) }} |
2.v-once
该指令前面不须要跟任何表白
该指令示意元素 <font color=’red’> 只渲染一次 </font>,不会随着数据的扭转而扭转。
<h2 v-once>{{message}}</h2>
3.v-html
解析 <font color=’red’> 数据中的 html</font> 代码,渲染到页面中
<h2 v-html="url"></h2>
4.v-text
v-text 作用和 Mustache 比拟类似:都是用于将 <font color=’red’> 数据显示在界面 </font> 中, 不同的是 v-text 是写在属性中
v-text 通常状况下,接管一个 string 类型
<h2 v-text="text"></h2>
5.v-pre
v-pre 用于跳过这个元素和它子元素的编译过程,用于 <font color=’red’> 显示本来的 Mustache</font> 语法。
<h2 v-pre>{{message}}</h2>
6.v-cloak
在某些状况下,咱们浏览器可能会间接显然出未编译的 Mustache 标签。
v-cloak 指令和 CSS 规定一起用的时候,可能解决插值表达式闪动的问题(即:能够暗藏未编译的标签直到实例筹备结束)
<!-- 在 vue 解析之前, div 中有一个属性 v -cloak
在 vue 解析之后, div 中没有一个属性 v -cloak -->
<div id="app" v-cloak>
<h2>{{message}}</h2>
</div>
总结
- Mustache: {{}}语法, 能够写变量 / 逻辑表达式 / 计算值 …
- v-once : 元素只渲染一次,不会随着数据的扭转而扭转。
- v-html=”” : 解析数据中的 html 代码,渲染到页面中
- v-text=”msg”: 写在属性当中, 将数据显示在界面中
- v-pre: 原文输入, 显示本来的 Mustache 语法
- v-cloak : 个别配合 CSS 规定一起应用, 够解决插值表达式闪动的问题
v-bind 绑定属性
1.v-bind 介绍
- 后面咱们学习的指令次要作用是将值插入到咱们 <font color=’red’> 模板的内容 </font> 当中。
- 然而,除了内容须要动静来决定外,某些 <font color=’red’> 属性 </font> 们也心愿动静来绑定。
-
作用:能够给 html 元素或者组件动静地绑定一个或多个个性,例如动静绑定
style
和class
- 比方动静绑定 a 元素的 href 属性
- 比方动静绑定 img 元素的 src 属性
-
这个时候,咱们能够应用 v -bind 指令:
- 作用:动静绑定属性
- 缩写:
:
- 预期:any (with argument) | Object (without argument)
- 参数:attrOrProp (optional)
2.v-bind 绑定 class
绑定 class 有两种形式
- 对象语法
- 数组语法
-
对象语法
- 对象语法的含意是
:class
前面跟的是一个 <font color=’red’> 对象 </font>。
- 对象语法的含意是
<!-- 用法一:间接通过 {} 绑定一个类 -->
<h2 :class="{'active': isActive}">Hello World</h2>
<!-- 用法二:也能够通过判断,传入多个值 -->
<h2 :class="{'active': isActive,'line': isLine}">Hello World</h2>
<!-- 用法三:和一般的类同时存在,并不抵触 -->
<!-- 注:如果 isActive 和 isLine 都为 true,那么会有 title/active/line 三个类 -->
<h2 class="title" :class="{'active': isActive,'line': isLine}">Hello World</h2>
<!-- 用法四:如果过于简单,能够放在一个 methods 或者 computed 中 -->
<!-- 注:classes 是一个计算属性 -->
<h2 class="title" :class="classes">Hello World</h2>
-
数组语法
- 数组语法的含意是
:class
前面跟的是一个 <font color=’red’> 数组 </font>。
- 数组语法的含意是
<!-- 1. ['active','news'] 当字符串应用 -->
<h2 class="title" :class="['active','news']">{{message}}</h2>
<!-- [active, new] 当变量应用 -->
<h2 class="title" :class="[active,news]">{{message}}</h2>
<!-- 3. 函数返回值应用 -->
<h2 class="title" :class="getClasses()">{{message}}</h2>
3.v-bind 绑定 style
- 咱们能够利用 v -bind:style 来绑定一些 CSS 内联款式
-
绑定 class 有两种形式
- 对象语法
- 数组语法
-
对象语法
style
前面跟的是一个对象类型- 对象的
key
是 css 属性名 - 对象的
value
是具体赋的值, 能够来自data
中的属性
:style="{color: currentColor, fontSize: fontSize +'px'}"
-
数组语法
style
前面跟的是一个数组类型, 多个值以 , 分隔
<div v-bind:style="[baseStyles, fontColor]"></div>
/* js */
baseStyle: {background: 'lime'},
fontSize: {fontSize: '80px'}
computed 计算属性
1. 基本概念
- 计算属性呈现的目标是 <font color=’red’> 解决模板中放入过多的逻辑 </font> 会让模板过重且难以保护的问题
- 计算属性是基于它们的响应式 <font color=’red’> 依赖进行缓存 </font> 的
-
在某些状况,咱们可能须要对数据进行一些转化后再显示,或者须要将多个数据联合起来进行显示
- 比方咱们有
firstName
和lastName
两个变量,咱们须要显示残缺的名称。 - 然而如果多个中央都须要显示残缺的名称,咱们就须要写多个
{{firstName}} {{lastName}}
- 比方咱们有
-
将下面代码转换成计算属性
/* html */ <h2>{{fullNmae}}</h2> /* js */ computed: {fullNmae: function () {return this.firstNmae + ' ' + this.lastNmae;} }
2. 计算属性的 setter 和 getter
-
每个计算属性都蕴含一个
getter
和一个setter
- 在下面的例子中,咱们只是应用
getter
来读取。 - 在某些状况下,你也能够提供一个 setter 办法(不罕用)。
- 在须要写 setter 的时候,代码如下:
- 在下面的例子中,咱们只是应用
3. 计算属性的缓存
-
methods 和 computed 区别
methods
外面的数据不论发没发生变化, 只有调用了都会执行函数(有的时候数据没发生变化咱们不心愿调用函数)computed
计算属性会进行缓存, 如果数据没发生变化, 函数只会被调用一次(数据发生变化才会调用函数)
-
总结:
methods
不论数据发没发生变化都会调用函数computed
只有在依赖数据发生变化时才回调函数
事件监听指令
-
在前端开发中,咱们须要常常和用户交互
- 这个时候咱们就必须监听用户的产生工夫,比方点击, 拖拽事件等等
-
v-on 介绍
- 作用: 绑定事件监听器
- 缩写:
@
1.v-on 参数
- 当
methods
中定义方法, 以供@click
调用时, 须要留神参数问题 -
状况一: 如果该办法不须要额定参数, 办法后
()
能够省略- 没有传入参数, 接管形参时默认会将原生事件
event
参数传递进去
- 没有传入参数, 接管形参时默认会将原生事件
- 状况二: 如果须要同时传入某个参数, 同时须要
event
时, 能够通过$event
传入事件
2.v-on 修饰符
v-on
提供了很多事件修饰符来辅助实现一些性能。事件修饰符有如下
修饰符 | 作用 | |
---|---|---|
.stop | 阻止冒泡。实质是调用 event.stopPropagation() | |
.prevent | 阻止默认事件行为 实质是调用 event.preventDefault() | |
.{keyCode \ | keyAlias } | 当事件是从特定键触发时才触发回调 |
.once | 事件只触发一次 |
条件渲染指令
1.vi- f 与 v -else-if 与 v -else
- Vue 的条件指令能够依据表达式的值在 DOM 中渲染或销毁元素或组件
<h2 v-if="score>=90"> 优良 </h2>
<h2 v-else-if="score>=80"> 良好 </h2>
<h2 v-else-if="score>=60"> 及格 </h2>
<h2 v-else> 不及格 </h2>
- 逻辑较多不倡议在模板中应用
v-if-else-if
2. 复用元素渲染问题
一个问题: 波及到了 Vue 底层, 虚构 DOM virtual DOM
点击切换表单后,input 的 value 值并没有被清空, 为什么?
- 引出:当实现点击按钮切换
input
表单时, 咱们输出上的value
, 点击按钮切换表单时会发现value
值还存在, 然而input
元素的确切换了, 这是因为什么呢?
<span v-if="isUser">
<label for="user"> 用户名 </label>
<input type="text" placeholder="用户名" id="user" key="user">
</span>
<span v-else>
<label for="email"> 邮箱 </label>
<input type="text" placeholder="邮箱" id="email" key="email">
</span>
<button @click="isUser=!isUser"> 切换类型 </button>
<script>
const app = new Vue({
el: '#app',
data: {isUser: true}
})
</script>
-
起因:
- 1. 这是因为 Vue 在进行 DOM 渲染时, 出于性能思考, 会尽可能服复用曾经存在的元素, 而不是创立新的元素
- 2. 下面的案例中, Vue 外部会进行比照发现两局部都类似只会替换属性, 不会给你创立全新的元素
- 3. 下面 if 的 input 不再应用, 间接作为 else 的 input 来应用
-
解决方案
- 1. 如果咱们不心愿
Vue
呈现相似反复利用的问题, 能够给对应的input
增加key
- 2. 并且保障要们须要的
key
不同, 这样vue
就会创立一个全新input
元素
- 1. 如果咱们不心愿
3.v-show
v-show 的用法和 v -if 十分类似, 也用于决定一个元素是否渲染
-
v-if 和 v-show 比照
- v-if 当条件为 false 时, 压根不会有对应的元素在 DOM 中
- v-show 当条件为 false 时, 仅仅是将元素的 display 属性设置 none 而已
-
开发中如何抉择呢?
- 当须要在显示与暗藏之间切换很频繁时, 应用 v -show
- 当只有一次切换时, 通过应用 v -if
<h2 v-show="isShow">{{message}}</h2>
循环遍历指令
1.v-for 遍历数组
- 作用:依据数组中的元素遍历指定模板内容生成内容。
- 语法:
v-for="(item, index) in items"
<ul>
<!-- item: 是每一项元素 index: 下标 / 索引 -->
<li v-for="(item, index) in name">
{{index+1}}.{{item}}
</li>
</ul>
2.v-for 遍历对象
- 作用: 遍历对象
- 语法:
v-for="(value, key, index) in items"
<ul>
<!-- value: 属性值 key: 属性名 index: 下标 / 索引 -->
<li v-for="(value, key, index) in info">
{{index+1}}.{{value}}
</li>
</ul>
3.Vue 中 Key 属性
- 官网举荐咱们在应用
v-for
时, 给对应的元素或组件增加上一个:key
属性。 -
为什么须要这个 key 属性呢(理解) ?
- 这个其实和 Vue 的虚构 DOM 的
Diff
算法有关系。
- 这个其实和 Vue 的虚构 DOM 的
-
当某一层有很多雷同的节点时,也就是列表节点时,咱们心愿插入一个新的节点
- 咱们心愿能够在 B 和 C 之间加一个 F,Diff 算法默认执行起来是这样的。
- 即把 C 更新成 F,D 更新成 C,E 更新成 D,最初再插入 E,是不是很没有效率?
-
所以咱们须要应用 key 来给每个节点做一个惟一标识
- Diff 算法就能够正确的辨认此节点
- 找到正确的地位区插入新的节点
- <font color=’red’>key 的作用次要是为了高效的更新虚构 DOM</font>
应用
v-for
更新已渲染的元素列表时, 默认用 <font color=’red’> 就地复用 </font> 策略; 如果列表数据批改的时候, 它会依据 key 值去判断某个值是否批改, 如果批改, 则从新渲染这一项, 否则复用之前的元素; 咱们在应用的应用常常会应用index
(即数组的下标) 来作为key
, 但其实这是不举荐的一种应用办法;
4. 数组响应式办法
- 因为 Vue 是响应式的, 所以当数据发生变化时, Vue 会自动检测数据变动, 视图会对应的更新
-
Vue 中蕴含了一组察看数组编译的办法, 使它们扭转数组也会触发更新视图
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
5.Vue.set 批改响应式数据
Vue.set(vm.items, indexOftem, newValue)
-
vm.$set(vm.items ,indexOften,newValue)
- 参数 1: 要批改的数组 / 对象
- 参数 2: 要设置的索引 / 增加的属性名
- 参数 3: 设置的值
6.v-if 和 v-for
当它们处于同一节点,
v-for
的优先级比v-if
更高,这意味着
v-if
将别离反复运行于每个v-for
循环中。防止
v-if
和v-for
用在一起
-
起因
- 如果应用了 if 判断, 每次渲染在 Vue 外部都会遍历整个列表, 不管判断条件是否产生了变动
-
应用计算属性的益处
- 1. 过滤后的列表只会在 users 数组产生相干变动时才被从新运算, 过滤更高效。
- 2. 应用 v -for=”user in activeusers” 之后, 咱们在渲染
- 3. 的时候只遍历沉闷用户, 渲染更高效。
- 4. 解耦渲染层的逻辑, 可维护性 (对逻辑的更改和扩大) 更强。
- 具体解说
表单绑定 v -model
1. 基本概念
-
Vue 中应用
v-model 指令
来实现表单元素和 <font color=’red’> 数据的双向绑定 </font>- 数据与模板是相互影响的, 一方发生变化, 另一方立刻做出更新
-
引出:
- 在之前的案例, 咱们通过 v -bind, 给 <input> 标签绑定了 data 对象里的 name 属性。data 中的 name 的值产生扭转时, <input> 标签里的内容会自动更新。
- 可当初要做的是: 在 <input> 标签里批改内容, 要求 data 中的 name 的属性值自动更新。从而实现 <font color=’red’> 双向数据绑定 </font>。该怎么做呢? 这就能够利用
v-model
这个属性。
-
区别:
v-bind
: 只能实现数据的单向绑定, 从 M 主动绑定到 v。v-model
: 只有v-model
能力实现双向数据绑定。留神,v-model 后
面不须要跟冒号
-
留神
v-model
只能使用在表单元素中, 或者用于自定义组件。常见的表单元素包含:input(radio,text,address,email...) ,select, checkbox, textarea.
2.v-model 原理
-
v-model 其实是一个语法糖, 他背地实质是蕴含两个操作
- v-bind 绑定一个 value 属性
- v-on 指令绑定以后元素的 input 事件
- 也就是说上面的代码:等同于上面的代码:
<input type="text" v-model="message">
<!-- 等同于上面的代码 -->
<input type="text" :value="message" @input="message = $event.target.value">
3. 表单绑定 v -model
- Vue 中应用
v-model
指令来实现表单元素和数据的双向绑定 -
案例解析:
- 当咱们在数据框输出内容时
- 因为 input 中 v -model 绑定了 message, 所以会实时将输出的内容传递给 message, message 发生变化
- 当 message 发生变化时, 因为下面咱们应用 Mustanche 语法, 将 message 的值插入到 DOM 中, 所以 DOM 会产生响应式的扭转
- 所以, 通过 v -model 实现了双向的绑定
- 当然, 咱们能够将 v -model 用于 textarea 元素
4. 表单中其它类型绑定 v -model
- 表单中其它类型, 绑定
v-model
表单类型 | 单选 / 多选状况 | 绑定的值 |
---|---|---|
v-model: radio |
多个单选框时 | 绑定的 值是 value |
v-model: checkbox |
单个勾选框 | v-model 即为 布尔值 |
多个复选框 | 选中多个, 对应的 data 属性是一个 数组 |
|
v-model: select |
单选 | v-model 绑定的是一个 值 |
多选 | v-model 绑定的是一个 数组 |
5. 值绑定
-
动静的给
value
赋值而已- 咱们后面之前写的
value
中的值, 都是在定义 input 中间接给定的 - 然而真是开发中, 这些 input 中的 value 值可能是从服务器中获取, 而后定义的
- 所以咱们能够通过
v-bind:value
动静的给 value 绑定值
- 咱们后面之前写的
5.v-model 的修饰符
修饰符 | 作用 |
---|---|
.lazy |
当表单 失去焦点 或按下 回车 时,data 中的数据才会更新 |
.number |
输出的内容转换为 number 数据类型 |
.trim |
过滤内容的两侧 空格 |
Vue 罕用个性
1. 自定义指令
为何须要自定义指令
- 内置指令不满足需要
Vue.directive 注册全局指令
- 自定义指令语法(获取焦点)
Vue.directive('focus', {inserted: function (el) {el.focus()// 获取元素的焦点
}
})
// 应用自定义指令
<input type="text" v-focus>
- 带参数的自定义指令
Vue.directive('color', {
// bind 申明周期, 只调用一次,指令第一次绑定到元素时调用。在这里能够进行一次性的初始化设置
// el 为以后自定义指令的 DOM 元素
// binding 为自定义的函数形参 通过自定义属性传递过去的值 存在 binding.value 外面
bind: function(el, binding){
// 依据指令的参数设置背景色
// console.log(binding.value.color)
el.style.backgroundColor = binding.value.color;
}
});
// 应用带参数自定义指令
<input type="text" v-color='msg'>
自定义部分指令
- 部分指令,须要定义在
directives
的选项 用法和全局用法一样 - 部分指令只能在以后组件外面应用
- 当全局指令和部分指令同名时以部分指令为准
directives: {
focus: {inserted: function(el) {el.focus();
}
}
}
2. 侦听器 watch
侦听器的利用场景
- 数据变动时执行
异步
或开销较大的操作
- 留神: watch 中的属性 肯定是 data 中 曾经存在的数据
// 当 data 中的: firstName 属性或 lastNames 属性扭转时, 会主动触发对应的 watch
watch: {firstName(val) { // val: 示意变动后的值
this.fullName = val + ' ' + this.lastName;
},
lastName(val) {this.fullName = this.firstName + ' ' + val;}
}
3. 过滤器
- 概念: Vue.js 容许咱们自定义过滤器, 可被用作一些常见的
文本格式化 / 解决
。- 过滤器能够用在两个中央: mustache 插值表达式、v-bind 表达式。
- 过滤器应该被增加在 JavaScript 表达式的尾部, 由“管道”符批示。
- 过滤器不扭转真正的
data
,而只是扭转渲染的后果,并返回过滤后的版本
- 全局注册时是 filter,没有 s 的。而部分过滤器是 filters,是有 s 的
- 反对级联操作(对前一个过滤的数据再次进行过滤解决)
自定义全局过滤器
- 咱们能够用全局办法
Vue.filter()
自定义一个全局过滤器。这样的话, 每一个 Vue 的对象实例 (每一个 VM 实例
) 都能够拿到这个过滤器。它接管两个参数
:过滤器的名称
、过滤器函数
。
<div>{{msg | upper}}</div>
<div>{{msg | upper | lower}}</div>
<div :class="msg | upper"></div>
<!-- 带参数过滤 -->
<div>{{date | format('yyyy-MM-dd')}}</div>
<script>
// 1. 全局过滤器
Vue.filter('upper', (val) => {
// val 就是要解决的数据
return val.charAt(0).toUpperCase() + val.slice(1);
})
// 2. 解决带参数过滤器
Vue.filter('format', (date, arg) => {
// arg: 传递的参数
if (arg === 'yyyy-MM-dd') {return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();}
})
</script>
自定义公有过滤器
- 公有过滤器: 在某一个 vue 对象外部定义的过滤器称之为公有过滤器
- 这种过滤器只有在
以后 vue 对象
的el 指定的监管区域
有用。
<!-- 管道符后面的 price: 要把 price 这段文本进行过滤 -->
<!-- 管道符前面的 showPrice: 是通过 showPrice 这个过滤器来进行操作 -->
<td>{{price | showPrice}}</td>
<script>
const app = new Vue({
filters: {showPrice(price) {return '¥' + price.toFixed(2);
}
}
})
</script>
4. 生命周期
- 事物从出世到死亡的过程
- Vue 实例从创立到销毁的过程, 这些过程中会随同着一些函数的自调用。咱们称这些函数为钩子函数
- 次要阶段
-
挂载(初始化相干属性)
- beforeCreate
- created
- beforeMount
- mounted
-
更新(元素或组建的变更操作)
- beforeUpdate
- updated
-
销毁(销毁相干属性)
- beforeDestroy
- destroyed
钩子函数 | 过程 |
---|---|
beforeCreate | 在实例初始化之后, 数据观测和事件配置之前被调用此时 data 和 methods 以及页面的 DOM 构造都没有初始化什么都做不了 |
created | 在实例创立实现后被立刻调用此时 data 和 methods 曾经能够应用然而页面还没有渲染进去 |
beforeMount | 在挂载开始之前被调用此时页面上还看不到实在数据只是一个模板页面而已 |
mouted | el 被新创建的 vm.$el 替换, 并挂载到实例下来之后调用该钩子。数据曾经实在渲染到页面上在这个钩子函数外面咱们能够应用一些第三方的插件 |
beforeUpdate | 数据更新时调用,产生在虚构 DOM 打补丁之前。页面上数据还是旧的 |
update | 因为数据更改导致的虚构 DOM 从新渲染和打补丁, 在这之后会调用该钩子。页面上数据曾经替换成最新的 |
beforeDestroy | 实例销毁之前调用 |
destroyed | 实例销毁后调用 |