[TOC]
Vue的基础
Vue概述:2014/2 Vue.js正式发布;2015/10/27 正式发布1.0.0版本;2016/4/27 发布2.0预览版本
- 渐进式JavaScript框架
- 声明式渲染 => 组件系统 => 客户端路由 => 集中式状态管理 => 项目构建
- 官网:https://cn.vuejs.org/v2/guide/
特性:
- 易用:熟悉HTML、CSS、JavaScript知识后,可快速上手Vue
- 灵活:在一个库和一套完整框架之间自由伸缩
- 高效:20kb运行大小,超快虚拟DOM
Vue基本使用
<div id="app">{{msg}}<div>
<div>{{1 + 2}}</div>
<div>{{msg + '!!!'}}</div>
<!-- Vue基本使用步骤 -->
<script src="js/vue.js"></script>
<script>
/*
* 1. 提供标签用于填充数据
* 2. 引入vue.js文件
* 3. 使用vue的语法实现功能
* 4. 把vue提供的数据填充到标签中即可
*/
var vm = new Vue({
el: '#app', // 把数据填充到哪个位置
data: {
msg: 'Hello Vue'
}
});
</script>
- 实例参数分析
- el:元素的挂载位置(值可以是CSS选择器或者DOM元素)
- data:模型数据(值是一个对象)
- 插值表达式用法
- 将数据填充到HTML标签中
- 差值表达式支持基本的计算操作
- Vue代码运行的原理
- 概述编译过程的概念(Vue语法 => 原生语法)
Vue的模板语法
- 如何理解前端渲染?
- 把数据填充到HTML标签中
- 前端渲染方式
- 原生js拼接字符
- 把数据以字符串的方式拼接到HTML标签中
- 缺点:不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来
- 使用前端模板引擎
- 有自己的一套模板语法规范
- 优点:遵循同样的规范写法代码,代码可读性明显提高了,方便后期的维护
- 缺点:没有专门提供事件机制
- 使用Vue特有的模板语法
- 差值表达式
- 指令
- 事件绑定
- 属性绑定
- 样式绑定
- 分支循环结构
- 原生js拼接字符
指令
- 什么是指令?
- 指令的本质就是自定义属性
- 指令的格式:以v开始(比如:v-cloak)
-
v-cloak
指令的用法- 差值表达式存在的问题:"闪动"
- 如何解决该问题:使用
v-cloak
指令 - 解决该问题的原理:先隐藏,替换好值之后再显示最终的值
<!-- v-cloak指令的用法
1. 提供样式
[v-cloak]{
display: none
}
2. 在插值表达式所在的标签中添加v-cloak指令
原理:先通过样式隐藏内容,然后在内存中进行值的替换,替换好之后再显示最终的结果
-->
<style>
[v-cloak]{
display: none
}
</style>
<div id="app" v-cloak>{{msg}}</div>
<script>
var vm = new Vue({
el: '#app', // 把数据填充到哪个位置
data: {
msg: 'Hello Vue'
}
});
</script>
- 数据绑定指令
-
v-text
填充纯文本- 相比差值表达式更加简洁
-
v-html
填充HTML片段- 存在安全问题,容易导致XSS攻击
- 本网站内部数据可以使用,来自第三方的数据不可以用
-
v-pre
填充原始信息- 显示原始信息,跳过编译过程(分析编译过程)
-
<div id="app">
<div v-text="msg"></div>
<div v-html="msg1"></div>
<div v-pre>{{msg}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello Vue',
msg1: '<h1>HTML</h1>'
}
});
</script>
Vue使用
-
数据响应式
- 如何理解响应式?
- html5中的响应式(屏幕尺寸的变化导致样式的变化)
- 数据的响应式(数据的变化导致页面内容的变化)
- 什么是数据数据绑定
- 数据绑定:将数据填充到标签中
-
v-once
只编译一次- 显示内容之后不再具有响应式功能
// v-once使用场景:如果显示的信息后续不需要再修改,就可以使用v-once,这样可以提高性能
- 如何理解响应式?
-
双向数据绑定
v-model
- 什么是双向数据绑定
<input type="text" v-model="uname"/>
- MVVM设计思想(M(module) V(view) VM(View-Module))
- 什么是双向数据绑定
-
事件绑定
- v-on指令用法
<input type="button" v-on:click="num++"/>
- v-on简写形式
<input type="button" @click="num++"/>
- v-on指令用法
-
事件函数的调用方式
- 直接绑定函数名称
<button v-on:click='say'>Hello</button>
- 自带事件对象
- 调用函数
<button v-on:click='say()'>Hello</button>
- 事件函数参数传递:普通参数和事件对象
<button v-on:click='say("hi", $event)'>Hello</button>
- 直接绑定函数名称
-
事件修饰符
-
.stop
阻止冒泡<a v-on:click.stop="handle">跳转</a>
-
.prevent
阻止默认行为<a v-on:click.prevent="handle">跳转</a>
-
.self
只有当前元素自身触发时才会触发这个函数
-
-
按键修饰符
-
.enter
回车键<input v-on:keyup.enter="submit">
-
.delete
删除键<input v-on:keyup.delete="handle">
-
-
自定义按键修饰符
- 全局
config.keyCodes
对象Vue.config.keyCodes.f1 = 112
- 规则:自定义修饰符的名字是自己定义的,但是对应的值必须是案件对应的
event.keyCode
值
- 全局
-
Vue如何动态处理属性?
-
v-bind
指令用法<a v-bind:href='url'>跳转</a>
- 缩写形式
<a :href='url'>跳转</a>
-
-
v-model
的底层原理分析<input v-bind="msg" v-on:input="msg=$event.target.value">
<div id="app"> <div>{{name}}</div> <input type="text" v-bind:value="name" v-on:input='handle'> <input type="text" v-bind:value="name" v-on:input='name=$event.target.value'> <input type="text" v-model="name"> </div> <script> let vm = new Vue({ el:'#app', data:{ name:"myVue" }, methods: { handle: function(event) { this.name = event.target.value; } } }); </script>
-
样式绑定
- class样式处理
- 对象语法
<div v-bind:class="{ active: isActive }"></div>
- 数组语法
<div v-bind:class="[activeClass, errorClass]"></div>
- 样式相关语法细节:
- 对象绑定和数组绑定可以结合使用
- class绑定的值可以简化操作
- 默认的class如何处理
- 对象语法
- style样式处理
- 对象语法
<div v-bind:style="{ color: activeColor, fontSize: fontSize }"></div>
- 数组语法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
- 对象语法
- class样式处理
```html
<style>
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
.error{
background-color: orange;
}
</style>
<div id="app">
<button v-on:click="handle">切换</button>
<div v-bind:class="{active: isActive,error: isError}">{{name}}</div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
name: "myVue",
isActive: true,
isError:true
},
methods: {
handle: function () {
this.isActive=!this.isActive;
this.isError=!this.isError;
}
}
});
</script>
```
```html
<style>
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
.error{
background-color: orange;
}
</style>
<div id="app">
<button v-on:click="handle">移除</button>
<div v-bind:class="[activeClass, errorClass]">{{name}}<div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
name: "myVue",
activeClass:'active',
errorClass:'error'
},
methods: {
handle: function () {
this.activeClass = '';
this.errorClass = '';
}
}
});
</script>
```
```html
<div id="app">
<button v-on:click='handle'>切换</button>
<div v-bind:style='{border: borderStyle, width: widthStyle, height: heightStyle}'>{{name}}</div>
<div v-bind:style='objStyle'></div>
<div v-bind:style='[objStyle, overrideStyle]'></div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
name: "myVue",
borderStyle: '1px solid blue',
widthStyle: '100px',
heightStyle: '150px',
objStyle: {
border:'1px solid green',
width: '150px',
height: '100px'
},
overrideStyle: {
border: '5px solid orange',
backgroundColor: 'blue'
}
},
methods:{
handle: function() {
this.heightStyle = '100px';
this.objStyle.width = '100px';
}
}
});
</script>
```
-
分支循环结构
- v-if:控制元素是否渲染到页面
- v-else
- v-else-if
- v-show:控制元素是否显示(已经渲染到页面)
<div id="app"> <div v-if='score>=90'>优</div> <div v-else-if='score<90&&score>=80'>良</div> <div v-else-if='score<80&&score>=60'>可</div> <div v-else>差</div> <!-- v-show的原理: 控制元素样式是否显示 --> <div v-show='flag'>测试v-show</div> <button v-on:click='handle'>点击</button> </div> <script> let vm = new Vue({ el:'#app', data:{ name:"myVue", score:99, flag: true }, methods:{ handle: function() { this.flag = !this.flag; } } }); </script>
-
循环结构
- v-for遍历数组
<li v-for='item in list'>{{item}}</li>
<li v-for='(item,index) in list'>{{item + '---' + index}}</li>
- key的作用:帮助Vue区分不同的元素,从而提高性能
<li :key='item.id' v-for='(item,index) in list'>{{item}} + '---' {{index}}</li>
- v-for遍历对象
<li v-for='(value, key, index) in object'></li>
- v-if和v-for结合使用
<li v-if='value==12' v-for='(value, key, index) in object'></li>
- v-for遍历数组
Vue常用特性
-
表单操作
- input 单行文本
- textarea 多行文本
- select 下拉多选
- radio 单选框
- checkbox 多选框
- 表单域修饰符:
- number:转化为数值
<input v-model.number="age" type="number">
- trim:去掉开始和结尾的空格
- lazy:将input时间切换为change事件
-
自定义指令
为何需要自定义指令? 内置指令不满足需求
-
自定义指令的语法规则(获取元素焦点)
// 自定义指令 Vue.directive('focus' ,{ inserted: function (el) { // 获取元素的焦点 el.focus(); } })
-
自定义指令的用法
<input type="text" v-focus>
钩子函数
-
钩子函数参数:
-
el
:指令所绑定的元素 -
binding
:一个对象,包含以下属性:-
name
:指令名,不包含v-
前缀 -
value
:指令绑定的值 - ...
-
-
vnode
:Vue生成的虚拟节点 -
oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用
-
<input type="text" v-color='{color:"orange"}'> <script> // 带参数的自定义指令 Vue.directive('color'. { inserted: function(el, binding) { el.style.backgroundColor = binding.value.color; } }) </script>
-
局部指令:如果想要注册局部指令,组件中也接受一个
directive
的选项:directive: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } }
-
计算属性
为何需要计算属性?表达式的计算逻辑可能会比较复杂,使用计算属性可以是模板内容更加简洁
-
计算属性用法:
computed: { reversedMessage: function () { return this.msg.split('').reverse().join() } }
-
计算属性和方法的区别:
- 计算属性是基于它们的依赖进行缓存的
- 方法不存在缓存
-
侦听器
侦听器应用场景:数据变化时执行异步或开销比较大的操作
-
侦听器的用法
watch: { firstName: function (val) { // val变化之后的值 this.fullName = val + this.lastName; }, lastName: function (val) { this.fullName = this.firstName + val; } }
-
过滤器
作用:格式化数据,比如将字符串格式化为首字母大写,将日期格式转化为指定的格式等
-
自定义过滤器
Vue.filter('过滤器名称', function(value) { // 过滤器业务逻辑 })
-
过滤器的使用:
<div>{{msg | upper}}</div> <div>{{msg | upper | lower}}</div> <div v-bind:id="id | formatId"></div>
-
局部过滤器
filters: { capitalize: function() {} }
<div id="app"> <h1>{{name}}</h1> <input type="text" v-model="msg"> <div>{{msg | upper}}</div> <div>{{msg | upper | lower}}</div> <div :abc="msg | upper">测试数据</div> </div> <script> // Vue.filter('upper', function (val) { // return val.charAt(0).toUpperCase() + val.slice(1); // }); Vue.filter('lower', function (val) { return val.charAt(0).toLowerCase() + val.slice(1); }) let vm = new Vue({ el: '#app', data: { name: "myVue", msg: '' }, filters:{ upper: function(val) { return val.charAt(0).toUpperCase() + val.slice(1); } }, methods: { } }); </script>
-
带参数的过滤器
<div>{{data | format('yyy-MMM-dd')}}</div> <script> Vue.filter('format', function(value, arg1) { // value就是过滤器传递过来的参数 })
-
生命周期
- 挂载(初始化相关属性)
-
beforeCreate
在实例初始化之后数据观测和事件按配置之前被调用 -
created
在实例创建完成后被立即调用 -
beforeMount
在挂载开始之前被调用 -
mounted
el被新创建的vm.$el
替换,并挂载到实例上去之后调用该钩子
-
- 更新(元素或组件的变更操作)
-
beforeUpdate
数据过呢更新时被调用,发生在虚拟DOM打补丁之前 -
updated
由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
-
- 销毁(销毁相关属性)
-
beforeDestroy
实例销毁之前调用 -
destroyed
实例销毁后调用
-
- 挂载(初始化相关属性)