介绍 — Vue.js
vscode必装插件:vuetr 和 Vue 2 snippets
为了方便调试,我们还应该安装官方浏览器插件devtools
https://github.com/vuejs/vue-devtoolsgithub.com
安装要翻墙,安装好后进入调试工具,找vue标签
小贴士合集:
每个 Vue 应用都是通过用Vue函数创建一个新的Vue 实例开始的
只有当实例被创建时就已经存在于data中的属性才是响应式的。
不要在选项属性或回调上使用箭头函数 (this问题)
v-on: 可以缩写为 @
v-bind: 可以缩写为 :
v-bind:class指令也可以与普通的 class 属性共存。
不推荐同时使用v-if和v-for
将计算属性computed里的函数取名为名词,当属性来调用
组件中使用v-for时,key属性是必须的
key必须使用v-bind来绑定,key必须是string或者number
v-on绑定的方法如果有参数,必须传参
为了与ES6风格统一,v-for="value in object"也可以写成v-for="value of object"
注册自定义组件时不建议使用驼峰命名法,驼峰命名法会自动转为 - 命名法
组件里的data必须是传入一个function,function里面再return对象出来
子组件props里的数据不要和子组件的表单做双向数据绑定!
最好不要在插槽上绑定vue指令,可以在其外面包一个div绑上
一. 概述
1.单页面应用程序 SPA
经典的多页面: 不同页面都是独立的页面(有利于搜索引擎,前后端融合)
现代式的单页面:不同网页其实是一个页面,只是在刷新区别内容 (只需要加载局部视图,用户体验好,不好兼容到低版本IE,所以诞生了一堆的开发框架,前后端分离,没有服务端渲染,服务端不再关心视图)
例如:https://music.163.com/ 不管页面怎么刷新,上面的导航条和下面的音乐播放条都不会刷新
2. 多页面的价值 //以服务端为主导,前后端混合
以服务端为主
有利于搜索引擎SEO
3.单页面的价值 //前后端分离
前后端分离,前后端通过接口交互,服务端不关心页面
不好兼容到低版本IE
没有服务端渲染
单页是肯定要使用框架的,比如 ract vue
4.前后端分离
项目立项
需求分析
服务端工作:
需求分析
设计数据库
接口设计(前端也参与)
数据处理及接口开发
前端工作
需求分析
页面搭建
页面功能制作
通过接口和服务器进行交互
5. vue简介
vue可以轻松构建SPA
通过指令扩展了HTML,通过 表达式 绑定数据到HTML
最大程度的解放DOM操作
vue特性:
MVVM
双向数据绑定
组件化
渐进式
Vue不支持IE8 及以下版本
6.MVC和MVVM的概念
mvc是后端分层的概念 m 数据库层 v 视图层 c控制层
MVVM是前端视图层的概念,主要关注于 模型 视图模型 视图
二. vue的安装和hello world
1.安装
也可以指定版本(推荐生产环境这样用)
还没有npm下载
$ cnpm install vue --save
2. hello world
Document
{{ 1+2 }}
{{ 'hello world'}}
{{message}}
{{lolo}}
在此,我们可以先把vue看作一个模板引擎,
data中的数据不是一般的数据,而是响应式数据,
响应式数据是一种数据驱动视图的思想,MVVM
el不要作用在html或body节点上
3. vue对象和其选项
(1) vue对象
每个 Vue 应用都是通过用Vue函数创建一个新的Vue 实例开始的
(2) data属性 (Vue的选项)
data其实Vue对象的一个属性,我们也可以称之为Vue的选项,那么vue有多少选项呢?
我们简单的看一下API就知道了
API — Vue.js
目前,我们只看最常用的选项.
当一个 Vue 实例被创建时,它将data对象中的所有的属性加入到 Vue 的响应式系统中。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。当这些数据改变时,视图会进行重渲染。
值得注意的是只有当实例被创建时就已经存在于 data 中的属性才是响应式的。也就是说如果你添加一个新的属性,比如:
vm.b = 'hi'
那么对 b 的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值。
除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。例如:
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
(3) methods
v-on 引用的函数都写在这个集合里
methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的this自动绑定为 Vue 实例。
(4) computed 计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。
这时候我们用到计算属性,他算是一种带有计算行为的属性,我们应该把他当作属性来调用
computed里的内容实质是方法,但不能当方法来调用,相较于方法,其特点是可以缓存计算结果
建议computed里的函数取名为名词,当属性来调用
例如:
{{ message.split('').reverse().join('') }}
但当计算复杂度高的时候,我们可以封装计算过程
"{{ reversed }}"
const app = new Vue({
el: '#app',
data: {
message:'hello world'
},
computed:{
reversed:function(){
return this.message.split('').reverse().join('')
}
}
})
双向绑定计算属性
每个计算属性其实都可以有自己的get和set属性. 如果设置了这两个属性,那么计算属性既可以get取值也可以set传值 (a=计算属性 计算属性=a)
只是默认只有 getter ,当你为其传入一个函数时,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
也会相应地被更新。
如果有一个计算属性是既可以get又可以set的,那么它完全可以双向绑定
例子:
如果我们想实现上图中的 全选联动 可以
computed: {
allDone:{
get:function(){
return this.todos.every(todo=>todo.done==true)
},
set:function(value){
todos.forEach(todo => {
todo.done=value
});
}
}
v-model绑定计算属性allDone, 这样就完成了联动,
当我们点击下面的按钮时,会改变this.todos.every(...)的值,这个值会通过计算属性allDone的getter改变顶部checkbox的勾选状态.
同时,我们点击checkbox改变勾选状态时,会触发allDone的setter 从而改变下面的todo的done状态
使用计算属性实现过滤
data: {
todos: JSON.parse(window.localStorage.getItem('todos') || '[]'),
filterText: 'all'
},
computed: {
filterTodos() {
switch (this.filterText) {
case 'done':
return this.todos.filter(todo => todo.done)
break;
case 'undone':
return this.todos.filter(todo => !todo.done)
break;
default:
return this.todos
break;
}
}
},
(5) watch 侦听属性 //用来监听属性的变化
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。
计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。
下例会侦听message的数据变化并触发方法
watch默认又两个参数;可以直接在函数中接收
newValue 属性的新值
oldValue 属性的旧值
Document
深度监视
watch监视对象只能监视一层,如果对象中还有子对象,则需要使用深度监视
如下面的例子C
var vm = new Vue({
data: {
a: 1,
b: 2,
c: 3,
d: 4,
e: {
f: {
g: 5
}
}
},
watch: {
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},
// 方法名
b: 'someMethod',
// 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 该回调将会在侦听开始之后被立即调用
d: {
handler: 'someMethod',
immediate: true
},
e: [
'handle1',
function handle2 (val, oldVal) { /* ... */ },
{
handler: function handle3 (val, oldVal) { /* ... */ },
/* ... */
}
],
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ }
}
})
vm.a = 2 // => new: 2, old: 1
(6) filters 过滤器
详见本系列第四篇第一节
(7) directives 自定义私有指令
详见本系列第三篇第一节
三. 生命周期函数
vue对象的生命周期:
1.创建期间的钩子函数
(1) beforeCreated
vue对象创建完成时触发, 还不能访问data和methods
(2)created
vue对象初始化完成时触发
created钩子可以用来在一个实例被创建之后执行代码 可以访问data和methods了
(3) beforeMounted
模板编译完成,在内存中,还没有挂载到页面中去时触发 //{{msg}}还是花括号
(4) mounted
模板编译完成,挂载到了页面中去时触发 //{{msg}}已经被替换成了this.msg的内容
2. 运行期间的钩子函数
(1)beforeUpdated
data数据改变,渲染到页面之前触发
(2)updated
data数据改变并渲染到页面之后触发
3. 销毁阶段
(1)beforeDestroyed
(2)destroyed
四. vue基本语法
1.条件
(1) v-if
v-if指令用于条件性地渲染一块内容。
现在你看到我了
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
也可以用v-else添加一个“else 块”:
Vue is awesome!
Oh no
还有v-else-if,顾名思义,充当v-if的“else-if 块”,可以连续使用
(2) 如何一次性判断多个元素?
因为v-if是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个元素当做不可见的包裹元素,并在上面使用v-if。最终的渲染结果将不包含元素。
(3) 元素复用问题
① 什么是元素复用
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:
那么在上面的代码中切换loginType将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,不会被替换掉——仅仅是替换了它的placeholder。
② 如何禁用元素复用
所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的key属性即可
(4) v-show
v-show指令和v-if用法基本一样
但是v-if用法是“真正”的条件渲染,v-show总是被渲染,只是简单地基于 CSS 进行切换。
2.循环
(1) v-for
- {{ todo.text }}
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: '学习 JavaScript' },
{ text: '学习 Vue' },
{ text: '整个牛项目' }
]
}
})
(2) 第二个参数 index
v-for 还支持一个可选的第二个参数,即当前项的索引。
- {{ parentMessage }} - {{ index }} - {{ item.message }}
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
(3) v-for遍历对象的属性
你也可以用 v-for 来遍历一个对象的属性。想循环谁就挂在谁身上
- {{ value }}
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
注意:为了与ES6风格统一,v-for="value in object"也可以写成v-for="value of object"
你也可以提供第二个的参数为 property 名称 (也就是键名):
{{ name }}: {{ value }}
你也可以提供第三个的参数为 index 名称 (也就是索引值):
{{ name }}: {{ value }} 索引值{{index}}
(4) 迭代数字
{{ count }}
(5) 绑定key属性
由于Vue虚拟dom机制问题, 给v-for的标签 绑定key之后会提升性能
组件中使用v-for时,key属性是必须的!!
key必须使用v-bind来绑定,key必须是string或者number 但不要绑定第三个参数 index(由于虚拟DOM算法问题,这样做无意义)
没有key会有什么问题? 如下图:我们尝试从数组的头部加项时,会出现r如下问题.这种问题靠key可以解决
五. vue基本列表渲染
表单输入绑定 — Vue.jscn.vuejs.org
1. 表单双向数据绑定 用v-model绑定
双向数据绑定,在表单中添加属性v-model=xxx即可
Document
{{message}}
2. 表单数据单向绑定 //值绑定 v-bind:value
v-bind可以用来动态绑定属性值, 可以把组件的value绑定任意内容或对象.但是这是单项的绑定,data里的值只会影响视图中的值,但视图中的值不会影响data
其值改变时,data里的message会改变,进而下面的标签值亦变
其值改变时,data里的message不会改变
当有v-bind:value时,组件的value失效
3. selected下拉单选框 //用v-model绑定 ,同时 option里设置好value或者v-bind:value
用v-model绑定select ,同时 option里设置好value,
如果没有设置value则 value=选项文本内容
Selected: {{ selected }}
new Vue({
el: '...',
data: {
selected: ''
}
})
如果v-model表达式的初始值未能匹配任何选项,
例子:计算器
Document
{{answer}}
4. selected下拉多选框 //用v-model绑定 ,同时 option里设置好value或者v-bind:value 数组接收
和上面基本一致,但是
Selected: {{ selected }}
数组接收
new Vue({
el: '#example-6',
data: {
selected: []
}
})
5.checkbox单个check框 用v-model
例:
Document
{{box1}}
6.checkbox单个check框 值绑定 //用v-model绑定,同时复选框里设置好true-value和false-value
Document
{{box1}}
7. checkbox多个check框 //用v-model绑定,同时每个复选框里设置好value或者v-bind:value,数组接收
Checked names: {{ checkedNames }}
可能接收到多个数据,故用数组表示
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})
8.单选按钮 //用v-model绑定同一个data,同时每个单选框里设置好value或者v-bind:value
Picked: {{ picked }}
new Vue({
el: '#example-4',
data: {
picked: ''
}
})
9.修饰符
(1) .lazy
在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加lazy修饰符,从而转变为使用change事件进行同步:
(2) .number
如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符:
(3) .trim
如果要自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符:
六. 事件处理
可以用v-on指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
v-on:有一个简写:@
v-on:click 等价于 @click
1.注册点击事件 用v-on:click="clickfunc"
vue对象本身包含mothod属性 ,可以把方法声明在其中
注意:方法不能用箭头函数,剪头函数的this不指向vue 实例
但可以使用另一种ES6写法:
func1:function (){} 可以简写成 func1(){}
Document
2.(内联版)注册点击事件 用v-on:click="count++"
如果函数执行简单可以直接内联写
三元表达式也可以写内联
Document
3.修饰符
在事件处理程序中调用event.preventDefault()或event.stopPropagation()是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为v-on提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop //停止冒泡
.prevent //阻止默认事件
.capture //采用捕获机制触发事件(反向冒泡,先触发外层的再触发内层的)
.self // 只有自己能触发,冒泡不会触发,但还是会继续往上冒泡
.once // 只触发一次
.passive //
.native // 如果是一个自定义组件,那么给它绑定事件时必须加.native
...
...
...
这个 .passive 修饰符尤其能够提升移动端的性能。
不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个
警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用v-on:click.prevent.self会阻止所有的点击,而v-on:click.self.prevent只会阻止对元素自身的点击。
4. 按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为v-on在监听键盘事件时添加按键修饰符:
Vue 提供了绝大多数常用的按键码的别名:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
除了上述按键码别名,也可以用 按键码来修饰
//113代表F2
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta
.exact
Do something
5.鼠标修饰符
.left
.right
.middle
这些修饰符会限制处理函数仅响应特定的鼠标按钮。
6.事件对象
事件方法会默认传入一个参数,event
我们编写方法时可以直接接收这个event
handleIn(e){
console.log(e);
},
此时,我们得到一个event对象
这个事件里有好多信息,后续我们会应用.
但是 , 如果调用函数里面有形参,这个参数是不会默认传递的,如果想既传参又传event 则需要在调用时强烈的声明!!!!并在写函数时做好形参接收工作!
handleIn(index,e){
}