1. 抽象出组件components
在复杂的页面中可以抽象出单个子组件,提供父组件调用或者传值,以减少父组件的复杂度和代码量。
有些项目组要求单个vue不超过400行代码,都是通过抽象组件完成的。
- 创建子组件,内容自己写
<template>
</template>
<script>
export default {
data() {
},
methods: {
}
};
</script>
<style>
</style>
- 在父组件中导入子组件
import SelectCoords from "./components/SelectCoords";
<script>
增加components元素,命令要求如下
“select-coords”: SelectCoords代表子组件 要调用就用<select-coords />
来表示
ColumnOrder: 默认用<ColumnOrder />
来表示
components: {
"select-coords": SelectCoords,
ColumnOrder
},
- 父组件中使用子组件
<select-coords />
2. 父子组件传值的问题
我来讲解一下子传父的数据传输问题。
举个例子,父组件需要子组件的地图数据,如何获取?
2.1 $emit自定义事件的方法
父子传值第一种方法:子传父,子创建一个按钮,定义一个点击事件,点击事件里用this.$emit方法触发一个自定义事件,并传递一个参数,父组件中监听这个事件并调用处理的方法
- 子组件的props属性写好,getCoords就是需要在父组件中调用的方法
props: {
getCoords: {
type: Function,
required: false
}
},
- 子组件需要定义一个点击事件@click=“clickHandler”
<baidu-map class="bm-view" :center="center" :zoom="zoom" :scroll-wheel-zoom="true" @click="clickHandler">
<bm-marker v-if="!!point" :position="point"></bm-marker>
</baidu-map>
- 点击后触发一个clickHandler事件,子组件增加一个clickHandler方法
methods: {
clickHandler(e) {
//父子页面传值第一种方法,抛出一个事件
// console.log(e.point)
this.point = e.point;
this.getCoords && this.getCoords(e);
this.$emit("selected", e.point);
}
}
- 父组件中在引用的子组件中进行事件监听,加上@selected=“getCoords”
<div>
<!-- 监听抛出的事件,selectd是自己定义的事件 -->
<select-coords @selected="getCoords"/>
</div>
- 父组件中,在监听到后触发getCoords事件,方法增加getCoords
getCoords(point) {
const {
lng, lat } = point;
this.form.baseCoordinateLatitude = lng;
this.form.baseCoordinateLongitude = lat;
this.form.coords = `${
lng},${
lat}`;
},
2.2 $ref获取
不推荐,少用。
- 在父组件中给子组件添加ref方法
<!-- 增加ref属性 -->
<select-coords ref="SelectCoords" />
- 父组件就可以找到子组件,直接使用$ref调用
我这里是在点击确定按钮的时候取出子组件的数据,为form表中的元素赋值,然后关闭对话框。
// 新增和修改时点击确定按钮时
ok() {
//父子传值第二种方法:$ref方法,少用。
//给引用的子组件加上ref,然后可以直接在父组件调用子组件的内容。
if (this.$refs.SelectCoords.coords()) {
const {
lng, lat } = this.$refs.SelectCoords.coords();
this.form.baseCoordinateLatitude = lng;
this.form.baseCoordinateLongitude = lat;
this.form.coords = `${
lng},${
lat}`;
this.closeMap();
}
},
2.3 附上vue地图调用的代码
- $emit自定义组件方法
子组件SelectCoords.vue
/*
* @Author: wh
* @Date: 2020-03-01 16:27:50
* @Last Modified by: wh
* @Last Modified time: 2020-03-02 16:09:40
*/
<template>
<baidu-map class="bm-view" :center="center" :zoom="zoom" :scroll-wheel-zoom="true" @click="clickHandler">
<bm-marker v-if="!!point" :position="point"></bm-marker>
</baidu-map>
</template>
<script>
export default {
props: {
getCoords: {
type: Function,
required: false
}
},
data() {
return {
center: {
lng: 118.794373, lat: 32.048494 },
zoom: 11,
point: null
};
},
methods: {
clickHandler(e) {
//父子页面传值第一种方法,抛出一个事件
// console.log(e.point)
this.point = e.point;
this.getCoords && this.getCoords(e);
this.$emit("selected", e.point);
},
// 父子组件传值第二种方法,子组件中预留的方法供父组件调用
// coords() {
// return this.point;
// }
}
};
</script>
<style>
.bm-view {
width: 100%;
height: 300px;
}
</style>
父组件index.html
/*
* @Author: wh
* @Date: 2020-03-01 16:22:49
* @Last Modified by: wh
* @Last Modified time: 2020-03-02 16:06:19
*/
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
<el-form-item label="基地编号" prop="baseNumber">
<el-input
v-model="queryParams.baseNumber"
placeholder="请输入基地编号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="基地名称" prop="baseName">
<el-input
v-model="queryParams.baseName"
placeholder="请输入基地名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="基地地址" prop="baseAddress">
<el-input
v-model="queryParams.baseAddress"
placeholder="请输入基地地址"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="基地坐标经度" prop="baseCoordinateLongitude">
<el-input
v-model="queryParams.baseCoordinateLongitude"
placeholder="请输入基地坐标经度"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="基地坐标纬度" prop="baseCoordinateLatitude">
<el-input
v-model="queryParams.baseCoordinateLatitude"
placeholder="请输入基地坐标纬度"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>-->
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['web:BaseManagement:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['web:BaseManagement:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['web:BaseManagement:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['web:BaseManagement:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="openTable"
v-hasPermi="['web:BaseManagement:export']"
>设置列表字段</el-button>
</el-col>
</el-row>