Vue的构造选项options(也就是new Vue实例时的输入参数),options一共有五类属性,作为初学者首先重点学习其中的四类,分别是:
- 数据:data、props、propsData、computed、methods、watch
- DOM:el、template、render、renderError
- 生命周期钩子:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deacticated、beforeDestroy、destroyed、errorCaptured
- 资源:directives、filters、components
数据
data(内部数据)
- 类型:
Object | Function - 限制:组件的定义只接受
function在定义一个组件的时候,data必须声明为一个返回初始数据对象的函数,因为组件有可能会被用来创建多个实例。
在JS中,对象是存放在内存中的堆区的,当组件创建了多个实例时,每一个实例都有属性data,而这些实例的data属性的值均指向data对象的内存地址,那么我们在修改A实例的data属性时,相当于直接在内存的对应位置修改了data对象的内容,内存中的data对象被A实例覆写了,因为B实例的data属性是对内存中data对象的引用,所以会造成引用传递,导致该组件创建的B实例的data数据被影响了。
把data声明为有返回值的函数时,每次创建一个新的实例后,data()函数被调用,返回的初始数据会生成一个全新的副本数据对象,每个实例之间的数据对象互相不影响,杜绝了同一个组件创建的不同实例互相影响的风险。
- 用法:
// vue.js完整版为例
console.log(window.Vue)
const Vue = window.Vue
Vue.config.productionTip = false
new Vue({
/* data是对象
data:{
n:0
}, */
data(){ // data是函数
return{
n:0
}
},
template:`
<div>
{{ n }}
<button @click="add">+1</button>
</div>
`,
methods:{
add(){
this.n += 1
}
}
}).$mount('#app')
props(外部数据)
- 类型:
Array<string> | Object - 详细:props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。
- 用法:
//main.js(相当于父组件)
const Vue = window.Vue
Vue.config.productionTip = false
import Demo from './Demo.vue' //引入子组件Demo
new Vue({
components:{Demo},
data:{
n:0
},
template:`
<div>
{{n}}
<Demo :fn="add" :message="n"/>
<button @click="add">+1</button>
</div>
`,
/*这里的fn和message前面的:表示冒号后面的是JS代码,
如果不加:,写成 <Demo fn="add" message="n"/>,
则add和n都以字符串的形式传给Demo组件*/
methods:{
add(){
this.n+=1
}
}
}).$mount('#lee')
父组件实例点击button,触发add()函数,父组件实例的n加1,并且把add()函数和n变量传递给子组件Demo的实例
//子组件Demo
<template>
<div>
这里是Demo的内部
{{message}}
</div>
</template>
<script>
export default{
props:['message','fn']
/*通过设置props接收父组件传进来的数据,
父组件通过<Demo :message= :n=/>的形式向子组件传数据*/
}
</script>
子组件的实例通过message和fn两个名字获取到了父组件实例传输过来的add()函数和n变量,父组件实例点击button时触发add()函数,因为子组件实例也有一个从父组件实例传过来的add(),所以子组件实例的add()也被触发,所以子组件实例的n变量值也会随着父组件实例的点击事件而递增。
methods(方法)
- 类型:
{[key: string]: Function} - 详细:事件处理函数或者是普通函数
- 用法:
// 事件处理函数
new Vue({
data() {
return{
n: 0
}
},
template:`
<div>
{{ n }}
<button @click="add">+1</button>
</div>
`,
methods: {
add() {
// 方法中的this自动绑定为Vue实例
this.n += 1
}
}
}).$mount('#app')
// 普通函数,可以代替filter
new Vue({
data() {
return{
n: 0,
array: [1,2,3,4,5,6,7,8]
}
},
template:`
<div>
{{ n }}
<button @click="add">+1</button>
<hr>
{{filter()}}
</div>
`,
methods: {
add() {
// 方法中的this自动绑定为Vue实例
this.n += 1
},
filter(){
//不使用Vue options的filter属性,而是用普通函数代替
return this.array.filter(i => i % 2 === 0)
}
}
}).$mount('#app')
注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。
DOM
el(挂载点)
- 类型:
string | Element - 限制:只在用
new创建实例时生效 - 详细:与
$mount有替换关系。 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。
在实例挂载之后,元素可以用 vm.$el 访问。
如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用 vm.$mount() 手动开启编译。
生命周期钩子
Vue实例生命周期图示:
created(实例出现在内存中)
-
类型:
Function -
详细:
在实例创建完成后被立即同步调用。在这一步中,实例已完成对选项的处理,意味着以下内容已被配置完毕:数据侦听、计算属性、方法、事件/侦听器的回调函数。然而,挂载阶段还没开始,且
$el property目前尚不可用。
mounted(实例出现在页面中)
-
类型:
Function -
详细:
实例被挂载后调用,这时
el被新创建的vm.$el替换了。如果根实例挂载到了一个文档内的元素上,当mounted被调用时vm.$el也在文档内。
updated(实例更新了)
-
类型:
Function -
详细:
在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。
destroyed(实例从页面和内存中消亡)
-
类型:
Function -
详细:
实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
该钩子在服务器端渲染期间不被调用。
资源
components(组件)
三种声明方式:
- 引用外部组件,使用
components声明,取名为Demo,在template中使用<Demo />引用。
new Vue({
components:{
Demo: DemoComponent
},
template:`
<div>
<Demo />
</div>
`,
})
- 使用
Vue.components中进行全局声明,值为该组件的options对象,在template中使用<Demo />引用。
Vue.component('Demo',{
template:`
<div>这是Demo组件内容</div>
`
})
new Vue({
template:`
<div>
<Demo />
</div>
`,
})
- 结合前面两种方法,直接在
components中声明,值为该组件的options对象,在template中使用<Demo />引用。
new Vue({
components:{
Demo:{
data(){
return {n:0}
},
template:`
<div>Demo组件的内容n的值为{{n}}</div>
`
}
},
template:`
<div>
<Demo />
</div>
`,
})
★★★★★★★★★★★★★考虑到模块化,最好使用第一种方法★★★★★★★★★★★★