一般来说,按照 Vue 的官方脚手架新建项目时,不会考虑到 new Vue() 的问题,因为官网已经替我们做好了。但是回过头来想想,实例化 Vue 对象时,到底可以传入哪些参数呢?
Vue 构造函数在 src/core/instance/index.js 文件中
我们可以看到 Vue 构造函数接受一个对象 options
作为参数。例如以下的方法就可以声明一个 vue 实例。
// new Vue(options)
const vm = new Vue({
el: '#app'
})
【注意】在 options 中如果用函数,其 this 对象并不能访问到当前 options 对象,其 this 指向会被指向 vm 实例。
const options = {
props: {
name: {
type: String,
default: 'weekbin'
}
},
data: function() {
return {
nameType: this.props.name.type // 错误用法,这里的 this 不指向 options
}
}
}
【注意】在 options 中如果用箭头函数,this 对象无法被 bind,call,apply 更改,也就意味着 this 不能被 vue 正常处理。
const options = {
props: {
name: {
type: String,
default: 'weekbin'
}
},
data: vm => ({ name: vm.name }) // 使用箭头函数时,接受一个 vm 作为参数,指向当前实例
}
根据 官方文档 我们可以看到 options
主要可以分为:Data、Dom、Lifecycle Hooks、Assets、Composition、Misc 这么几种。
与数据相关的参数总共有五个:data、props、propsData、computed、methods 和 watch。
data 推荐使用 function 返回,防止模块化配置导致多个组件共用一个 data 引用的情况发生。
props 有两种配置方式:一种是数组,一种是对象。以数组传递的方式,仅仅只能用字符串形式,不能写成对象数组。以对象的形式传递,每个变量有四种可选配置:type、default、required 和 validator 四种。
props: ['age']
props: {
name: {
type: String,
default: 'age',
required: false,
validator: function(value) {
return value >= 0
}
}
}
propsData 几乎不用,用于在创建实例时传递 props 的值,用于测试。
computed 也有两种配置方式:一种是方法,另一种是一个包含 get 和 set 函数的对象。
computed: {
name(){
return this.name
}
}
computed: {
_name: {
get(){
return this.name
},
set(val) {
this.name = val
}
}
}
methods: {
hello(){
console.log(this.name)
},
world: () => console.log(this.name) // 错误,箭头函数会导致 this 无法绑定到 vm 上
}
watch: {
a: 'hello', // 会调用 methods 中的 hello 方法
b: function(val, oldVal){},
c: {
handler: function(val, oldVal){},
deep: true
},
d: {
handler: 'hello',
deep: true
},
e: [
... // 支持以数组形式配置多个回调函数
]
}
与 DOM 相关的参数总共有四个:el、template、render 和 renderError。
el 接受一个字符串或者一个 Element 的引用作为入参,vue 讲设法找到提供的节点作为挂载的节点。
template 模板字符串,用其解析编译出 render 函数,渲染的内容将替换 el 节点的子节点。
render 函数,渲染的内容会替换 el 的子节点。优先级比 template 编译出来的 render 函数优先级高。
renderError 函数,兜底函数,用于提供无法渲染时的替换方案。
与声明周期相关的参数总共有十一个:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deactivated、beforeDestroy、destroyed 和 errorCaptured。
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy 和 destroyed 这 8 个钩子是每个 vm 实例都会执行的。写在声明周期参数中的函数体将在钩子调用时被同步执行(如果有异步方法,并不会等待异步方法返回结果)。
当组件是 keep-alive 组件的子组件时,会多 activated 和 deactivated 两个钩子,当从别的路由切换回来查看 keep-alive 的缓存时,注册在 activated 中的函数体将被同步执行(如果有异步方法,并不会等待异步方法返回结果);当从当前页面离开,查看别的 keep-alive 的子组件时,会触发 deactivated 钩子(beforeDestroy 和 destroyed 在 keep-alive 缓存的情况下不会执行)。当离开 keep-alive 组件页面时,子组件的 beforeDestroy 和 destroyed 钩子会被调用。
这边有个坑,就是在 keep-alive 的子组件中的定时器,如果需要其在离开页面,在缓存的情况下也销毁,需要在 deactivated 中销毁掉。否则虽然视图不显示,但是页面被缓存下来了,不会调用 beforeDestroy 和 destroyed 钩子。
errorCaptured 捕获子组件的 render 错误,如果该钩子返回 false,则会阻止错误继续冒泡,被 vue 全局异常处理器捕获,视为该组件已经正确地处理了该异常。
与 Assets 相关的参数总共有三个:directives、filters 和 components。局部注册指令、过滤器和组件的方法与 Vue.directive()、Vue.filter() 和 Vue.component() 类似,只不过是这三个方法接受两个参数,第一个是名称,第二个是具体的 Assets;局部注册是将名称作为 key,Assets 作为 value。
与 Assets 相关的参数总共有五个:parent、mixins、extends、provide 和 inject。
parent 接受一个 vm 为参数,建立父子管理。通常这在 vue 的工程化项目中,这是自动的。
mixins 接受一个 options 作为混入对象,其原理就是调用 mergeOptions 函数将其与当前 options 混合。故被混入的 options 数据结构与当前 options 完全相同。
extends 接受一个 vm 参数,继承 vm 的所有功能并拓展一些功能。
provide 和 inject 用于同祖先组件跨组件通信。provide 在祖先组件定义要下发的内容,inject 在具体的子组件中接受。派发是一次性的,不是响应式的,保持响应式可传递引用或取值函数。
与 Assets 相关的参数总共有五个:name、delimiters、functional、model、inheritAttrs 和 comments。
name 属性当且仅当是组件 option 时生效,如果不提供,默认将提取文件名作为组件名。
delimiters 可以更换插槽表达式,不推荐使用。
// default: ["{{", "}}"]
new Vue({
delimiters: ['${', '}']
})
functional 参数将组件标记为函数式渲染组件(没有响应式数据和 this 上下文)。
model 参数允许自定义 v-model 的行为,不常用。
inheritAttrs 默认为 true,<hello-world message="hello weekbin" />
如果组件没有用 props 接收 message,message 将会被渲染到 dom 中;如果设置为 false,即使没有用 props 接收 message,也不会被渲染到 dom 中。
comments 保留 HTML 模板中的注释节点,默认为 false。