该文章只是我对vue基础知识的一点总结,详细vue知识请看Vue官方文档。
一、什么是vue.js
是一个轻量级MVVM框架,数据驱动+组件化的前端开发。
数据驱动:数据响应原理——数据(model)改变驱动视图(view)自动更新。
-
组件化:扩展html元素,封装可重用代码。
组件设计原则
页面上每个独立的可视/可交互区域视为一个组件
每个组件对于一个工程目录,组件所需要的各种资源在这个目录下就近维护
页面不过是组件的容器,组件可以嵌套自由组合形成完整的页面
二、MVVM
响应式,双向数据绑定,即MVVM。是指数据层(Model)-视图层(View)-数据视图(ViewModel)的响应式框架。它包括:
1.修改View层,Model对应数据发生变化。
2.Model数据变化,不需要查找DOM,直接更新View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
三、vue基础
1、创建第一个vue实例
Vue入门
{{msg}}
运行结果:
-
挂载点,模板,实例之间的关系
一个 Vue 应用由一个通过
new Vue
创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。是vue实例的挂载点。vue只会去处理挂载点下面的内容。
挂载点内部的内容即为模板内容,如示例中的
{{msg}}
。也可以将模板内容放在vue实例中(template):
new Vue({
el:"#root",
template:'{{msg}}
',
data:{
msg:"hello world"
}
})
2、vue的生命周期
下面部分参考详解vue生命周期,可详细阅读该文章
生命周期函数就是vue实例在某一个时间点会自动执行的函数。
PS:其中created和mounted比较重要,一个是data数据和事件的初始化,一个是html模板,挂载渲染到页面完毕。
生命周期图示:下图展示了实例的生命周期。
Vue实例生命周期函数
{{message}}
控制台:
初始化实例:3、模板语法
- 插值
区别:v-text会转译,v-html不会转译
{{name}}
对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。注意:每个绑定都只能包含单个表达式。
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
{{ var a = 1 }}
{{ if (ok) { return message } }}
指令
事件绑定:
v-on
{{content}}
- 属性绑定:
v-bind
hello world
- 双向数据绑定:
v-model
{{content}}
-
v-if
,v-else
指令
hello world
bye world
- v-show指令
hello world
- v-for指令
- {{item}}
- 缩写
- v-bind
...
...
- v-on
...
...
4、计算属性、方法与监听器
-
计算属性
对于任何复杂逻辑,你都应当使用计算属性。
Original message: "{{ message }}"
Computed reversed message: "{{ reversedMessage }}"
结果:
Original message: "Hello"
Computed reversed message: "olleH"
-
计算属性缓存 vs 方法
我们可以通过在表达式中调用方法来达到同样的效果:
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now()
不是响应式依赖:
computed: {
now: function () {
return Date.now()
}
}
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
- 计算属性vs侦听属性
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
侦听属性有缓存,但是代码是命令式且重复的。
将它与计算属性的版本进行比较:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
-
计算属性的setter
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
// ...
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
// ...
现在再运行 vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和 vm.lastName
也会相应地被更新。
-
监听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。
当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
姓:
名:
{{fullName}}
{{count}}
5、class与style绑定
下面通过一个点击改变颜色例子来说明样式绑定。
- class的对象绑定
class的对象绑定
Hello world
- class的数组绑定
class的数组绑定
Hello world!
- style的对象绑定
Hello world!!
- style的数组绑定
Hello world!!!
6、条件渲染
v-if
,v-else
,v-show
基础知识详见上文指令部分。
-
在元素上使用
v-if
条件渲染分组当我们需要切换多个元素时,可以把一个
元素当做不可见的包裹元素,并在上面使用
v-if
。最终的渲染结果将不包含
元素。
Title
Paragraph 1
Paragraph 2
-
v-else-if
充当
v-if
的“else-if 块”,可以连续使用:
A
B
C
Not A/B/C
类似于 v-else
,v-else-if
也必须紧跟在带 v-if
或者 v-else-if
的元素之后。
-
用
key
管理可复用的元素Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
但有时我们并不需要这样的功能,如当我们在使用账号登录时,可以选择用户名登录和邮箱登录,而这两者的信息可能是不一样的,这时我们可以增加key使切换时输入的内容清空。如下面的例子:
用户名:
邮箱名:
7、列表渲染
- 用
v-for
把一个数组对应为一组元素
{{index}}----{{item.text}}----{{item.id}}
输出结果:
- 一个对象的
v-for
{{ index }}. {{ key }}: {{ value }}
输出结果:
当我们要在此基础上再加一个数据,在控制台中我们要重新定义该对象才能使页面改变。
vm.object={
firstName: 'John',
lastName: 'Doe',
age: 30,
address: 'hangzhou'
}
除此之外,我们还可以通过set方法向对象注入数据,同时页面更新。
方法一:Vue.set(vm.object,"address","hangzhou")
方法二:vm.$set(vm.object,"address","hangzhou")
-
变异方法
Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
-
非变异方法
filter()
,concat()
和slice()
。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
-
注意事项
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
1.当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
2.当你修改数组的长度时,例如:
vm.items.length = newLength
为了解决第一类问题,以下两种方式都可以实现和
vm.items[indexOfItem] = newValue
相同的效果,同时也将触发状态更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set 的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
- 为了解决第二类问题,你可以使用 splice:
vm.items.splice(newLength)