Vue实例的选项很丰富,包含多种不同的功能特性:组件选项皆为可选
1,选项/数据:props, data, computed, methods, watch, propsData
a, data(数据选项):用来定义组件自身的状态;可用于自身模板中,各种方法中,计算属性,以及一些可以访问实例的生命周期钩子函数中,监视器中;可用于通过attributes传递给子组件;会将数据选项对象属性递归转为响应式属性;这样数据的改变会触发通知以更新视图(Vue的数据变更队列是异步的,响应式负责通知,而更新视图的行为是另一个任务);
data的用法:data: Function | Object; 可以是个函数(当实例是数组时,要求data必须是个函数,当它是个函数时,把返回的值作为实例$data属性,并将返回的对象属性转为响应式属性);可以是个对象; data的属性也将混入到实例中成为实例的属性(不包括嵌套);
//数据选项的使用
var component = {
tamplate: '',
data: function(){ //必须是函数
return {test: 'test', terminal: 'terminal', initVal: this.value};
//this.value from props
},
props: ['value', 'type'], //value from parent component;
computed: {
mer: function(vm){
vm.test + ' ' + this.terminal; //参数vm是组件实例;在属性方法中可以使用this指向实例
}
},
mathods: {
reverse: function(){//方法没有若要使用实例,必须不能是个箭头函数
this.test = this.test.split('').reverse().join('');
}
},
watch:{
mer: function(newVal, oldVal){
}
}
};
b, props(props选项): 用来接收父组件向下传递的数据(这是通过组件的attributes向组件内部传递数据;在组件实例化,会在初始渲染时,从attrs找到props的键值并组成propsData选项对象,propsData会用于props的初始);Vue的设计思想是父组件向子组件单向传递数据,但不允许子组件直接更改父组件的状态,所以强烈建议不要修改来自父组件的状态;这样可以防止以外修改父组建的状态,父组件因状态的更改重新渲染虚拟dom树以及更新DOM元素,也会更新子组件;若修改父组件传递过来的数据,可以props的属性值作为data的属性的初始值,然后转为对组件自身data的修改;
props的用法:props:Array
c, computed(计算属性选项):一般当需要将一个状态或prop进行复杂的变形或计算时,或模板表达是个复杂的表达式时,可以用计算属性实现并代替复杂的表达式;计算属性可用于自身模板中,各种方法中,以及一些可以访问实例的生命周期钩子函数中,监视器中;可用于通过attributes传递给子组件;计算属性使用到的响应式属性会成为计算属性的依赖,当任意依赖发生变化时,计算属性的值才会改变,不然拿的都是之前缓存的值;若依赖的数值是非响应式,则计算属性值不会更新;初始时,会为计算属性创建监视器,但不会把计算属性转为响应式属性,计算属性的响应靠依赖项体现;
computed的用法: { [key: String]: Function | {get: Function, set: Function} };是个对象,属性名便是计算属性名;属性值是个函数时,它表示是个getter访问器;
计算属性不同于方法,用在模板表达式中,计算属性的值不需要通过时时执行函数,因为计算属性的值是缓存的,当依赖项该改变时,计算属性的值才会更新并通知更新视图,若是方法在每次触发重新渲染,都会再次执行方法;用在属性绑定中,方法总是时时执行,这样不利于调试和性能;当然方法有方法用处;计算属性不同于监听器,计算属性主要是处理复杂的表达式,但是像数据的变更需要异步获取数据或开销较大时需要用watch;
d,methods:{[key:String]: Function};定义方法集合,每个属性都是方法;methods可以用在模板中成为绑定属性的表达式(如何作为事件处理函数),也可以用在watch选项中,也可以用在其他方法中;每个方法都接受两个参数(newVal, oldVal); 创建Vue实例时,methods中所有方法都自动绑定了实例(this === vm);
用在事件处理:Vue.js系统,可以使用v-on(简写@)监听DOM事件,并绑定事件处理逻辑;可以使用methods选项中的方法名或方法调用做为事件器;其中提到DOM修饰符、按键修饰符、系统修饰键、鼠标修饰符等:
//事件修饰符:
//.passive, .prevent,.caprure,.stop,.once,.self
//阻止点击事件继续传播
Test
//按键修饰符: 这些是按键码别名,有的时候为了兼容不同平台,用按键码别名比较合适
//通过全局配置可以设置按键码的别名:Vue.config.keyCodes.f1 = 112;
//按键码是数字
//当放开按键enter时触发事件
//系统修饰键:meta, shift, ctrl, alt,表示按其他键时,要同时按着这些按键之一
test
//exact 表示精确;像下边这句表示点击时只有只能还按着ctrl键才能触发事件
test
//鼠标事件修饰符:left,right,down,up
e, watch: 定义监视器;主要是当监视的属性发生改变时,可以执行回调函数处理一些需要在某些属性变化后逻辑;主要处理异步调用、异步获取数据或开销比较大的逻辑;
watch的用法: {[key:String]: String | Array | Object | Function} ;key是需要监视的属性名;属性值有几种表示形式:字符串表示methods选项中method,Array可以是String,Object,Function的集合,表示有个回调处理;Object形式的可以可选选项{handler: fn, immediate: bool, deep: bool};函数就是一个简单的监听器;
data: {
a: 'test',
b: 'b',
c: 'c',
d: {g: 'hello'}
},
methods: {
test: function(){
console.log(this.a);
}
},
watch:{
a: 'test', //test是methods中的一个方法
b: function(newVal, oldVal){
///
},
c: {
handler: function(newVal, oldVal){
///
},
immediate: true, //设置为true时,在生命周期钩子created之前调用,会立即调用该回调一次
//newVal就是当前监听的属性的当前值,oldVal是undefined;可选
},
'd': [
'test',
{
handler: fn,
immediate: true,
deep: true //可选,设置为true,则监听整个对象(包括属性、属性的属性等等)的变化;
//否则监听的是自身的变化;如vm.d = {g: 'df'}才会调用该回调
//监听的是个引用类型的属性,当是属性改变,newVal和oldVal总是相等
},
function(newVal, oldVal){ //改变的是自身,则是指向改变了,newVal和oldVal不等
///
};
],
'd.g': 'test' //只支持dot-limiter的键路径;不仅是值的改变,若是指针的指向变了也会调用回调
}
监听子组件事件:
//html
//js template
//触发事件$emit(type, ...args);
var component = {
name: 'my-comp',
template:''
}
var vm = new Vue({
el: '#test',
components: {
'my-comp': component
}
});
//双向绑定的真相之一:model和event的emit
//表单的元素的双向绑定v-model;拿作为例子;
//相当于v-bond:value='val' v-on:input='val=$event.target.value'
//自定义组件的双向绑定相当于:
//
//my-comp的template
f, propsData:创建实例时传递props,主要作用是方便测试;就是在测试时,不需要修改父组件模板传递props数据,propsData可代替这种行为。
2, 选项/Dom:el(只有根实例才使用),template(组件模板,实例时,预编译template),render(渲染函数)
a: el:String | Element;el可以是个string类型的css选择器;可以是个DOM元素实例;用于Vue实例的模板挂载,即Vue实例的模板会挂载在这个指定的元素上(el);该选项会让实例在实例化时执行编译,若组件选项没有该值时,则需要显式地调用vm.$mount(selector | Element)执行编译和挂载;el选项只能用在用new创建的实例的组件选项中,el会被template或render覆盖,所以el建议不要使用body、html等元素,可以用一个div元素作为挂载点;若template和render都没有给定,那么el会被提取出来用作实例的模板(这时跟给template一样需要用到compiler):像这样
//html
title
//js
var component = {
name: 'my-comp',
template: `
`,
data: function(){
return {value: 3};
},
methods: {
test: function(str, event){
this.value ++;
}
}
};
var vm = new Vue({
template: 'for test here',//给定template组件选项且是个valid的数据
components: {
myComp: component //或者'my-comp',但在html模板中总是用小写短横线的格式'my-comp'
}
});
vm.$mount('#test');
//(以上例子没有调试过,若有问题,可根据调试解决)那么渲染后的DOM树是这样的
for test here
//vm实例没有给出template选项也没有render选项,那么渲染后的DOM树是这样的
//el被提取作为实例模板;
title
b: template: String(以'#'开头选择符,常用的技巧是用 包含模板;或者是html字符串);作为Vue实例的模板,用于展现Vue实例的DOM内容;模板会替换挂载元素,挂载元素的内容会被忽略,除非模板中有分发插槽(
c: render: (createElement:() => VNode, context: Object) => VNode;(function(createElement, context){///});这是个渲染函数,代替template;在render函数可以在bebal下使用JSX语法;在某些情境下比template方便且容易掌控也比较编程式;(给render一个总结的篇章)
d:renderError: (createElement:()=> VNode, error: Error)=>VNode
3,选项/生命周期钩子:beforeCreate,Created,beforeMount,mounted,beforeUpdate,updated,activated,deactivated,beforeDestroy,destroyed,errorCaptured;Vue实例在初始化中,会初始生命周期钩子,会执行一些生命周期钩子的函数;生命周期钩子给我们留下在不同阶段可以添加自己的逻辑的空间;
a: beforeCreate:()=>void;在实例初始化之后,在数据观测和event/watcher配置之前调用;能拿到实例,但还不能访问实例的数据property,方法等;
b:created:()=>void(实例被创建后,this可用;慎用箭头函数,因为箭头函数的this不能绑定为当前实例)实例创建完成后,到这步已完成以下配置:数据观测(data observer,),property和方法的运算,event/watcher事件回调;但$el还不能用,因为挂载完成才能使用;
c:beforeMoute:()=>void;在挂载之前调用,render函数首次被调用;在服务端渲染期间不调用该钩子函数;$el还不能用;
d:mounted:()=>void;完成挂载后调用,$el这时可以访问,el也被新建的$el替换;如果根元素挂载到了文档内的元素上,这时,$el也在文档内;mounted不会保证所有子组件也都一起被挂载,若想等待整个视图渲染完成,可以使用vn.$nextTick(func);服务端渲染不调用该函数;
e:beforeUpdate:()=>void;视图更新之前;服务端渲染不调用该函数
f:updated:()=>void;视图更新之后;updated不能保证所有子组件也都一起重新渲染,可以用vm.$nextTick(fn);服务端渲染不调用该函数
g:activated:()=>void;被kepp-alive缓存的组件被激活时调用;服务端渲染不调用该函数
h:deactivated:()=>void;被keep-alive缓存的组件停用时被调用;服务端渲染不调用该函数
i:beforeDestroy:()=>void;实例销毁之前;这时的实例还完全可用;(在版本3,不叫destroy,而是unmounte): 服务端渲染不调用该函数
j:destroyed:()=>void;实例销毁后调用,执行该钩子函数后,实例的所有指令都解绑,所有事件监听器被移除,所有子组件都被销毁;服务端渲染不调用该函数
k:errorCaptured: (error: Error, vm: Component, info: string)=>?boolean;vm是抛出错误的组件实例;在处理子孙组件抛出的错误时被调用;返回值为false时,可以防止错误继续向上传播;