一、业务需求
在一个拥有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
是已经被赋过值的了。