对于昨天求助的动态切换子组件之后 怎么跳转到该页面切换指定子组件的问题 在大神的劝告下 今天上午我还是走了老办法,把问题解决了,特此小编在这里把代码粘贴出来供大家知道。
问题求助帖子地址: https://blog.csdn.net/Leon_940002463/article/details/103478501
问题是这样的:
这个父组件的代码:
其他代码 不怎么重要 主要是把从其他页面接受到的 active 值接收到 传递给 flow 这个模板组件 以便后续再flow 里面判断 从而实现 进入这个页面切换到指定子组件
<!-- ---------------------
-- 充值主页面模板
-- @auther: Leon
-- --------------------- -->
<template>
<z-flow :steps="steps" :aStep="active" /> // 这个是自己写的模板组件 在下面有介绍
</template>
<script>
import * as log from 'loglevel'
import Flow from '../../layout/flow.vue'
import vEvents from '../../utils/v_events'
// 引入内容子 组件
import CertType from './steps/cert_type.vue' // 选卡类型
import ReadIdCard from '../common/read_id_card.vue' // 读身份证
import ReadShiBaoCard from '../common/red_she_bao_card.vue' // 读社保卡
import InputChongZhiCount from './steps/chong_zhi_input.vue' // 输入充值金额
import InputMiMa from './steps/input_mi_ma.vue' // 输入密码
import ShowBalance from './steps/show_blance.vue' // 展示余额
import ReadBankCard from '../common/read_bank_card.vue' // 读银行卡
import ReadHisCard from '../common/read_his_card.vue' // 读就诊卡
import VerifyHisCard from '../common/verify_his_card.vue' // 读卡后显示 卡片信息-----核对信息
import PayType from './steps/pay_type.vue' // 选择支付方式
import MoneyReceiver from '../common/money_receiver.vue' // 现金支付 投币动画
import VerifyMoney from './steps/xianshijine.vue' // 显示投币金额
import WechatSao from './steps/wechat_sao.vue' // 显示微信扫码
import WechatBeiSao from './steps/pay_bei-sao.vue' // 显示微信被扫动画
import AlipaySao from './steps/alipay_receiver.vue' // 支付宝扫码
import AlipayBeiSao from './steps/alipay_bei_sao.vue' // 支付宝被扫
export default {
name: 'steps-pay',
components: {
'z-flow': Flow
},
data () {
return {
active: '',
steps: [{ // 这个是传给 模板组件的数组
id: 'z-cert-type',
name: '证件类型',
component: CertType
}, {
id: 'z-read-id-card',
name: '读取证件',
component: ReadIdCard
}, {
id: 'z-verify-id-card',
name: '核对信息',
component: VerifyHisCard
}, {
id: 'z-pay-type',
name: '支付方式',
component: PayType
}, {
id: 'z-money',
name: '现金支付',
component: MoneyReceiver
}, {
id: 'z-verify-money',
name: '核对金额',
component: VerifyMoney
}, {
id: 'z-show-balance',
name: '充值成功',
component: ShowBalance
}]
}
},
created () {
// 在这里接受其他页面传递过来的 值
this.active = this.$route.query.active
log.info('active-------是否充值页面',this.active)
},
mounted () {
// 监听事件
vEvents.$on('cert-type', this.onCertChanged) // 读卡方式
vEvents.$on('pay-type', this.onPayChanged) // 支付方式
},
beforeDestroy () {
vEvents.$off('cert-type', this.onCertChanged)
vEvents.$off('pay-type', this.onPayChanged)
},
methods: {
// 卡类型
onCertChanged (t) {
log.info('--> card type: ', t)
switch (t) {
case 'id':
this.steps.splice(1, 1, { // splice (开始索引,删除个数,替换值) // 读身份证
id: 'z-read-id-card',
name: '读取证件',
component: ReadIdCard
})
break
case 'ssc':
this.steps.splice(1, 1, {
id: 'z-read-she-bao-card',
name: '读取证件',
component: ReadShiBaoCard
})
break
default:
this.steps.splice(1, 1, {
id: 'z-read-his-card',
name: '读取证件',
component: ReadHisCard
})
break
}
},
// 支付类型
onPayChanged (p) {
log.info('--> pay type: ', p)
switch (p) {
case 'bill': // 现金支付
this.steps = [{
id: 'z-cert-type',
name: '证件类型',
component: CertType
}, {
id: 'z-read-id-card',
name: '读取证件',
component: ReadIdCard
}, {
id: 'z-verify-id-card',
name: '核对信息',
component: VerifyHisCard
}, {
id: 'z-pay-type',
name: '支付方式',
component: PayType
}, {
id: 'z-money',
name: '现金支付',
component: MoneyReceiver
}, {
id: 'z-verify-money',
name: '核对金额',
component: VerifyMoney
}, {
id: 'z-show-balance',
name: '充值成功',
component: ShowBalance
}]
break
case 'bank-card': // 银行卡支付
this.steps = [{
id: 'z-cert-type',
name: '证件类型',
component: CertType
}, {
id: 'z-read-id-card',
name: '读取证件',
component: ReadIdCard
}, {
id: 'z-verify-id-card',
name: '核对信息',
component: VerifyHisCard
}, {
id: 'z-pay-type',
name: '支付方式',
component: PayType
}, {
id: 'z-input-count',
name: '输入金额',
component: InputChongZhiCount
}, {
id: 'z-bank',
name: '银联支付',
component: ReadBankCard
},{
id: 'z-input-mi',
name: '输入密码',
component: InputMiMa
}, {
id: 'z-show-balance',
name: '充值成功',
component: ShowBalance
}]
break
case 'wechat': // 微信支付
this.steps = [{
id: 'z-cert-type',
name: '证件类型',
component: CertType
}, {
id: 'z-read-id-card',
name: '读取证件',
component: ReadIdCard
}, {
id: 'z-verify-id-card',
name: '核对信息',
component: VerifyHisCard
}, {
id: 'z-pay-type',
name: '支付方式',
component: PayType
}, {
id: 'z-input-count',
name: '输入金额',
component: InputChongZhiCount
}, {
id: 'z-wechat-sao',
name: '微信支付',
component: WechatSao
}, {
id: 'z-wechat-bei-sao',
name: '微信支付-被扫',
component: WechatBeiSao
}, {
id: 'z-show-balance',
name: '充值成功',
component: ShowBalance
}]
break
default: // 支付宝支付
this.steps = [{
id: 'z-cert-type',
name: '证件类型',
component: CertType
}, {
id: 'z-read-id-card',
name: '读取证件',
component: ReadIdCard
}, {
id: 'z-verify-id-card',
name: '核对信息',
component: VerifyHisCard
}, {
id: 'z-pay-type',
name: '支付方式',
component: PayType
}, {
id: 'z-input-count',
name: '输入金额',
component: InputChongZhiCount
}, {
id: 'z-alipay',
name: '支付宝支付',
component: AlipaySao
}, {
id: 'z-alipay-bei-sao',
name: '支付宝支付-被扫',
component: AlipayBeiSao
}, {
id: 'z-show-balance',
name: '充值成功',
component: ShowBalance
}]
break
}
}
}
}
</script>
flow 模板组件 代码:
<!-- ---------------------
-- 流程组件 模板 步骤条。左右按钮
-- @author: Leon
-- --------------------- -->
<template>
<z-main-layout>
<!-- 左边按钮 -->
<template slot="left">
<z-side-btn v-for="(btn, idx) in leftBtns" :key="'l-btn-' + idx"
pos="left" :text="btn.text" :icon="btn.icon"/>
<z-side-btn @tapped="onPrev" :disabled="prevStopped" pos="left" text="上一步" icon="fa fa-fw fa-arrow-left"/>
</template>
<!-- 中间部分 -->
<div class="panel">
<!-- 步骤条 -->
<div class="step-wrap">
<el-steps id="steps" align-center :active="active - 1" finish-status="success">
<el-step v-for="(step, idx) in steps" :key="'step-' + idx" :title="step.name"/>
</el-steps>
</div>
<!-- 可切换组件位置 --> 在这里显示主题内容 切换不同子组件
<component :is="currentView" ref="jinE" />
</div>
<!-- 右边按钮 -->
<template slot="right">
<z-side-btn v-for="(btn, idx) in rightBtns" :key="'r-btn-' + idx"
pos="right" :text="btn.text" :icon="btn.icon" @tapped="onTiaoZhuan(btn.text)" />
<z-side-btn v-if="active != steps.length" :disabled="nextStopped" @tapped="onNext" pos="right" text="下一步"/>
</template>
</z-main-layout>
</template>
<script>
// 引入依赖
import * as log from 'loglevel'
import _ from 'lodash'
import vEvents from '../utils/v_events'
// 引入组成flow 模板组件的 布局子组件跟咱问题无关的组件只是布局用
import MainLayout from './main_layout.vue'
import SideBtn from '../component/side_button.vue'
// 引入硬件读卡js
import CardMaker from '../hardware/card_maker'
export default {
name: 'flow',
components: {
'z-main-layout': MainLayout,
'z-side-btn': SideBtn
},
props: {
fromPath: {
type: String,
default: '/frame/home'
},
steps: { // 这个就是上面父组件传入的 切换子组件的一个集合
type: Array,
required: true
},
aStep: { // 这就是上面父组件里面接收到的 其他页面传过来的值 这个值就决定了自定切换到第几个子组件
type: String,
default: ''
}
},
data () {
return {
active: 1,
prevStopped: false,
nextStopped: false
}
},
// 计算属性
computed: {
// 获取当前步
currentStep () {
return this.steps[this.active - 1]
},
// 当前的事件源-当前子组件
currentView () {
return this.currentStep.component
},
leftBtns () { // 左边动态生成按钮
if (_.hasIn(this.currentStep, 'buttons.left')) {
return this.currentStep.buttons.left
} else {
return null
}
},
rightBtns () { // 右边动态生成按钮集
if (_.hasIn(this.currentStep, 'buttons.right')) {
return this.currentStep.buttons.right
} else {
return null
}
}
},
/* _.has(object, path)
*检查 path 是否是object对象的直接属性
* object (Object): 要检索的对象。path (Array|string): 要检查的路径path。
* (boolean): 如果path存在,那么返回 true ,否则返回 false。
*/
/* _.trimEnd([string=''], [chars=whitespace])
*从string字符串中移除后面的 空格 或 指定的字符。
*[string=''] (string): 要处理的字符串。[chars=whitespace] (string): 要移除的字符。
*(string): 返回处理后的字符串。
*/
created () {
log.info('--> steps:', this.steps)
this.basePath = this.$route.path
log.info('this.basePath!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', this.basePath)
if (_.has(this.$route.params, 'idx')) { // 这一步就是用编程式导航切换组件 这是关键
this.basePath = _.trimEnd(this.basePath, '/' + this.$route.params['idx'])
}
log.info('--> base path: ', this.basePath)
vEvents.$on('next-step', this.onNext)
vEvents.$on('prev-step', this.onPrev)
vEvents.$on('prev-stopped', this.onPrevStopped)
vEvents.$on('next-stopped', this.onNextStopped)
if(this.aStep){ // 动态切换 子 组件
log.info('存在存在存在存在存在存在存在',this.aStep)
this.active = parseInt(this.aStep)
this.onNext() // 下面定义好的方法 切换上下组件用
} else {
log.info(this.aStep,'aStepaStepaStepaStepaStep')
}
},
beforeDestroy () {
vEvents.$off('prev-step', this.onPrev)
vEvents.$off('next-step', this.onNext)
vEvents.$off('prev-stopped', this.onPrevStopped)
vEvents.$off('next-stopped', this.onNextStopped)
},
methods: {
// 上一步
onPrev () {
if (this.active > 1) {
this.active -= 1
this.$router.push(this.basePath + '/' + this.active)
} else {
this.$router.push(this.fromPath)
}
log.info('--> active: ', this.active)
},
onPrevStopped (v) { // 禁止点击上一步
this.prevStopped = v
},
// 下一步
onNext (step) {
log.info(this.currentView.name, 'this.currentView.name')
switch (this.currentView.name) {
case 'bind-mobile-money':
this.$refs.jinE.judgeValue()
break
case 'input-mi-ma':
log.info('银联支付成功')
this.$refs.jinE.zhifuqueren()
break
default:
break
}
// 这个就是判断当前步 是不是最后一步 不是得话就往下切换组件 到这里整个 切换组件的操作就结束了
if (this.active < this.steps.length) {
this.active += 1
this.$router.push(this.basePath + '/' + this.active)
}
log.info('--> active: ', this.active, this.currentView)
},
onNextStopped (v) { // 禁止点击下一步
this.nextStopped = v
},
onTiaoZhuan (e) { // 动态生成的按钮处理事件
log.info(e,'动态生成的按钮处理事件----flow组件')
switch (e) {
case '充值':
log.info('chongzhi')
this.$router.push({path:'/frame/pay/steps/:1',query:{active: '3'}})
break;
case '取卡':
log.info('quka')
// TODO 其实在 办卡页面这个按钮处就会 自动退卡根本不需要 再 执行下面操作
let cm = new CardMaker()
cm.readTrack().then((result) => {
this.sn = result.Track2
return cm.move(100)
}).catch((error) => {
this.$notify.error({
title: '错误',
message: error.error_msg || error.error_code
})
})
break;
default:
break;
}
}
}
}
</script>
<style scoped>
.panel {
display: flex;
flex-direction: column;
height: 75vh;
overflow: hidden;
color: #303133;
background-color: #fff;
border: 1px solid #ebeef5;
border-radius: .75rem;
box-shadow: 0 0 0.75rem 0.75rem rgba(12, 89, 209, 0.1), 0 0 0.75rem 0.75rem rgba(12, 89, 209, 0.1);
transition: .3s;
}
.step-wrap {
padding: 1rem 0;
width: 100%;
height: 4rem;
}
</style>
从 其他页面跳转的代码:
this.$router.push({path:'/frame/pay/steps/:1',query:{active: '3'}}) // 这里地址后面那个数字 是几都无所谓 只要有就会跳转到 这个页面 重要的是通过 穿过去的active 的值来切换子组件 传3 就会在跳转到该页面之后自动切换到第三个组件。
路由配置:
// router.js
const routes = [{
path: '/',
redirect: '/frame/home'
}, {
path: '/frame',
component: require('./layout/frame.vue').default,
children: [{
path: 'home',
component: require('./view/home.vue').default
}, {
path: 'factory/login',
component: require('./view/factory/login.vue').default
}, { // 办卡
path: 'card/steps/:idx',
component: require('./view/card/steps_card.vue').default,
props: true
}, { // 签约
path: 'sign/way/:idx',
component: require('./view/sign/inser_cart.vue').default,
}, { // 充值
path: 'pay/steps/:idx', // 这个就是跳转到的目标页面 路由
component: require('./view/pay/steps_pay.vue').default,
props: true
},