vue杂记
VUE杂记
声明式渲染
{{ message }}
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
v-bind 缩写:
鼠标悬停几秒钟查看此处动态绑定的提示信息!
var app2 = new Vue({
el: '#app-2',
data: {
message: '页面加载于 ' + new Date().toLocaleString()
}
})
v-if
现在你看到我了
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
v-for
{{ todo.text }}
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: '学习 JavaScript' },
{ text: '学习 Vue' },
{ text: '整个牛项目' }
]
}
})
v-on 缩写@click
{{ message }}
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
v-model
Vue 还提供了 v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。
{{ message }}
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
数据与方法
当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
// 我们的数据对象
var data = { a: 1 }
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
data: data
})
// 它们引用相同的对象!
vm.a === data.a // => true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3
当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时 data 中存在的属性才是响应式的。
如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值。
$data、$el、$watch
除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来
可以在 API 参考中查阅到完整的实例属性和方法的列表。
实例生命周期
比如 created 钩子可以用来在一个实例被创建之后执行代码:
new Vue({
data: {
a: 1
},
created: function () {
// this 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mounted、updated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例。
beforeCreate、created、beforeMount、mounted、BeforeUpdate、updated、beforeDestroy、destroyed
注意:
不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this 不会是如你所预期的 Vue 实例,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。
模板语法
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接写渲染 (render) 函数,使用可选的 JSX 语法。
插值
v-once
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:
Message: {{ msg }}
这个将不会改变: {{ msg }}
v-html
{{ rawHtml }}
注意,你不能使用 v-html 来复合局部模板,因为 Vue 不是基于字符串的模板引擎。反之,对于用户界面 (UI),组件更适合作为可重用和可组合的基本单位。
注意:
你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。
v-bind 用来绑属性
Mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind 指令
使用 JavaScript 表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
指令
指令 (Directives) 是带有 v- 前缀的特殊属性。指令属性的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。回顾我们在介绍中看到的例子:
现在你看到我了
这里,v-if 指令将根据表达式 seen 的值的真假来插入/移除
元素。
参数
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。
修饰符
修饰符 (Modifiers) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
计算属性和侦听器
计算属性
例子
Original message: "{{ message }}"
Computed reversed message: "{{ reversedMessage }}"
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// this 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。
计算属性缓存和方法的区别
计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
计算属性和watch的区别
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
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 也会相应地被更新。
侦听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。
当需要在数据变化时 执行异步 或开销较大的操作时,这个方式是最有用的。
Ask a yes/no question:
{{ answer }}
除了 watch 选项之外,您还可以使用命令式的 vm.$watch API。
Class 与 Style 绑定
-
直接绑对象
上面的语法表示 active 这个 class 存在与否将取决于数据属性 isActive
绑定多个class
data: {
isActive: true,
hasError: false
}绑定的数据对象不必内联定义在模板里:
data: {
classObject: {
active: true,
'text-danger': false
}
}返回对象的计算属性。这是一个常用且强大的模式:
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
} -
数组语法
我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:
data: {
activeClass: 'active',
errorClass: 'text-danger'
}如果你也想根据条件切换列表中的 class,可以用三元表达式:
不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:
-
绑定内联
v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名:
data: {
activeColor: 'red',
fontSize: 30
}直接绑定到一个样式对象通常更好,这会让模板更清晰:
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。
多重值
条件渲染
v-if v-else-if v-else
A
B
C
Not A/B/C
key
添加key就可以重新渲染,否则会复用
v-show
Hello!
不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
注意,v-show 不支持 元素,也不支持 v-else。
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。 var example1 = new Vue({ v-for中第二个参数index var example2 = new Vue({ 可以用v-for来遍历一个对象 new Vue({ 建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。 Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下: push() 例如:filter(), concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组: example1.items = example1.items.filter(function (item) { 注意: 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength vue都不能识别数组的变动 // Vue.set example1.items.splice(newLength) 可以用以上方法解决 有时,我们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性。 在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个 method 方法: var example2 = new Vue({ // 也可以用 JavaScript 直接调用方法 可以用event作形参,可以传$event 事件修饰符 .stop 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 @click.prevent.self 会阻止所有的点击,而 @click.self.prevent 只会阻止对元素自身的点击。 Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。 这个 .passive 修饰符尤其能够提升移动端的性能。 .enter .ctrl .exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。 .left Message is: {{ message }} 复选按钮 new Vue({ 单选按钮 选择框 多选 在自定义组件中使用这些受限制的元素时会导致一些问题,例如: 应当注意,如果使用来自以下来源之一的字符串模板,则没有这些限制: 这在有很多大模板的演示应用或者特别小的应用中可能有用,其它场合应该避免使用,因为这将模板和组件的其它定义分离了。v-if vs v-show的差别
列表渲染
v-for
{{ item.message }}
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
{{ parentMessage }} - {{ index }} - {{ item.message }}
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
{{ index }}. {{ key }}: {{ value }}
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
})数据更新检测
pop()
shift()
unshift()
splice()
sort()
reverse()
return item.message.match(/Foo/)
})
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)过滤/排序
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
事件处理
监听事件
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 methods 对象中定义方法
methods: {
greet: function (event) {
// this 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// event 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
example2.greet() // => 'Hello Vue.js!'
.prevent
.capture
.self
.once
按键修饰符
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
系统修饰键
.alt
.shift
.meta
<input @keyup.alt.67="clear">
<div @click.ctrl="doSomething">Do something
<button @click.ctrl="onClick">A
<button @click.ctrl.exact="onCtrlClick">A
<button @click.exact="onClick">A鼠标修饰符
.right
.middle表单输入绑定
Checked names: {{ checkedNames }}
el: '#example-3',
data: {
checkedNames: []
}
})
Picked: {{ picked }}
new Vue({
el: '#example-4',
data: {
picked: ''
}
})
Selected: {{ selected }}
new Vue({
el: '...',
data: {
selected: ''
}
})
Selected: {{ selected }}
new Vue({
el: '#example-6',
data: {
selected: []
}
})
组件
自定义组件
Vue.component('hello-world', {
template: '#hello-world-template'
})
浙公网安备 33010602011771号