几个概念
1. 中文官网:Vue.js
2. VUE简单介绍
- Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
- 数据和 DOM 已经被建立了关联,所有东西都是响应式的。
- 一个 Vue 应用实例会将其挂载到一个 DOM 元素上,然后对其进行完全控制。
- 在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。
3. MVVM模型
- model:模型,数据对象,例如app实例中的data
- view:视图,模板页面,例如整个div
- viewModel:视图模型vue的实例,例如app实例对象
- 【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。
- 【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。
<div id="app">
{{ message }}
</div>
var app = new Vue({
//element:选择器字符串,对应到一个dom
el: '#app',
data: {
message: 'Hello Vue!'
}
})
4. 声明式编程、命令式编程以及函数式编程
- 声明式(Declarative)
- 告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。
- 只需要告知计算机我们声明了什么,无需关注他内部到底如何实现。
- Vue也通过这种开发模式,实现了数据与界面的分离。
- 命令式编程(Imperative)
- 命令“机器”如何去做事情(how),这样不管你想要的是什么(what)
- 以命令为主的,给机器提供一条又一条的命令序列让其原封不动的执行。
- JavaScript并非完全是命令式编程,只是在这一点上为命令式。
- 函数式编程(Functional)
- 函数式编程是声明式编程的一部分,因为他们思想是一致的:即只关注做什么而不是怎么做。
- 但函数式编程除了对声明式编程的相似处之外,同时他也利用了js函数能够作为参数传递的特点。
文本输出
- “Mustache”语法(大括号表达式):{{msg}}
- v-text="msg"
v-once
- 只执行一次,msg改变,页面不变
<span v-once>这个将不会改变: {{ msg }}</span>
html输出显示
- v-html="rawHtml"
- 绑定的内容将会被替换成为rawHtml的内容,渲染页面
- 动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS(跨站脚本攻击) 攻击
强制绑定
- v-bind:xxx="msg"
- Mustache 语法不能作用在 HTML attribute 上
- v-bind:xxx="msg"可以简写成:xxx="msg"
- v-bind绑定的值如果是 null、undefined 或 false,比如 disabled attribute 甚至不会被包含在渲染出来的 <button> 元素中。
<button v-bind:disabled="isButtonDisabled">Button</button>
事件监听
- v-on:click="method",可以简写成@click="method"
计算属性:computed
- 将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同
- 计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
- 只要
message
还没有发生改变,多次访问reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。调用方法将总会再次执行函数。
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
},
fullName3: {
// 当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
get () {
console.log('fullName3 get()')
return this.firstName + '-' + this.lastName
},
// 当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
set (value) {
console.log('fullName3 set()', value)
// 更新firstName和lastName
const names = value.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
}
}
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
侦听属性:watch
- 随着数据变动而做一些操作,与computed作用类似
- 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
watch: {
firstName: function (newVal,oldVal) {
this.fullName = newVal+ ' ' + this.lastName
},
lastName: function (newVal,oldVal) {
this.fullName = this.firstName + ' ' + newVal
}
}
绑定class和style
- class绑定: :class='xxx'
- xxx是字符串
- xxx是对象
- xxx是数组
- style绑定::style="{ color: activeColor, fontSize: fontSize + 'px' }"
<div id="demo">
<h2>1. class绑定: :class='xxx'</h2>
<p :class="myClass">xxx是字符串</p>
<p :class="{classA: hasClassA, classB: hasClassB}">xxx是对象</p>
<p :class="['classA', 'classB']">xxx是数组</p>
<h2>2. style绑定</h2>
<p :style="{color:activeColor, fontSize}">:style="{ color: activeColor, fontSize: fontSize + 'px' }"</p>
<button @click="update">更新</button>
</div>
new Vue({
el: '#demo',
data: {
myClass: 'classA',
hasClassA: true,
hasClassB: false,
activeColor: 'red',
fontSize: '20px'
},
methods: {
update () {
this.myClass = 'classB'
this.hasClassA = !this.hasClassA
this.hasClassB = !this.hasClassB
this.activeColor = 'yellow'
this.fontSize = '30px'
}
}
})
条件渲染:v-if
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。v-else
元素必须紧跟在带v-if
或者v-else-if
的元素的后面,否则它将不会被识别。v-else-if
类似于v-else
,也必须紧跟在带v-if
或者v-else-if
的元素之后。
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
<h1 v-show="ok">Hello!</h1>
条件渲染:v-show
- 与v-if不同的是带有
v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS propertydisplay
。 v-show
不支持<template>
元素,也不支持v-else
v-if vs v-show
v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。v-show
不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。- 一般来说,
v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show
较好;如果在运行时条件很少改变,则使用v-if
较好。
列表渲染:v-for
- 语法:可以用of替换in
- 数组:v-for="(item, index) in items" :key="唯一值"
- 对象:v-for="(value, key, index) in object" :key="唯一值"
- 数字:v-for="n in 10"
- 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一
key
attribute
变更方法:顾名思义,会变更调用了这些方法的原始数组。
- push():向数组的末尾添加一个或多个元素,并返回新的长度。
- pop():用于删除并返回数组的最后一个元素。
- shift():用于把数组的第一个元素从其中删除,并返回第一个元素的值。
- unshift():向数组的开头添加一个或更多元素,并返回新的长度。
- splice()
- 用于删除元素时,第一个参数是开始的位置,第二个参数传要删除的个数,如果第二个参数不传,会从开始的位置把后面的全部删除。
- 用于替换元素时, 第一个参数是开始的位置,第二个参数是要替换的个数,后面是要替换的内容
- 用于插入元素时,第一个参数是开始的位置,第二个参数传0,后面跟上要插入的内容
- sort():用于对数组的元素进行排序。
- reverse():用于颠倒数组中元素的顺序。
非变更方法:不会变更原始数组,而总是返回一个新数组。
- filter() :创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
- concat() :用于连接两个或多个数组。
- slice() :可从已有的数组中返回选定的元素。
- split() :用于把一个字符串分割成字符串数组。
过滤并排序示例:
computed: {
filterPersons () {
// 取出相关数据
const {searchName, persons, orderType} = this
let arr = [...persons]
// 过滤数组
if(searchName.trim()) {
arr = persons.filter(p => p.name.indexOf(searchName)!==-1)
}
// 排序
if(orderType) {
arr.sort(function (p1, p2) {
if(orderType===1) { // 降序
return p2.age-p1.age
} else { // 升序
return p1.age-p2.age
}
})
}
return arr
}
},