1.有关数组的变异方法可以实现响应式
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
无法实现响应式的非变异方法:例如:filter()
, concat()
和 slice()
。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:
注意事项:
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
- 当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
vm.items.length = newLength
举个例子:
|
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue
相同的效果,同时也将触发状态更新:
|
|
你也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set
的一个别名:
|
为了解决第二类问题,你可以使用 splice
:
|
对象更改检测注意事项
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
|
对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value)
方法向嵌套对象添加响应式属性。例如,对于:
|
你可以添加一个新的 age
属性到嵌套的 userProfile
对象:
|
你还可以使用 vm.$set
实例方法,它只是全局 Vue.set
的别名:
|
有时你可能需要为已有对象赋予多个新属性,比如使用 Object.assign()
或 _.extend()
。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:
|
你应该这样做:
|
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:
|
那么在上面的代码中切换 loginType
将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input>
不会被替换掉——仅仅是替换了它的 placeholder
。
自己动手试一试,在输入框中输入一些文本,然后按下切换按钮:
Username
Toggle login type
这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key
属性即可:
|
现在,每次切换时,输入框都将被重新渲染。请看:
Username
Toggle login type
注意,<label>
元素仍然会被高效地复用,因为它们没有添加 key
属性。
3.props在父组件HTML的变量要大写转换成(-小写字母)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<child :next-to="nextTo"></child>
//父组件数据绑定 不幸的是,由于 HTML 是大小写不敏感的,在 DOM 模板中必须仍使用next-to
</div>
<script>
Vue.config.debug = true;
Vue.component('child', {
props: ['nextTo'], //子组件接收数据
template: '<span>{{nextTo}}</span>' //子组件数据展示
});
var vm = new Vue({
el: '#app1',
data:{
nextTo:'eat' //父组件数据
}
})
</script>
<!--<script src="test2.js"></script>-->
</body>
</html>
4.Vue.component使用注意事项
Vue.component使用的时候并不是随便使用的,我们要遵循一个原则:
要在初始化根实例之前注册组件,例如;
HTML代码 :
<div id="example">
<my-component></my-component>
</div>
js代码:
// 注册
Vue.component('my-component', { //这里的Vue.component要放在根实例前面
template: '<div>A custom component!</div>'
})
// 创建根实例
new Vue({
el: '#example'
})
渲染结果
<div id="example">
<div>A custom component!</div>
</div>
5.自定义事件的事件名字大小写问题
跟组件和 prop 不同,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。举个例子,如果触发一个 camelCase 名字的事件:
this.$emit('myEvent') |
则监听这个名字的 kebab-case 版本是不会有任何效果的:
<my-component v-on:my-event="doSomething"></my-component> |
跟组件和 prop 不同,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on
事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent
将会变成 v-on:myevent
——导致 myEvent
不可能被监听到。
因此,我们推荐你始终使用 kebab-case 的事件名。