封装可以让整体程序看起来很优雅,但有些问题需要解决,当然这些问题解决之后,开发效率自然就上去了,我的目标就是高效,然后能准点下班。靠时间换取金钱,意义不大。
子组件与子组件之间是不能直接传值的,需要凭借父组件,这个也非常容易理解。
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);
}
}
但显示的结果如图所示,问题出现在哪里了呢?
原因是因为你的组件没有引入
import pgPanel from './pgPanel.vue';