一、选项 / 数据
1.data
当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例,如果 data 仍然是一个纯碎的对象,则所有的实例将被共享引用同一个数据对象。通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
2.props
props 可以是数组或者对象,用于接收来自父组件的数据。props 中使用对象可以配置高级选项,类型检测,自定义验证,设置默认值
可以使用以下选项
type:可以是原生构造函数中的一种:String、Number、Boolean、Array、Object、Date、Function、Symbol、任何自定义构造函数,或上述内容组成的数组。会检查一个 prop 是否是给定的类型,否则抛出警告。
default:为 prop 指定一个默认值。如果该 prop 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回
required:Boolean 定义该 prop 是否是必填项
validator:function 自定义验证函数会将该 prop 的值作为唯一的参数带入。返回 false 就给默认值,控制台有警告
props: {
// 检测类型
height: Number,
// 检测类型 + 其他验证
age: {
type: Number,
default: 0,
required: true,
validator: function (value) {
return value >= 0
}
}
}
3.propsData
只用于 new 创建的实例中,创建实例时传递 props,主要作用时方便测试(开发的过程中基本用不到)
4.computed 计算属性
计算属性将被混入到 Vue 实例中,所有 geter 和 setter 的 this 上下文自动地绑定为 Vue 实例
注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。
计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖(必须非响应式 property)在该实例范畴之外,则计算属性是不会被更新的。
<p>a + b 的结果是:{{ count }}</p>
computed: { count(){ return this.a + this.b
}
}
计算属性 vs 方法
<p>a + b 的结果是:{{ count() }}</p>
methods: {
count(){
return this.a + this.b
}
}
我们可以将同一函数定义为一个方法而不是一个计算属性,两种方式的最终结果确实是完全相同的。不同的是计算属性是基于他们的响应式依赖进行缓存的。只在相应响应式依赖发生改变时他们才会重新计算求值。就是说只要 a 或者 b 还没有发生改变,多次访问 count 计算属性会立即返回之前的计算结果,而不必再次执行函数。
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数,
我们为什么需要缓存? 假设我们有一个性能开销比较大的计算属性 A,他需要遍历一个巨大的数组并做大量的计算,然后我们可能有其他的计算属性依赖于 A。如果没有缓存我们将不可避免的多次执行 A 的getter。如果不希望有缓存出现,请用方法代替。
计算属性的 setter
计算属性默认只有 getter ,不过在需要时也可以提供一个 setter
computed: {
str: {
get: function() {
return this.a + this.b
},
set: function(newVlaue) {
var abs = newValue.split(' ')
this.a = abs[0]
this.b = abs[abs.length - 1]
}
}
}
现在运行 this.str = '2 3 4 5'时,setter 会被调用,this.a 和 this.b 也会相应地被更新
5.methods 事件处理
在模板中通过 v-on 定义方法名,在 methods 中定义方法
有时在内联语句处理器中访问原始的 DOM 事件,可以用特殊变量 $event 把它传入方法
<button @click="count(200, $event)">按钮</button>
<button @click="count2">按钮2</button>
methods: {
count: function(val, event) {
if(event) {
event.preventDefault()
}
// ...
},
count2: function(event) {// 如果模板中什么都不传递,在这里可以默认直接接受一个参数就是 dom 对象
if(event) {
event.preventDefault()
}
// ...
}
}
6.watch 监听器
一个对象,键是需要观察的表达式,值是对应回调函数,值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性
值是包括选项的对象,有三个选项
handler:回调函数,即监听到变化时应该执行的函数
deep: Boolean,确认是否深度监听
为了发现对象内部值的变化,可以在选项参数中指定 deep: true 注意监听数组的变更不需要这么做
immediate:Boolean,为true时,将立即以表达式的当前值出发回调(进入页面就开始监听)
watch: {
a(){},
// 该回调会在任何被监听的对象 property 改变时被调用,不论其被嵌套多深
b: {
handler: function(){},
deep: true
},
// 该回调将会在侦听开始之后立即调用
c: {
handler: function(),
immediate: true
},
// 可以传入回调数组,他们会被一一调用
d: [
handle1,
function handle2(){},
{
handler: function handle3(){}
}
]
}
二、选项 / DOM
在开发的过程中很少需要考虑这些东西,看看官网熟悉一下
三、选项 / 生命周期钩子
每个 Vue 实例在被创建时都要经过一系列的初始化过程,设置数据监听,编译模板,实例挂载到 DOM ,数据变化时更新 DOM 等,这里面有一系列的函数,称之为生命周期钩子
1.beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用,此时组件的选项对象还没有创建,el 和 data 并未初始化,因此无法访问 methods,data,computed 等上的方法和数据
2.created
在实例创建完成之后被立即调用。这一步,实例已经完成以下配置:数据观测(data observer),property 和方法的运算,watch/event 事件回调。然而挂载阶段还没开始,$el property 目前尚不可用。这是一个常用的生命周期,这里面可以调用 methods 中的方法,改变 data 中的数据,并且修改可以通过 vue 的响应式绑定体现在页面上,获取 计算属性 等等,通常我们在这里请求接口中的数据,
3.beforeMount
在挂在之前被调用,相关的 render 函数首次被调用,实例已经完成一下的配置:编译模板,把 data 里面的数据和模板生成 html,完成了 el 和 data 初始化,注意此时还没有挂载到 html 页面上
4.mounted
实例被挂载后被调用,这时 el 被新创建的 vm.$el 替换了。如果跟实例挂载到了一个文档内的元素上,当 mounted 被调用时 vm.$el 也在文档内
注意 mounted 不会保证所有的子组件也一起被挂载,如果希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick
mounted(){
this.$nextTick(function(){
// ...
})
}
5.beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前,这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行
6.updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用 计算属性 或 watcher 取而代之。
注意 updated 不会保证所有子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick(同上)
7.activated
被 keep-alive 缓存的组件激活时调用
该钩子在服务器端渲染期间不被调用
8.deactivated
被 keep-alive 缓存的组件停用时被调用
该钩子在服务器端渲染期间不被调用
9.beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用
该钩子在服务器端渲染期间不被调用
10.destroyed
实例销毁后调用,该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁
该钩子在服务器端渲染期间不被调用
11.errorCaptured
当捕获一个来自子孙组件的错误时被调用,此钩子会收到三个参数:错误对象、发生错误的组件实例和一个包含错误来源信息的字符串。此钩子返回 false 以阻止该错误继续向上传播
可以在此钩子中修改组件的状态。因此在捕获错误时,在模板或渲染函数中有一个条件判断来绕过其他内容就很重要,不然该组件可能会进入一个无限的渲染循环
错误传播规则
1.默认情况下,如果全局的 config.errorHandler 被定义,所有的错误仍会发送它,因此这些错误仍然会向单一的分析服务的地方进行汇报。
2.如果一个组建的继承或父级从属链路中存在多个 errorCaptured 钩子,则它们将会被相同的错误一一唤起
3.如果此 errorCaptured 钩子自身抛出了一个错误,则这个新错误和原本被捕获的错误都会发送给全局的 config.errorHandler
4.一个 errorCaptured 钩子能够返回 false 以阻止错误继续向上传播。本质上是说’这个错误已经被搞定且应该被忽略‘。他会阻止其他任何会被这个错误唤起的 errorCaptured 钩子和全局的 config.errorHandler
四、选项 / 资源
1.directives 自定义指令
2.filters 过滤器
3.components 组件
directives、filters、components 详情在这里有介绍 vue API 知识点(1)---全局 API 总结
五、选项 / 组合
1.parent
指定已创建的实例之父示例,在两者之间建立父子关系。子实例可以用 this.$parent 访问父实例,子实例被推入到父实例的 $children 数组中
我们在开发中,基本上不会使用到 $parent 和 $children 。更多的是使用 props 和 events 实现父子组件通信,
2.mixins 混入
3.extends
允许声明扩展另一个组件,而无需使用 Vue.extend。这主要是为了便于扩展单文件组件
这和 mixins 有点类似
mixins、extends 在这篇文章中有详细的介绍 vue API 知识点(1)---全局 API 总结
4.provide / inject
provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
解析:就是组件的引入层次过多,我们的子孙组件想要获取祖先组件的资源,可以不使用 props 的方式依次传递给子孙组件,层次太多,代码结构容易混乱。那么就可以使用 provide/inject 来做传递
官方注解
provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 Symbols 作为key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的环境下可工作
inject 选项应该是一个字符串数组或一个对象,对象的key是本地的绑定名,
value 是 在可用的注入内容中搜索用的 key(字符串或 Symbol),或一个对象,该对象的
from property 是在可用的诸如内容中搜索用的 key(字符串或 Symbol)
default property 是降级情况下使用的 value
个人解析
provide 是一个对象,或者是一个返回对象的函数,里面就包含要给子孙后代的东西,也就是属性和属性值
inject 一个字符串数组,或者是一个对象。属性值可以是一个对象,包含 from 和 default 默认值
const Child = {
inject: {
foo: {
from: 'bar',
default: 'foo'
}
}
}
from 表示在可用的注入内容中搜索用的 key,default 当然就是默认值
注意:provide 和 inject 绑定并不是可响应的。这是刻意为之的,然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的
官方示例
// 父组件
var Provider = {
provide: {
name: 'zhangning'
},
// ...
} // 子组件注入
var Child = {
inject: ['name'],
created() {
console.log(this.name) // => 'zhangning'
}
}
利用 es 中的 Symbols、函数 provide 和对象 inject
const a = Symbol();
const Parent = {
provide(){
return {
[a]: 'zhangning187'
}
}
} const Child = {
inject: { a },
// ...
}
在新版本中,使用一个注入的值作为一个 property 的默认值
const Child = {
inject: ['name'],
props: {
bar: {
default() {
return this.name
}
}
}
}
使用一个注入的值作为数据入口
const Child = {
inject: ['name'],
data() {
return {
bar: this.name
}
}
}
如果它需要从一个不同名字的 property 注入,则使用 from 来表示其源 property
const Child = {
inject: {
from: 'bar',
default: 'name'
}
}
与 prop 的默认值类似,你需要对非原始值使用一个工厂方法
const Child = {
inject: {
name: {
from: 'bar',
default: () => [1, 2, 3]
}
}
}
在日常的开发中,我们经常会使用 Vuex 做状态管理,但是 vuex 有时候太过于繁琐。如果我们不想使用 vuex,这个时候我们就可以使用 provide/inject 这个方式来代替vuex,在跟组件中传入变量,然后在后代组件中使用即可
// 在跟组件中提供一个非响应式变量给后代组件
export default {
provide() {
return {
text: 'zhangning'
}
}
} // 后代组件注入
export default {
inject: ['text'],
created() {
this.text = 'zhangning187'// 在我们使用 text 的时候它依然是 zhangning,而不是zhangning187
}
}
上面已经讲过,provide 和 inject 绑定并不是可响应的,这是可以为之。当然我们也可以传入一个可响应的对象,那么它的属性也就是可响应的了
也就是说,Vue 不会对 provide 中的变量进行响应式处理。所以要想 inject 接受的变量是响应式的,provide 提供的变量本身就需要是响应式的。
由于组件内部的各种状态就是可响应式的,所以我们直接在根组件中将组件本身注入 provide,此时,我们可以在后代组件中任意访问根组件中的所有状态,根组件就成为了全局状态的容器
// 根组件提供将自身提供给后代组件
export default {
provide() {
return {
app: this
}
},
data() {
return {
text: 'zhangning'
}
}
} // 后代组件 注入 export default {
inject: ['app'],
data(){
return{}
},
created: {
this.app.text = 'zhangning187'// 此时使用 text,它的值就是zhangning187
}
}
当然,我们也可以通过 $root 来获取根节点,但是在团队开发的过程中,如果所有的全局变量都统一定义在根组件中并不合适,而使用 provide/inject 不同模块的入口组件传给各自的后代组件可以完美解决这个问题
Vuex 和 provide/inject 区别在于,Vuex 中的全局状态的每次修改都是可以追踪回溯的,而 provide/inject 中变量的修改是无法控制的,通俗说就是,你不知道是哪个组件修改了这个全局状态。
provide/inject 破坏了我们的单向数据流原则。如果多个后代组件同时依赖于一个祖先组件提供的状态,那么只要有一个组件修改了这个状态,则所有组件都会受到影响。这个使耦合度增加了,让我们的数据变化不可控,在多人的开发过程中,这个可能会变得特别混乱。
以上看起来使用 provide/inject 做全局状态管理好像很危险,所以我们要谨慎使用这个方式。
但是在组件开发的时候,vue 官方提倡我们使用这种方法。例如 elment-ui
六、选项 / 其他
1.name
只有作为组件选项时起作用
允许组件模板递归地调用自身,注意,组件在全局用 Vue.component() 注册时,全局 ID 自动作为组件的 name
指定 name 选项的好处就是便于调试,有名字的组件有更友好的警告信息,当在 vue-devtools 下,未命名组件将显示成<AnonymousComponent>,这很没有语义,通过提供 name 选项,可以获得更有语义信息的组件树
2.delimiters
了解一下就行,通常不会去更改插入分隔符
类型 Array<string>
默认值 ["{{", "}}"]
限制 这个选项只在完整构建版本中的浏览器内编译时可用
改变纯文本插入分隔符
示例
new Vue({
delimiters: ["${", "}"]
})
// 分隔符变成了 ES6 模板字符串的风格
3.functional
了解一下,通常用不到
类型 Boolean
使组件组状态(没有 data)和无实例(没有 this 上下文)。他们用一个简单的 render 函数返回虚拟节点,是他们渲染的代价更小
4.model
允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一下输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突
// 定义一个组件
Vue.component('my-check', {
model: {
prop: 'checked',
event: 'change'
},
props: {
value: String,
checked: {
type: Number,
default: 0
}
}
})
使用
<my-check v-model='foo' value='some value'></my-check>
以上代码相当于
<my-check :checked='foo' @change='value=>{foo = val}' value='some value'></my-check>
我们先了解一下 input 中的 v-model 是怎么实现双向绑定的。
<input type='text' v-model='msg'>
v-model 只是语法糖真正的实现方式
<input type='text' :value='msg' @input='msg=$event.target.value'>
真正的双向绑定是通过监听 input 事件
v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件
text 和 textarea 元素使用 value 属性和 input 事件
checkbox 和 radio 使用 checked 属性和 change 事件
select 使用 value 和 change 事件
我们可以自定义输入框组件的 v-model,双向绑定
Vue.component('my-input', {
template: `<input :value='value' @input='updateValue($event.target.value)' type='text'></input>`,
props: ['value'],
methods: {
updateValue(val) {
this.$emit('input', val)
}
}
}) let app = new Vue({
el: '#app',
data(){
message: ''
},
methods: {
handleInput(val) {
this.message = val
}
}
})
<div id='app'>
<my-input :value='message' @input='handleInput'></my-input>
</div>
上面的示例我们可以了解到,默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,所以当我们在一个自定义组件上使用 v-model 并不能实现双向绑定,因为自定义的组件并没有默认的 value 和 input 事件,在使用时,我们需要按照上面那样显式的去声明定义这些东西,这时,选项 model 就派上用场了,在定义组件的时候指定 prop 的值和监听的事件(看到这里,上面写的官网给出的例子也应该可以看明白了)
举例
Vue.component('my-input', {
model: {
prop: 'uname',
event: 'handleChange'
},
props: {
uname: {
type: String,
default: 'zhangning'
}
},
methods: {
updateVal(val) {
this.$emit('handleChange', val)
}
}
})
模板
<template>
<div>
<input type='text' :value='uname' @input='updateVal($event.target.value)'>
</div>
</template>
使用组件
<my-input v-model='name' value='some value'></my-input>
等价于
<my-input :uname='name' @handleChange='val=>{foo = val}' value='some value'></my-input>
上面的示例中我们就可以在自定义的组件中使用 v-model 来进行双向绑定了(多看一下示例就明白了)
vue API 知识点(2)---选项总结的更多相关文章
-
vue API 知识点(1)---全局 API 总结
1.Vue.extend(options) 构造器,创建一个 子类 .参数是一个包含组件选项的对象 data 选项是特例,需要注意 在 Vue.extend() 中它必须是一个函数, <div ...
-
vue API 知识点(3) --- 实例 总结
一.实例 property 1.vm.$data Vue 实例观察的数据对象,Vue 实例代理了对其 data 对象 property 的的访问 2.vm.$props 当前组件接收到的 props ...
-
记vue API 知识点
1. v-cloak指令:这个指令保持在元素上直到关联实例结束编译.和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标 ...
-
vue API 知识点(4) --- 指令、特殊 attribute 、内置组件
一.指令 1.v-text <span v-text="msg"></span> <!-- 两种写法是一样的 --> <span>{ ...
-
Vue实例初始化的选项配置对象详解
Vue实例初始化的选项配置对象详解 1. Vue实例的的data对象 介绍 Vue的实例的数据对象data 我们已经用了很多了,数据绑定离不开data里面的数据.也是Vue的核心属性. 它是Vue绑定 ...
-
VUE API 重点
VUE API 重点 生命周期方法 每个组件都有生命周期,是向 ReactJs 学习的. computed 在一个组件声明一个人,人有名,人有姓,输入姓和名.((&--&%--& ...
-
vue 里面的watch 选项详解
早就想好好写写这个watch了,一直顾不上,因为想深刻的记录一下,其实这些东西只要是好好看看官网的说明,都在里面呢. 虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器.这就是为什么 V ...
-
VUE【二、选项和生命周期】
vue对象,类似于一个viewModel,是处理页面显示的数据模型的对象 其中会有很多选项,以下为较常用的: 选项 1.data-数据 vue实例会代理其data对象里的所有属性 2.methods- ...
-
关于iOS和OS X废弃的API知识点
今天在查看苹果接口文档时,突然对于接口的声明知识点比较感兴趣,再网络找到下面这个比较不错的文章,记录一下并分享: 如你所知,已废弃(Deprecated)的API指的是那些已经过时的并且在将来某个时间 ...
随机推荐
-
char nchar varchar nvarchar的区别(转)
char nchar varchar nvarchar的区别 今天在论坛里看到有人激烈讨论这几个数据类型的区别跟实际使用情况,很多人都搞不清楚究竟哪个场景使用哪个数据类型 现在就摘录一下sql2 ...
-
ICMP 实现
以下代码取自 kernel- . [数据结构] struct icmp_control { void (*handler)(struct sk_buff *skb); //icmp处理函数,根据icm ...
-
zookeeper集群的安装
顾名思义zookeeper就是动物园管理员,他是用来管hadoop(大象).Hive(蜜蜂).pig(小猪)的管理员, Apache Hbase和 Apache Solr 的分布式集群都用到了zook ...
-
关于socket.io的使用
这段时间学习了socket.io,用它写了小项目,在此总结下它的基本使用方式和一些要点. socket.io是基于Node.js和WebSocket协议的实时通信开源框架,它包括客户端的JavaScr ...
-
C#自定义控件、用户控件、动态加载菜单按钮
一.效果图,动态加载5个菜单按钮: 二.实现方法 1.创建用户控件 2.在用户控件拖入toolStrip 3.进入用户控件的Lood事件,这里自动添加5个选 ToolStripMenuItem,后期 ...
-
协同过滤算法 teamCF
http://www.infoq.com/cn/articles/recommendation-algorithm-overview-part02
-
Linux多线程 - 基本操作
0. 线程 vs 进程 何为线程?线程即轻量级进程,如何理解轻量级这个概念? 我们知道,Linux的资源分为用户空间资源和内核空间资源: 用户空间资源:用来存放用户自定义的一些数据,用户可直接控制: ...
-
P4611 [COCI2011-2012#7] TRAMPOLIN
题目背景 有很多超级英雄:蝙蝠侠,蜘蛛侠,超人等.其中,有一位叫牛.今天他想模仿蜘蛛侠,所以他选择了一排高大的摩天楼来跳. 题目描述 具体而言,他选择了一个由 N 个摩天大楼构成的序 列,从左到右编号 ...
-
Oracle EBS R12多组织访问架构
关于R12的新特性Multi-Org Access Control(MOAC).Oracle宣传的好处主要有:1.enable users to access to secured data in o ...
-
安装lighttpd
依赖包: zlib,pcre,cronolog,bzip2, 1: 将lighttpd的原码包.以土豆现用lighttpd配置文件为基础的lighttpd.conf文件.日志轮循工具cronolog ...