- Object.freeze()
Object.freeze()用于冻结对象,冻结后对象元素不能被删除,修改,添加新的元素,基本做到了唯一性,但如果冻结的元素中存在对象时,对象的元素并不会冻结,任然可以被修改等操作,就是涉及到内存空间的问题了。
由于 JavaScript 的限制,Vue 不能检测以下数组的变动
出现这种问题的主要原因是,vue对数组进行了区别对待,并没有如同object那样,对数据内容做深层的数据劫持,与监听(应为大多数数据都是用来遍历的,同时数据量一般都非常大,做深层次的数据劫持与监听,将耗费很大的性能,似乎也完全没有必要),但为了实现数据的双向绑定,对Array的push,pop,shift,unshift,splice,sort,reverse方法做了处理,同时提供了$set方法,实现数组内部变量的双向绑定,当然是用原数组替换的方式也可以达到你想要的效果,使用filter,concat,slice等方法。
备注:源码中就明确的写了相关方法处理。
// v2.5.21
/*
* not type checking this file because flow doesn't play well with
* dynamically accessing methods on Array prototype
*/
import { def } from '../util/index'
const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)
const methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
/**
* Intercept mutating methods and emit events
*/
methodsToPatch.forEach(function (method) {
// cache original method
const original = arrayProto[method]
def(arrayMethods, method, function mutator (...args) {
const result = original.apply(this, args)
const ob = this.__ob__
let inserted
switch (method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
if (inserted) ob.observeArray(inserted)
// notify change
ob.dep.notify()
return result
})
})
- v-model
适用于基础组件的编写
<input v-model="searchText">
等价于
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
- input修饰符 .lazy .number .trim
v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。
你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步
<input v-model.lazy="msg" >
自动将用户的输入值转为数值类型
<input v-model.number="age" >
自动过滤用户输入的首尾空白字符
<input v-model.trim="name" >
- 事件修饰符.once
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
- 事件名命名注意事项
v-on
事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent
将会变成 v-on:myevent
——导致 myEvent
不可能被监听到。
- 关于.native和$listeners的使用场景
.native适用于父组件给子组件添加根节点上的事件监听,如果子组件的根节点非想监听的目标元素,这是#listener就能提供帮助。
$listeners旨在为父组件提供,在子组件上任意节点的事件监听,特别使用于复杂的子组件结构。
// 官网例子
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
computed: {
inputListeners: function () {
var vm = this
// `Object.assign` 将所有的对象合并为一个新对象
return Object.assign({},
// 我们从父级添加所有的监听器
this.$listeners,
// 然后我们添加自定义监听器,
// 或覆写一些监听器的行为
{
// 这里确保组件配合 `v-model` 的工作
input: function (event) {
vm.$emit('input', event.target.value)
}
}
)
}
},
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on="inputListeners"
>
</label>
`
})
- .sync的使用
子组件使用$emit传递参数
this.$emit('update:title', newTitle)
父组件使用update更新参数
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
而.sync相当于父组件update的简写
v-bind:title.sync="doc.title"
注意:使用修饰符sync,其参数只能是变量,而非表达式('' || doc.title)
- 作用域插槽v-slot
<current-user>
<h5>插槽</h5>
<template v-slot:person>person.firstName</template>
<template v-slot:user>{{user.firstName}}</template>
</current-user>
<current-user v-slot:user="users">
<h5>插槽变量传递</h5>
{{users.firstName}}
</current-user>
<div>
<h5>非作用域插槽参数</h5>
<current v-slot="users">
{{users.firstName}}
</current>
</div>
<current v-slot="{users}">
<h5>作用域插槽参数</h5>
{{users.firstName}}
</current>
<current v-slot="{users: person}">
<h5>作用域插槽参数名变换</h5>
{{person.firstName}}
</current>
<current v-slot="{ persons = { firstName: 'Peterss' } }">
<h5>作用域插槽参数自我赋值</h5>
{{persons.firstName}}
</current>
<current-prop v-slot="{users}" :userp="user">
<h5>作用域插槽prop用于传递参数</h5>
{{users.firstName}}
</current-prop>
- ref获取组件的属性
<base-input ref="usernameInput"></base-input>
this.$refs.usernameInput
来获取一些相关的操作
- emit在组件上的特殊运用
组件
<prop v-medol="info"></prop>
相当于
<prop :value="info" @input="info = $event"></prop>
所以一般会监听value 使用 $emit('input', val) 更新参数
参考文献: