【Vue.js】Vue组件使用与父子组件间通信
- props和$emit
- 组件间通讯 - 自定义事件
- 组件生命周期
1.vue父组件如何向子组件中传递数据?
使用props: 通过属性传递
子组件中:
props: ['list'],
// 属性中的名称不能和data中的属性重名
父组件中:
<u-list :list="list"></u-list>
props可以限制属性的类型
2.vue中子组件如何调用父组件的方法
通过v-on 监听 和$emit触发来实现:
1、在父组件中 通过v-on 监听 当前实例上的 自定义事件。
2、在子组件 中 通过'$emit'触发 当前实例上的 自定义事件。
3.非父子组件如何进行通信
非父子组件:vuex 本地存储 总线机制 自定义事件
使用事件传递
在子组件触发事件
// this.$emit(事件名, 数据)
this.$emit('completed', this.item.id)
在父组件响应事件
<!--响应子组件的事件 @子组件定义的事件-->
<u-input @add="addToList"></u-input>
代码示例
Index.vue
<template>
<div>
<Input @add="addHandler" />
<List :list="list" @delete="deleteHandler" />
</div>
</template>
<script>
import Input from './components/Input'
import List from './components/List'
export default {
components: {
Input,
List
},
data () {
return {
list: [
{
id: 'id-1',
title: '标题1'
},
{
id: 'id-2',
title: '标题2'
}
]
}
},
methods: {
addHandler (title) {
this.list.push({
id: `id-${Date.now()}`,
title
})
},
deleteHandler (id) {
this.list = this.list.filter((item) => item.id !== id)
}
},
created () {
// eslint-disable-next-line
console.log("index created");
},
mounted () {
// eslint-disable-next-line
console.log("index mounted");
},
beforeUpdate () {
// eslint-disable-next-line
console.log("index before update");
},
updated () {
// eslint-disable-next-line
console.log("index updated");
}
}
</script>
Input.vue
<template>
<div>
<input type="text" v-model="title" />
<button @click="addTitle">add</button>
</div>
</template>
<script>
import event from './event'
export default {
data () {
return {
title: ''
}
},
methods: {
addTitle () {
// 调用父组件的事件
this.$emit('add', this.title)
// 调用自定义事件
event.$emit('onAddTitle', this.title)
this.title = ''
}
}
}
</script>
List.vue
<template>
<div>
<ul>
<li v-for="item in list" :key="item.id">
{{ item.title }}
<button @click="deleteItem(item.id)">删除</button>
</li>
</ul>
</div>
</template>
<script>
import event from './event'
export default {
// props: ['list']
props: {
// prop 类型和默认值
list: {
type: Array,
default () {
return []
}
}
},
data () {
return {}
},
methods: {
deleteItem (id) {
this.$emit('delete', id)
},
addTitleHandler (title) {
// eslint-disable-next-line
console.log("on add title", title);
}
},
created () {
// eslint-disable-next-line
console.log("list created");
},
mounted () {
// eslint-disable-next-line
console.log("list mounted");
// 绑定自定义事件
event.$on('onAddTitle', this.addTitleHandler)
},
beforeUpdate () {
// eslint-disable-next-line
console.log("list before update");
},
updated () {
// eslint-disable-next-line
console.log("list updated");
},
beforeDestroy () {
// 及时销毁,否则可能造成内存泄露
event.$off('onAddTitle', this.addTitleHandler)
}
}
</script>
生命周期(重点)
- 挂载阶段
- 更新阶段
- 销毁阶段
Vue生命周期经历哪些阶段:
1.总体来说: 初始化、运行中、销毁
2.详细来说: 开始创建、初始化数据、编译模板、挂载Dom、渲染——>更新——>渲染、销毁等一系列过程
- beforeCreate: 此时vue(组件)对象被创建了,但是vue对象的属性还没有绑定, 如data属性、computed属性,即没有值
- created: 最早能放到data、methods等数据成员的钩子函数, 可以把http请求写到这个钩子函数中, 可以做一些和数据相关的操作
- beforeMount: 在这里第一次可以获取到DOM模板的生命周期,但是数据还没有挂载到页面上。即此时页面中的{{}}里的变量还没有被数据替换
- mounted: 实例已经完成挂载, 模板中的数据已经完成渲染
- beforeUpdate: 当数据每次改变时(循环往复调用),数据改变之后,模板解析替换之前,这里的模板还没有完成视图更新
- updated: 当数据每次改变的时候(循环往复调用):数据改变之后,模板解析替换已经完成,已经是数据更新之后的最新的模板视图
- beforeDestroy: 实例销毁之前做的一些收尾工作, 例如清除在实例运行期间开启的定时器和自定义事件.
- destroyed: 实例销毁
Keep-alive的使用
activated函数:keep-alive组件激活时调用
activated函数:keep-alive组件停用时调用
包裹动态组件时, 会缓存不活动的组件实例, 主要用于保留组件状态或避免重新渲染
例如有一个列表和一个详情, 那么用户就会经常执行打开详情 => 返回列表 => 打开详情…这样的话列表和详情都是频率很高的一个页面,就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染而不是重新渲染。