一、业务需求
在一个拥有4个步骤的单向流程(Flow)中,需要在第2步展现 A 组件,第4步展现 B 组件,在第1、3步的时候隐藏组件。在有组件展示的步骤里,会传给组件的4组不同的数据(param),组件需要根据传入的数据做一些业务操作。
二、需求分析
- 在同一个地方有组件间的切换,可采用动态组件
component。 - 对一个组件来说,当传入参数改变的时候,需要有相应的动作,所以可用
watcher监听传入的参数是否改变。 - 组件需要隐藏 / 显示,可考虑使用
v-if或者v-show -
v-if会重新创建组件(这是所谓开销大的一方面),有些组件自己维护的状态是不能保留的
三、伪代码
/*
* A.vue
* 组件A
*/
<template lang="pug">
div
p {{param.text}}
</template>
<script>
export default {
name: 'A',
props: [ 'param' ],
watch: {
param: () => {
...
}
}
}
</script>
组件 B 和组件 A 类似,除了 name: 'B',所以略过了。
/*
* Flow.vue
*/
<template lang="pug">
div
div#container(v-if='show')
component(
:is='view'
:param='param'
)
</template>
<script>
import A from 'A.vue'
import B from 'B.vue'
export default {
name: 'Flow',
components: { A, B },
data() {
return {
show: false,
view: null,
param: null
}
},
mounted() {
this.view = 'A'
setTimeout(() => {
// 经过1秒以后流程进入第二步
this.param = { ... } // 模拟第一次传入数据
this.show = true // 显示组件
// ... 其余步骤模拟略过
}, 1000)
}
}
</script>
当 Flow 的 mounted 执行的时候,A 中的 param watcher 并不会被执行;若把 Flow 中的 v-if 改成 v-show,则 param watcher 会被执行。
四、分析
当使用 v-show 的时候,this.view = 'A' 的时候,A 组件已经完成了初始化(会触发 mounted),此时 A 组件拿到的 param 是 null,所以当 param 在 Flow 中被赋值的时候,会触发 watcher 事件。注意:在切换 view 的时候,把新组件的一些初始化操作放到 vm.$nextTick 的回调里面。
而使用 v-if的话,A 组件的初始化会被延迟到 this.show = true 的时候,此时 A 组件拿到的 param 是已经被赋过值的了。