Vue简介
Vue
是一套用于构建用户界面
的前端框架。
vue的两个特性
(1)数据驱动视图
- 在使用vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构。
- 当页面数据发生变化的时候,会自动重新渲染(数据的变化会驱动视图自动更新)
- 数据驱动视图是单向的数据绑定
(2)双向数据绑定
- 双向数据绑定可以辅助开发者在不操作DOM的前提下,自动把用户填写的内容同步到数据源中。
- 数据源发生变化,会被自动渲染到页面中
- 页面上表单采集的数据发生变化时,会被vue自动获取到,并更新到js数据中。
MVVM
MVVM
(Model View ViewModel)
是vue实现数据驱动视图
和双向数据绑定
的核心原理。
它把html页面拆分成了三个部分:
Model
表示当前页面渲染时所依赖的数据源
View
表示当前页面所渲染的DOM结构
ViewModel
表示vue的实例,它是MVVM的核心
MVVM的工作原理
ViewModel作为MVVM的核心,它把当前页面的数据源(Model)和页面的结构(View)连接在了一起。
- 当数据源发生变化的时候,会被ViewModel监听到,VM会根据最新的数据源更新页面的结构。
- 当表单元素的值发生变化时,也会被VM监听到,VM会把变化过后的最新的值同步到Model数据源中。
Vue的使用
Vue的基本使用
<!-- 1. 导入vue.js的script脚本文件(导入后,window全局中就有了Vue这个构造函数) -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2. 在页面中声明一个将要被vue所控制的DOM区域 -->
<div id="app">{{username}}</div>
<script>
// 3.创建vue的实例对象
const vm = new Vue({
el: '#app',
data: {
username: '关羽'
}
})
</script>
el
: 指定vm实例控制页面哪个区域(值是一个选择器)data
: 指定Model数据源(就是要渲染到页面上的数据)
1.Vue指令
1.内容渲染指令
用来渲染DOM元素的文本内容。
v-text
<p v-text="username"></p>
- 把username对应的值,渲染到标签p中
- v-text指令的缺点: 会覆盖掉元素内部原有的内容
{{}}
<p>姓名:{{username}}</p>
- 使用
{{}}差值表达式
将对应的值渲染到元素的内容中 - 差值表达式专门用来解决v-text覆盖默认文本内容的问题(只是内容的占位符)
v-html
<div v-html="info"></div>
- 如果要把包含html标签的字符串渲染为页面html元素,则需要使用到v-html
v-text和{{}}差值表达式只能渲染纯文本内容,v-html可以渲染含有标签的字符串。
2.属性绑定指令
如果需要为元素的属性动态绑定属性值,则需要用到v-bind属性绑定指令。
v-bind
<input type="text" v-bind:placeholder="tips">
- v-bind: 可以简写为
:
模板渲染语法中支持js语法
<div id="app">
<!-- v-text中使用js语法 -->
<p v-text="'username:'+username"></p>
<!-- 差值中使用js语法 -->
<div>1+1的结果: {{ 1+1 }}</div>
<div>num的值为: {{ num+1 }}</div>
<div>{{con}}翻转的结果是: {{ con.split('').reverse().join('') }}</div>
<!--v-bind中使用js语法-->
<!-- id=list3 -->
<div :id="'list' + index"></div>
</div>
3.事件绑定指令
vue提供了v-on事件绑定指令,可以为DOM元素绑定事件监听。
v-on:事件名称="事件的处理函数"
<button v-on:click="add">+1</button>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
add() {}
}
</script>
- v-on可以简写为
@
methods
中定义事件的处理函数
绑定事件并传参
<button v-on:click="add(2)">+1</button>
- 可以在绑定事件时,添加小括号进行传参
(1)事件对象$event
vue提供了内置变量$event
来表示事件对象e
,它就是原生DOM的事件对象e。
<button @click="add(1,$event)">+1</button>
- 如果事件没有传参,则事件处理函数中是有事件对象e的
- 如果事件传了参数,会覆盖掉事件对象e,methods中的add得到的就是我们传入的参数
- 如果我们在绑事件时,传参了而且还需要用到事件对象e,就可以用到$event
(2)事件修饰符
vue提供了事件修饰符的概念,让我们更方便的对事件的触发进行控制。
常见的5个事件修饰符:
.prevent
: 阻止默认行为.stop
: 阻止事件冒泡.capture
: 以捕获模式触发当前的事件处理函数.once
: 绑定的事件只触发一次.self
: 只有在even.target是当前元素自身时,触发事件处理函数
事件.事件修饰符
<a href="http://www.baidu.com" @click.prevent="show">跳转到百度首页</a>
(3)按键修饰符
在监听键盘事件时,我们经常需要判断详细的按键。此时可以用键盘相关的事件添加按键修饰符。
事件.按键修饰符
<input type="text" @keyup.enter="commit">
- 只有按下enter回车键的时候,才调用commit方法
4.双向绑定指令
v-model双向数据绑定,在不操作DOM的前提下,就可以快速的获取表单的数据。
v-model
<input type="text" v-model="username">
<script>
const vm = new Vue({
el: '#app',
data: {
username: '关羽',
}
})
</script>
- 当表单元素绑定了v-model,用户修改表单时,数据源也随之发生改变。当数据源发生改变时,重新渲染表单得到最新的值
- v-model在表单元素下使用。
v-model指令的修饰符
为了方便对用户输入的内容进行处理,vue为v-model指令提供了3个修饰符:
.number
: 自动将用户输入的值转换为数值类型.trim
: 自动过滤用户输入的首尾空白字符.lazy
: 表单数据在"change"时不需要"input"实时更新。就是表单数据变化时,不需要实时同步到data数据源,当完成时再同步,使用.lazy是可以优化性能的
<!-- 自动将用户输入的值转换为数值类型 -->
<input type="text" v-model.number="n1">+<input type="text" v-model.number="n2">=<span>{{n1+n2}}</span>
<!-- 自动过滤用户输入的首尾空白字符 -->
<input type="text" v-model.trim="username">
<!-- 表单数据在"change"时不需要"input"实时更新 -->
<input type="text" v-model.lazy="username">
5.条件渲染指令
条件渲染指令用来按需控制DOM的显示与隐藏,分别为: v-if,v-show。
v-if
<p v-if="flag">这是被 v-if 控制的元素</p>
- v-if原理: 每次动态
创建
或移除
元素,来实现元素的显示与隐藏
v-show
<p v-show="flag">这是被 v-show 控制的元素</p>
- v-show原理: 动态为元素创建或移除
display:none
样式,来实现元素的显示与隐藏。
两者的使用场景:
如果要频繁的切换元素的显示状态,v-show的性能会更好。
如果刚进入页面时,某些元素默认不需要被展示,而且后期可能也不需要被展示出来,此时v-if性能更好。
v-if的配套指令
v-else-if
<div v-if="type === 'A'">优秀</div>
<div v-else-if="type === 'B'">良好</div>
<div v-else-if="type === 'C'">一般</div>
<div v-else>差</div>
- v-else-if充当v-if的
“else-if块”
,可以连续使用 - v-else-if必须配合v-if指令使用,否则它将不会被识别
6.循环渲染指令
vue提供了v-for循环渲染指令,可以基于一个数组
来渲染一个列表结构
。
v-for
<tr v-for="(item,index) in list" :key="item.id">
<td>{{index}}</td>
<td>{{item.id}}</td>
<td>{{item.uname}}</td>
</tr>
- 要循环生成哪个DOM元素,就给这个DOM元素加上v-for
- v-for需要使用
item in items
形式的特殊语法 - items: 是待循环的数组;item: 是循环的每一项
- v-for指令还支持一个可选的第二个参数,即当前项的索引(index)。
- 官方建议只要用到了v-for命令,那么就一定要绑定一个
:key
属性并且尽量把id作为key的值 - key的值类型: 字符串或数字类型
- key的值是不能重复的(具有
唯一性
)
2.过滤器
Filter过滤器
常用于文本的格式化。过滤器可以用在两个地方: 差值表达式和v-bind属性绑定。
<div id="app">{{message | flt}}</div>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue.js'
},
// 定义过滤器
filters: {
flt(msg) {
const first = msg.charAt(0).toUpperCase()
const res = msg.slice(1)
// 过滤器中一定要有返回值
return first + res
}
}
})
</script>
- 过滤器添加到js表达式的尾部,通过
|(管道符)
进行调用。过滤器本身是函数,带有返回值。 - 过滤器函数必须定义到
filters
节点下 |
: 管道符,上一个表达式输出的结果作为下一个表达式的输入
扩展:
可以连续调用多个过滤器
{{ message | filter1 | filter2.. }}
过滤器可以接受参数
{{ message | filter1(arg1,arg2)}}
- 第一个参数永远都是管道符前面的值,第二个参数开始才是调用过滤器时传入的参数
(1)私有过滤器
在filters节点
下定义的过滤器为私有过滤器
,因为它只能在当前vm实例所控制的el区域
内使用。
(2)全局过滤器
如果希望实例之间共享过滤器,则可以定义全局过滤器。
Vue.filter('过滤器名',function(形参){})
<div id="app">
<p>{{message | flt}}</p>
</div>
<script>
Vue.filter('flt', function (res) {
const first = res.charAt(0).toUpperCase()
const other = res.slice(1)
return first + other
})
</script>
3.侦听器
watch侦听器
允许我们监视数据
的变化
,从而针对数据的变化做特定的操作。
<div id="app">
<input type="text" v-model="username">
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
username: ''
},
// 定义侦听器(所有侦听器都定义到watch节点下)
watch: {
username(newVal, oldVal) {
console.log('侦听到了username的值变化', newVal, oldVal)
}
}
})
</script>
-
要侦听哪个数据,哪个数据就作为方法名
-
newVal
是变化后的新值,oldVal
是变化前的旧值
1.方法格式的侦听器
<script>
const vm = new Vue({
el: '#app',
data: {
username: ''
},
watch: {
// watch侦听用户名是否被占用
username(newVal) { //
if (newVal === '') return
// 调用ajax请求,判断newVal是否被占用
$.get('https://www.escook.cn/api/finduser' + newVal, res => {
console.log(res)
})
}
}
})
</script>
- 要侦听data中的哪个数据,哪个数据就作为方法名
2.对象格式的侦听器
<script>
const vm = new Vue({
el: '#app',
data: {
username: ''
},
watch: {
// 对象格式的侦听器
username: {
handler(newVal, oldVal) {
console.log(newVal, oldVal)
},
immediate: true
}
}
})
</script>
immediate
选项的默认值是false- immediate的作用就是控制侦听器是否
自动触发
3.深度侦听
<div id="app">
<input type="text" v-model="info.username">
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
info: {
username: 'zs'
}
},
watch: {
// 侦听info对象
info: {
handler(newVal) {
console.log(newVal)
},
deep: true
},
}
})
</script>
deep
选项默认值为false- 设置deep选项,开启深度侦听,只要对象中的任何一个属性发生变化,都会触发对象的侦听器
方法格式的侦听器缺点:
- 无法在刚进入页面的时候,自动触发
- 如果侦听的是一个对象,对象中的的属性发生了变化,不会触发侦听器
对象格式的侦听器优点:
- 可以通过设置immediate选项,当进入页面时,就让侦听器自动触发
- 可通过设置deep选项,深度侦听对象中的每个属性的变化
4.计算属性
计算属性
指的是通过一系列运算之后,最终得到一个属性值,这个动态计算
出来的属性值可以被模板结构或methods方法使用。
计算属性的特点:
- 定义的时候,定义成方法格式。在使用计算属性的时候,当普通的属性来使用
计算属性的好处:
- 实现了代码的复用
- 只要计算属性中依赖的数据源发生变化,则计算属性会自动重新求值
用计算属性动态生成rgb这么一个字符串
<div class="box" :style="{ backgroundColor: rgb }">{{ rgb }}</div>
<button @click="show">按钮</button>
<script>
var vm = new Vue({
el: '#app',
data: {
r: 0,
g: 0,
b: 0
},
methods: {
show() {
console.log(this.rgb)
}
},
computed: {
rgb() {
return `rgb(${this.r},${this.g},${this.b})` // 返回生成rgb(x,x,x)字符串
}
}
});
console.log(vm) // 可以看到vm实例中有rbg属性
</script>
- 所有的计算属性定义在
computed
节点下