详情页的文件目录:
Add.vue文件
Detail.vue文件
DetailModify.vue文件
Main.vue文件
param.js文件
一般情况下Main.vue文件肯定是点击菜单项后的入口文件。
至于原因可以参考根据上一章节学习的,点击菜单项 -> 加载的是Main.vue组件。
// 列表页面
pathConfig[`${parent.target}_${child.target}`] = {
auth: child.id,
key: `${parent.target}_${child.target}`,
base:`${parent.target}_${child.target}`,
menu: child,
value: child.menuName,
component: loadComponent(`${parent.target}/${child.target}/Main`)
}
在走读代码的时候看到这样一段代码:
window.pathConfig = pathConfig
将pathConfig挂载在全局的 window 对象上。这样,pathConfig 就可以在浏览器的全局作用域中被访问,即在任何地方都可以通过 window.pathConfig 或直接 pathConfig 来访问这个对象。(类比java类中的全局变量)
那这里me简单的研究一下Main.vue文件:
<my-table ref="table" :name="pageParam.key" :data="list" :cols="cols" :loading="loading" full :summary="summary" :full-param="param"
:page-param="page" @pageChange="pageChange"
:operate="finalOperate" @commandExec="commandExec"
@rowDbClick="rowDbClick" @sortChange="sortChange">
</my-table>
-
ref="table"
:为组件设置引用名,方便后续操作 -
:name="pageParam.key"
:将 pageParam.key 的值绑定到 name 属性 - :data="list" :将 list 数据绑定到表格的数据源
- :cols="cols" :定义表格的列配置
-
:loading="loading"
: 控制表格加载状态 -
:summary="summary"
:提供表格汇总信息
第一个问题:
pageParam的值是怎么来的?
回顾到第二章节,关于详情页的展示部分:
<el-main class="my-main">
<template v-for="item in pathConfig">
<component :key="item.key" :is="item.component" :ref="item.key" :page-param="item"
v-if="isShowTab(item.key)" :class="{ active:isMe(item.key) }"></component>
</template>
</el-main>
然后子组件可以直接通过props进行接收:
props: {
pageParam: {
type: Object,
default: ()=>({})
},
}
第二个问题:
list的值是怎么来的?
created() {
setTimeout(() => {
if (!this.stop) {
this.page.page = 1
this.getList()
}
}, 0)
}
通过this.getList()
方法this.list = res.records可以给list赋值。
在走读代码的时候发现一个比较新鲜的东西:
mixins: [mixinBase(param), mixinTable]
<p style="color: red"> mixins这是个啥玩意?</p>
mixins 是一种用于分发 Vue 组件中可复用功能的灵活方式。通过 mixins,可以将多个组件共用的选项(如数据、方法、生命周期钩子等)提取出来,然后应用到多个组件中,从而提高代码的复用性和可维护性。同时mixins 可以分为局部混入和全局混入。(类比java中的抽象方法和实现类)
所以这也是为什么会在src/config/下面添加mixin文件夹,该文件夹下面都是Vue的混入对象,是Vue组件公用的选项部分。(类似java中有个common文件夹)
第三个问题:
cols的值是怎么来的?
数据来源于param.js文件配置的cols数组:
cols的作用是用来渲染表格的表头的
<template v-for="(col, i) in realCols">
<el-table-column :key="col.key + i" v-if="col.sList" :prop="col.key"
:label="col.valueShow || col.value" :show-overflow-tooltip="col.notShowOverFlow ? false : true"
:sortable="hideSort ? false : col.sort" :min-width="col.width" :align="getAlign(col)"
:header-align="getAlign(col)" :fixed="col.fixed || $variable.fixed.normal">
</el-table-column>
</template>
<hr />
另外看到按钮权限控制的代码:
<el-dropdown class="right" @command="operateCommand">
<my-button>
更多操作<i class="el-icon-arrow-down el-icon--right"></i>
</my-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :disabled="!auth.canEnable" command="enableBatch">批量启用</el-dropdown-item>
<el-dropdown-item :disabled="!auth.canDisable" command="disableBatch">批量禁用</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
el-dropdown-item
是 Element UI 的组件,disabled 属性可以根据 auth.canEnable 的布尔值决定是否禁用该菜单项。
回顾到第二章节,auth是在加载菜单项的时候设置的,可以在配置菜单项的时候->配置菜单项的按钮:
this.$store.commit('setAuth', authObj)
关于点击新增的时候如何弹出新增页面:
<my-drawer class="dialog-form" :show.sync="formDialog.add" :title="pageParam.value + '新增'">
<template slot-scope="{max}">
<add-page v-if="formDialog.add" class="dialog-form" :pageParam="getFormPageParam('Add')"
:dialog-min="!max" @close="formDialog.add = false"></add-page>
</template>
</my-drawer>
使用的是element-ui的el-drawer标签,add-page标签就是上面的Add.vue文件。
另外看到很多使用插槽的代码片段:
<template #top>
</template>
<template #right>
</template>
<template #slot_year="{ props }">
{{ props.row.year }}年{{ props.row.month }}月
</template>
<template slot-scope="{max}">
</template>
<div class="my-table__operate-left">
<slot name="top"></slot>
</div>
<div class="my-table__operate-right">
<slot name="right"></slot>
</div>
<slot :max="max">{{content}}</slot>
插槽有三大类:默认插槽+具名插槽+作用域插槽(类似于java代码里面接入模板引擎文件使用的模板占位符)
插槽就是子组件中提供给父组件使用的一个占位符,父组件可以在这个占位符中填充任何模板代码
如果子组件没有使用插槽,父组件如果需要往子组件中填充模板或者html, 是没法做到的
作用域插槽:作用域插槽其实就是带数据的插槽,即带参数的插槽,简单的来说就是<font color="red">子组件提供给父组件的参数,该参数仅限于插槽中使用</font>,父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容。
具体步骤:
子组件存放一个带数据的插槽
父组件通过 “slot-scope” 来接收子组件传过来的插槽数据,再根据插槽数据来填充插槽的内容
另外一个思考:通过Main.vue可以跳转到Add.vue,可以跳转到DetailModify.vue,Detail.vue的入口在哪里?在DetailModify.vue中找到这样的代码:
<template>
<div class="edit-container">
<template v-if="edit">
<component :is="selfComponent" @update="editChange" modify :page-param="pageParam"
:dialog-min="dialogMin"></component>
</template>
<page-detail v-else @update="editChange" :page-param="pageParam" :dialog-min="dialogMin" :tableKeyData="tableKeyData" @close="$emit('close')"></page-detail>
</div>
</template>
这段代码根据 edit 的布尔值决定Add.vue
组件或Detail.vue
组件。当 edit 为真时,渲染Add.vue
组件内容,否渲染Detail.vue
内容,Detail.vue文件的内容使用了element-ui的el-descriptions和el-descriptions-item渲染。
上面用到了@update
和@close
,分别绑定了update事件(触发条件:组件内部的数据更新时)和close事件(触发条件:用户执行了关闭操作)。
结尾
giao!!!