vue 子组件与子组件之间传参

封装可以让整体程序看起来很优雅,但有些问题需要解决,当然这些问题解决之后,开发效率自然就上去了,我的目标就是高效,然后能准点下班。靠时间换取金钱,意义不大。
子组件与子组件之间是不能直接传值的,需要凭借父组件,这个也非常容易理解。
1

1 子组件向父组件传参
查询条件子组件,显示格局条件,如果超过8个,则显示下拉菜单,
子组件通过this.$emit("addCond",item)传参,即子组件可以使用 $emit 触发父组件的自定义事件

<template>
    <div>
        <el-row :gutter="20" >
            <el-col :span="20">
                <span class="title">{{condTitle}}</span>
                <el-button type="text" v-for="item in baseList" :key="item.val" @click="selectGeju(item)">{{item.name}}</el-button>
                <el-dropdown v-if="showMore" style="margin-left:10px;">
                    <span class="el-dropdown-link">
                        更多格局<i class="el-icon-arrow-down el-icon--right"></i>
                    </span>
                    <el-dropdown-menu slot="dropdown" >
                        <el-dropdown-item v-for="item in moreList" :key="item.val" @click.native="selectGeju(item)">{{item.name}}</el-dropdown-item>
                    </el-dropdown-menu>
                </el-dropdown>
            </el-col>
        </el-row>
    </div>
</template>
<script>
export default {
    name: "gj-cond",
    data() {
        return {
            showMore:false,
            baseList:[],
            moreList:[]
        }
    },
    props: {
        condTitle: String,
        gejuList: Array
    },
    methods:{
        selectGeju(item) {
            this.$emit("addCond",item)
        }
    },
    mounted: function(){
        if (this.gejuList.length>8){
            this.showMore = true
            this.baseList = this.gejuList.slice(0,8)
            this.moreList = this.gejuList.slice(8)
        } else{
            this.baseList = this.gejuList
        }
    }
}
</script>
<style lang="less">
    .title {
        display:-moz-inline-box; 
        display:inline-block; 
        width:80px;
    }
    .el-dropdown-link {
        cursor: pointer;
        color: #409EFF;
    }
    .el-icon-arrow-down {
        font-size: 12px;
    }
</style>

2 父组件接受子组件传参
父组件中自定义事件@addCond对应的方法,获取从子组件传过来的参数,通过lodash来判断对象是否存在,如果存在则不用重复条件tag

<template>
    <div>
        <el-row>
            <el-col :span="6" v-for="(bazi,index) in tableData" :key="index" class="text-center">
                <bazi-panel :info="bazi"></bazi-panel>
            </el-col>
        </el-row>
        <el-row class="text-right">
            <el-pagination background layout="prev,pager,next" 
                :total="total" 
                :hide-on-single-page="true"
                @current-change="handleCurrentChange">
            </el-pagination>
        </el-row>
    </div>
</template>
<script>
import BaziPanel from '@/components/BaziPanel'
export default {
    name: "gj-table",
    components: {BaziPanel},
    data() {
        return {
            tableData:[],
            total:0,
            rows:10,
            page:1
        }
    },
    props: {
        cond:Array
    },
    methods: {
         findList() {
            console.log(this.cond)
            this.$store.dispatch("FindGjList", {page:this.page,rows:this.rows}).then(res => {
                if (res.success){
                    this.tableData = res.data.rows
                    this.total = res.data.total
                }
            }).catch(err => {})
        },
        handleCurrentChange: function(currentPage){
            this.page = currentPage
            this.findList()
        }
    },
    mounted: function(){
        this.findList()
    }
}
</script>

3 父组件向另外一个组件传参

<template>
    <div>
        <el-row>
            <el-col :span="6" v-for="(bazi,index) in tableData" :key="index" class="text-center">
                <bazi-panel :info="bazi"></bazi-panel>
            </el-col>
        </el-row>
        <el-row class="text-right">
            <el-pagination background layout="prev,pager,next" 
                :total="total" 
                :hide-on-single-page="true"
                @current-change="handleCurrentChange">
            </el-pagination>
        </el-row>
    </div>
</template>
<script>
import BaziPanel from '@/components/BaziPanel'
export default {
    name: "gj-table",
    components: {BaziPanel},
    data() {
        return {
            tableData:[],
            total:0,
            rows:10,
            page:1
        }
    },
    props: {
        cond:Array
    },
    methods: {
         findList() {
            console.log(this.cond)
            this.$store.dispatch("FindGjList", {page:this.page,rows:this.rows}).then(res => {
                if (res.success){
                    this.tableData = res.data.rows
                    this.total = res.data.total
                }
            }).catch(err => {})
        },
        handleCurrentChange: function(currentPage){
            this.page = currentPage
            this.findList()
        }
    },
    mounted: function(){
        this.findList()
    }
}
</script>

接下来要做的就是将查询条件,传给vue2 自定义card分页子组件,子组件定义props属性

<gj-table :cond="selectConds" ref="gjTable"></gj-table>

4 父组件触发子组件事件
this.$refs.gjTable.findList(),通过$refs触发子组件中的事件
5 页面跳转的问题
5.1 Cannot read property ‘ob’ of undefined
出现这个问题,页面跳转跳不动了,需要强制刷新一下才可以,这是为什么呢?
vue 报错 Cannot read property ‘ob’ of undefined的解决方法
我检查我的页面,确实有一个页面是data(){}的情况,补上data() {return {}}就没有这个问题了

Vue2.0 之 vue Cannot read property ‘ob’ of undefined 异常(back报错)
这种情况倒是有,但这拿到不是一种很容易想到的页面方式吗,难道非得要写到子组件中吗?

<el-col :span="6" v-for="(sample,index) in tableData" :key="index" class="text-center">
       <ml-panel :info="sample"></ml-panel>
 </el-col>
vue.min.js:6 TypeError: Cannot read property '__ob__' of undefined
    at a.e.$destroy (vue.min.js:6)
    at destroy (vue.min.js:6)
    at b (vue.min.js:6)
    at b (vue.min.js:6)
    at a.__patch__ (vue.min.js:6)
    at a.e.$destroy (vue.min.js:6)
    at destroy (vue.min.js:6)
    at b (vue.min.js:6)
    at b (vue.min.js:6)
    at a.__patch__ (vue.min.js:6)

5.2 Cannot read properties of undefined (reading ‘jiaziStr’)
子组件读不到属性,并不一定是props的问题

<el-card class="gong">
        <div slot="header" class="header">
            <span>{{gong.jiaziStr}}</span>
            <span style="margin-left:auto;">{{gong.gongStr}}</span>
        </div>
        
props: {
        gong: Object
    },
  

看看引用 <gong-panel :gong="gongs.chou"></gong-panel>,下面的这种方式是不对的

data() {
        return {
            gongs:{}
        }
    },

正确的方式应该为,这样就没有问题了

data() {
        return {
            gongs:{zi:{},chou:{},yin:{},mao:{},chen:{},si:{},wu:{},wei:{},shen:{},you:{},xu:{},hai:{}}
        }
    },

5.3 子组件获取不到值
参考解决vue组件props传值,对象获取不到的问题
这里可以看到配置文件this.zpPan.struct = {qiangruo:this.zpPan.zpBazi.qiangruo}这样赋值,就解决了子组件获取不到值得问题

paipan(formName){
            this.$refs[formName].validate(valid=>{
                if (valid){
                    this.cond.hour = this.cond.hourTime.join(':')
                    this.$store.dispatch("Paipan"+this.cond.ylnl,this.cond).then(res=>{
                        this.zpPan.zpBazi = res.data.zpBazi
                        this.zpPan.daYuns = res.data.daYuns
                        // 强弱
                        this.zpPan.struct = {qiangruo:this.zpPan.zpBazi.qiangruo}
                        console.log('八字结构:',this.zpPan.struct)
                        // 大运流年
                        this.zpPan.config.preJieQi = res.data.preJieQi;
                        this.zpPan.config.preJieQiTime = res.data.preJieQiTime;
                        this.zpPan.config.nextJieQi = res.data.nextJieQi;
                        this.zpPan.config.nextJieQiTime = res.data.nextJieQiTime;
                        this.zpPan.config.qyzs = res.data.qyzs;
                        //
                    }).catch(err=>{
                    })
                }
            })
        },
    },

6 vue3中传达的一些问题

<pg-panel :info="yjBazi" :sex="sex"></pg-panel>
const yjBazi = ref({})
const paipan = async () =>{
    condVis.value = false;
    let res;
    let year;
    sex.value = sexRef.value.selected.currentLabel
    switch(condForm.value.type){
        case '1':
            res = await window.$apis.yjrule.solarPp({
                birthday:condForm.value.birthday,sex:condForm.value.sex,hour:`${condForm.value.hour}:${condForm.value.minute}`
            });
            year = condForm.value.birthday.substring(0,4)
            break;
        case '2':
            res = await window.$apis.yjrule.lunarSj({
                year:condForm.value.year,sex:condForm.value.sex,month:condForm.value.month,day:condForm.value.day
                ,hour:`${condForm.value.hour}:${condForm.value.minute}`
            });
            year = condForm.value.year
            break;
        case '3':
            res = await window.$apis.yjrule.baziSj({
                bazi:condForm.value.bazi,sex:condForm.value.sex
            });
            year = condForm.value.ftYear
            break;
    }
    
    if (res.success) {
        yjBazi.value = res.data.zpBazi;
    } else {
        window.$message.error(res.msg);
    }
}

但显示的结果如图所示,问题出现在哪里了呢?
1
原因是因为你的组件没有引入

import pgPanel from './pgPanel.vue';
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值