vue笔记-抽象出组件,父子组件传值的问题,vue地图功能实现

本文详细介绍了在Vue中如何抽象组件以降低代码复杂度,包括创建子组件并导入到父组件中,以及如何通过$emit自定义事件和$ref进行父子组件之间的值传递。同时,文中还分享了在地图功能实现中应用这些技巧的例子。
摘要由CSDN通过智能技术生成

1. 抽象出组件components

在复杂的页面中可以抽象出单个子组件,提供父组件调用或者传值,以减少父组件的复杂度和代码量。

有些项目组要求单个vue不超过400行代码,都是通过抽象组件完成的。

  1. 创建子组件,内容自己写
<template>

</template>

<script>
export default {
    
  data() {
    
  },
  methods: {
    
  }
};
</script>

<style>
</style>

  1. 在父组件中导入子组件
import SelectCoords from "./components/SelectCoords";
  1. <script>增加components元素,命令要求如下
    “select-coords”: SelectCoords代表子组件 要调用就用<select-coords />来表示
    ColumnOrder: 默认用<ColumnOrder />来表示
components: {
   
  "select-coords": SelectCoords,
  ColumnOrder
},
  1. 父组件中使用子组件
<select-coords />

2. 父子组件传值的问题

我来讲解一下子传父的数据传输问题。
举个例子,父组件需要子组件的地图数据,如何获取?

2.1 $emit自定义事件的方法

父子传值第一种方法:子传父,子创建一个按钮,定义一个点击事件,点击事件里用this.$emit方法触发一个自定义事件,并传递一个参数,父组件中监听这个事件并调用处理的方法

  1. 子组件的props属性写好,getCoords就是需要在父组件中调用的方法
props: {
   
  getCoords: {
   
    type: Function,
    required: false
  }
},
  1. 子组件需要定义一个点击事件@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>
  1. 点击后触发一个clickHandler事件,子组件增加一个clickHandler方法
methods: {
   
    clickHandler(e) {
   
      //父子页面传值第一种方法,抛出一个事件
      // console.log(e.point)
      this.point = e.point;
      this.getCoords && this.getCoords(e);
      this.$emit("selected", e.point);
    }
  }
  1. 父组件中在引用的子组件中进行事件监听,加上@selected=“getCoords”
<div>
   <!-- 监听抛出的事件,selectd是自己定义的事件 -->
   <select-coords @selected="getCoords"/>
 </div>
  1. 父组件中,在监听到后触发getCoords事件,方法增加getCoords
getCoords(point) {
   
  const {
    lng, lat } = point;
  this.form.baseCoordinateLatitude = lng;
  this.form.baseCoordinateLongitude = lat;
  this.form.coords = `${
   lng},${
   lat}`;
},

2.2 $ref获取

不推荐,少用。

  1. 在父组件中给子组件添加ref方法
<!-- 增加ref属性 -->
<select-coords ref="SelectCoords" />
  1. 父组件就可以找到子组件,直接使用$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地图调用的代码

  1. $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>

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值