前端学习笔记(二)
1.解决数据字典带出问题
当前效果:
需求效果

index.vue(原生代码,未使用公共组件)
<template>
<el-table-column
label="办公地点"
:show-overflow-tooltip="true"
// formatter调用方法
:formatter="dictFormat"
prop="place"
align="center"
min-width="100"
></el-table-column>
</template>
<script>
// 引入数据字典js方法
import SysDict from '@/api/business/sys/sysDict.js';
export default {
data() {
return {
// 初始化变量
dict: {},
dictVal: 'place'
}
},
created() {
// 调方法
this.getDict(this.dictVal);
},
methods: {
// 获取表格中需要使用的数据字典
async getDict(val) {
let catCodes = [val];
// 等待数据字典加载完毕 调用引入的SysDict里的方法
let res = await SysDict.mapDictByCatCodes(catCodes);
if (res.success === true) {
this.dict = res.data;
}
},
dictFormat(cellValue) {
if (cellValue.place == this.dict[this.dictVal][cellValue.place].dictCode) {
return this.dict[this.dictVal][cellValue.place].dictName;
} else {
return '';
}
}
}
}
</script>
2.解决element-ui输入框按回车刷新页面和不搜索问题
// 页面有两个组件都有搜索功能 @submit.native.prevent关闭刷新
<el-form class="sBar" :inline="true" size="mini" @submit.native.prevent>
<el-form-item>
// @keyup.enter.native="getUserData" element-ui使用的按下回车调用方法
<el-input v-model="req.search" placeholder="姓名或工号" @keyup.enter.native="getUserData"></el-input>
</el-form-item>
<el-form-item>
<el-button class="line" @click="getUserData">查询</el-button>
</el-form-item>
</el-form>
3.前后端交互查询数据显示在列表中
需求效果

(1)后端方法
service层:PrjTrackService.java
@Service
public class PrjTrackService extends ServiceImpl<PrjTrackMapper, PrjTrack> {
public List<PrjTrack> getAllTrackList(String cstmPrjCode){
return this.baseMapper.selectList(new QueryWrapper<PrjTrack>().lambda().eq(PrjTrack::getCstmPrjCode, cstmPrjCode));
}
}
controller层:PrjTrackController.java
@Api(value = "PrjTrackController", tags = {"PrjTrack接口"})
@RequestMapping("/PrjTrack")
@RestController
public class PrjTrackController extends BaseController {
private static final Logger LOG = LoggerFactory.getLogger(PrjTrackController.class);
@Autowired
private PrjTrackService prjTrackService;
@ApiOperation("根据项目编号或客户编号查询某项目所有的数据")
@GetMapping(value = "/listAllTrack")
public ResponseData<Object> getAllTrackList(String cstmPrjCode){
return ResponseData.success(prjTrackService.getAllTrackList(cstmPrjCode));
}
}
2.前端页面
track.js
import http from '@/utils/serviceHttp';
export default {
//获取跟踪数据
getAllTrack: cstmPrjCode => {
http.sales.get('/PrjTrack/listTrack', { cstmPrjCode: cstmPrjCode });
}
};
组件排序: 爷组件(A层)–父组件(B层)–子组件(C层)
(1)A层:index.vue
<template>
<div class="layout vflex" v-loading="loading" v-keydown:search="'enter'">
<el-row :gutter="20" class="shrink1 end">
<el-col :span="24" style="height: 100%;">
<el-card class="vflex h4">
<div class="clearfix h3" slot="header">
<span class="co-rect">{{ alias }}</span>
</div>
<im-table
class="getHeight vflex singlePage"
ref="im_table"
api="/im-gateway/im-project/PrjCustomer/sale/search"
http_method="get"
:table_header="tableHeader"
:show_operate="true"
@cell-click="cell_click"
>
<template v-slot:operate="{ row }">
// 点击查看编辑调用show方法显示组件
<el-link type="primary" @click.stop="show(row)">查看</el-link>
<template v-if="btnShow">
<el-link type="primary" @click.stop="edit(row)">编辑</el-link>
<el-link type="primary" @click.stop="track(row, 'edit')">客户跟进</el-link>
</template>
<template v-if="!btnShow">
<el-link type="primary" @click.stop="track(row, 'show')">客户跟进</el-link>
</template>
</template>
</im-table>
</el-card>
</el-col>
</el-row>
// is_show_addDialog默认为false 不显示
<el-dialog
:visible.sync="is_show_addDialog"
:title="dialogTitle"
width="70%"
class="send-dialog"
v-dialogDrag
:before-close="close"
:close-on-click-modal="false"
custom-class="min-form-dialog fit "
>
// 4.传参给子组件(B层), :[子组件中的props中接收] = "[父组件要传入子组件的参数或属性]"
<cust-popup
v-if="is_show_addDialog"
// ☆☆☆
:form_param="popupParam"
/>
</el-dialog>
</div>
</template>
<script>
import IMTable from '@/components/imTable/imTable.vue';
// 1.引入子组件
import CustPopup from './components/cust-popup.vue';
export default{
name: 'my-client',
components: {
'im-table': IMTable,
// 2.在此处将组件重命名,自定义组件,即可以使用<cust-popup />
'cust-popup': CustPopup
},
data() {
return {
// 3.初始化要用的变量
is_show_addDialog: false,
popupParam: {},
customerCode: ''
}
},
method() {
// 点击调用查看方法
show(param) {
this.popupParam = param; // param为点击查看获取到的整行数据,将param赋值给popupParam传给B层
this.is_show_addDialog = true; // 显示表单dialog
}
}
}
</script>
(2)B层:cust-popup.vue 管理3个小组件在一个表单中显示
效果:联系人、项目、时间线,拆分为3个子组件

<template>
<div class="layout vflex" v-loading="loading">
<cust-form v-model="formData.main" :edit_type="edit_type" :edit_param="edit_param" @close="close" @refresh_main="getMainData" />
<fieldset>
<legend>联系人</legend>
<contacts v-model="formData.contacts" :edit_type="edit_type" :edit_param="edit_param" @close="close" />
</fieldset>
<fieldset>
<legend>项目</legend>
<project ref="proj" v-model="formData.project" :edit_type="edit_type" :edit_param="edit_param" @close="close" />
</fieldset>
// 以上仅为演示效果
<fieldset>
<legend>时间线</legend>
// ※※※ 4.将参数传给C层: 从A层接收来的,在props中定义的form_param传给C层,C层以edit_param接收
<form-track v-model="formData.track" :edit_param="form_param" ref="track_table" @close="close" />
</fieldset>
<div class="footbutton">
<el-button @click="close" class="line">取消</el-button>
<el-button v-if="edit_type !== 'info'" @click="submit" type="primary">提交</el-button>
</div>
</div>
</template>
<script>
// 1.引入组件依赖
import Track from './cust-form-track.vue';
export default {
name: 'cust-popup',
components: {
// 2.命名组件 <form-track />
'form-track': Track
},
props: {
// 3.从A层☆☆☆处传入的数据,在props中接收,form_param是一行数据的集合,包含多种属性值
form_param: {
type: Object,
required: false,
default: () => {}
}
},
data() {
return {
// 初始化值
loading: false,
formData: {
track: []
}
}
}
}
(3)C层:cust-form-track.vue,表单具体内容,获取表单data都是在此层显示
<template>
<div class="layout vflex">
<im-table
style="height: 260px;"
// $$$地址
ref="im_table_track"
// 定位到上面controller层的listAllTrack方法
api="/im-gateway/im-sales/PrjTrack/listAllTrack"
// get请求
http_method="get"
// 表头数据
:table_header="tableHeader"
></im-table>
</div>
</template>
<script>
// 1.引入im-table组件
import IMTable from '@/components/imTable/imTable.vue';
export default {
name: 'cust-form-track',
components: {
// 2.定义组件,可以<im-table />形式使用
'im-table': IMTable
},
props: {
// 3.从B层中的※※※处传入的参数,在此接收并可以用this调用参数的属性
edit_param: {
type: Object,
required: false,
default: () => {}
}
},
data() {
return {
// 初始化值
/** 客户跟进数据 */
trackReport: [],
/** 客户跟进表头 */
tableHeader: []
};
},
created() {
this.initData();
},
mounted() {
// 点击查看时调用该方法
this.getTrackReport();
},
methods: {
initData() {
// 表头数据
this.tableHeader = [
{
prop: 'customerName',
label: '客户名称',
width: 150,
show: true
},
{
prop: 'visitMode',
label: '拜访方式',
width: 150,
show: true
},
{
prop: 'visitors',
label: '拜访对象',
width: 150,
show: true
},
{
prop: 'visitTime',
label: '拜访时间',
width: 150,
show: true
},
{
prop: 'visitContents',
label: '拜访内容',
width: 'auto',
show: true
},
{
prop: 'rmk',
label: '备注',
width: 150,
show: true
}
];
},
// ☆ 重点,通过传入的cstmPrjCode(此处是customer编码)来筛选数据
/** 获取项目跟进 */
getTrackReport() {
// 筛选条件 = this.传来的参数.customerCode属性
this.cstmPrjCode = this.edit_param.customerCode;
// $refs后对应im-table组件中的$$$处地址
// this.$refs.地址.getData方法({ 右边的this.cstmPrjCode赋值给左边的cstmPrjCode,使用这个cstmPrjCode进行筛选 })
this.$refs.im_table_track.getData({ cstmPrjCode: this.cstmPrjCode }, data => {
// ※数据库中没有存customerName属性,但是传来的edit_param参数是有这条属性值的,所以使用forEach循环给data循环添加customerName属性值,此处属性值对应表头中的客户名称prop
data.forEach(x => (x.customerName = this.edit_param.customerName));
//(x.表客户名称 = this.传入的参数.客户名称属性)
});
}
}
};
</script>
4.导出表数据为excel案例
public void exportModelRunStatistics(String startTime,String endTime,String unitName) throws UnsupportedEncodingException{
List<ModelRunStatistics> result = modelRunStatisticsService.queryExportedModelRunStatistics(startTime,endTime,unitName);
String[] columnNames = new String[]{"模型名称","统计年月","单位","专业","运行次数"};
String fileName="模型监控运行.xls";
if (result==null) {
result = new ArrayList<ModelRunStatistics>();
}
//可通过通用方法实现,但由于已经写好,而且select * 所以自定义导出。
exportExcel(fileName,columnNames,result);
}
private void exportExcel(String fileName,String[] columnNames,List<ModelRunStatistics> list) throws UnsupportedEncodingException{
fileName= URLEncoder.encode(fileName, "UTF-8");
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
// 定义一个新的工作簿
HSSFWorkbook wb = new HSSFWorkbook();
// 创建一个Sheet页
HSSFSheet sheet = wb.createSheet("products");
sheet.setDefaultRowHeight((short) (2 * 256));//设置行高
sheet.setColumnWidth(0, 4000);//设置列宽
sheet.setColumnWidth(1,4000);
sheet.setColumnWidth(2,4000);
sheet.setColumnWidth(3,4000);
sheet.setColumnWidth(11,4000);
sheet.setColumnWidth(12,4000);
sheet.setColumnWidth(13,4000);
HSSFFont font = wb.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 16);
//获得表格第一行
HSSFRow row = sheet.createRow(0);
HSSFCell cell;
//根据需要给第一行每一列设置标题
for (int i = 0; i < columnNames.length; i++) {
cell = row.createCell(i);
cell.setCellValue(columnNames[i]);
}
HSSFRow rows;
HSSFCell cells;
//循环后台拿到的数据给所有行每一列设置对应的值
for (int i=0;i<list.size();i++){
// 在这个sheet页里创建一行
rows = sheet.createRow(i+1);
// 该行创建一个单元格,在该单元格里设置值
cells = rows.createCell(0);
cells.setCellValue(list.get(i).getModelName());
cells = rows.createCell(1);
cells.setCellValue(list.get(i).getStatisticsDate());
cells = rows.createCell(2);
cells.setCellValue(list.get(i).getUnitName());
cells = rows.createCell(3);
cells.setCellValue(list.get(i).getTypeName());
cells = rows.createCell(4);
cells.setCellValue(String.valueOf( list.get(i).getRunNum()));
}
OutputStream out=null;
try {
out = response.getOutputStream();
//response.getWriter();
wb.write(out);
}catch (IOException e){
e.printStackTrace();
}finally {
try {
out.close();
wb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5.在日期区间选择器限制中添加自调用方法
<template>
<el-col :span="10">
<el-form-item label="开始时间:" size="medium">
<el-date-picker
v-model="startDate"
format="yyyy-MM"
type="month"
placeholder="选择月份"
:picker-options="firstPickerOption"
>
</el-date-picker>
</el-form-item>
</el-col>
</template
<script>
import { addYear } from "@/plugins/common/dateUtils.js";
export default {
name: "manual-access",
data() {
return {
startDate: "",
beforeDate: "",
// 只可以选本月之前的 自调用,将this的作用域改为可以调用外部变量
firstPickerOption: {
disabledDate:(function(_this){
return function(time){
return (time.getTime() < _this.beforeDate) || (time.getTime() > Date.now());
};
})(this)
},
};
},
created() {
this.beforeDate = addYear(new Date(), -1);
},
};
</script>
// 从api中引入的addYear()方法
//日期添加年份
export function addYear(curDate,years){
var date = new Date(curDate);
date.setFullYear(date.getFullYear() + years);
if (date.getMonth() < curDate.getMonth())
date.setDate(0);
return date;
}
6.子组件调用父组件中的方法
1.父组件页面,调用子组件dialog
<el-dialog
:visible.sync="is_show_accessDialog"
:title="dialogTitle"
>
// ☆ @传给子组件 = '方法名'
<manual-access @closeAccess='closeManual' v-if="is_show_accessDialog" />
</el-dialog>
<script>
export default {
name: 'model_function',
data () {
return {}
},
components: {
// 引入子组件
'manual-access': ManualAccess
},
methods: {
// 关闭子组件
closeManual() {
this.is_show_accessDialog = false;
}
}
</script>
2.子组件页面
<el-button class="mybtn" size="medium" @click="cancel">取消</el-button>
<script>
name: "manual-access",
components: {},
data() {
return {}
},
methods: {
// 关闭组件
cancel() {
// 通过$emit调用父组件中的方法,方法名与☆中@ 后的方法名对应
this.$emit("closeAccess");
}
},
</script>
1万+

被折叠的 条评论
为什么被折叠?



