TypeScript语法中@emit的使用方法及注意事项

下面先说JS传统的this.$emit使用方法,然后对比TS的@emit方法便可一目了然,首先看this.$emit的使用方法。 this.$emit 算是父子通信的一种方法,作用为在子组件可以触发父级函数并且可以传参...

下面先说JS传统的this.$emit使用方法,然后对比TS的@emit方法便可一目了然,首先看this.$emit的使用方法。


this.$emit 算是父子通信的一种方法,作用为在子组件可以触发父级函数并且可以传参,当然这只是其中一种方法,之前总结过Vue子组件调用父组件函数的方法,可以点击查看,并且还有父调子组件的方法供大家参考。


首先回顾下this.$emit的使用方法

父组件

<template>
  <div>
    <child @fatherMethod="fatherMethod"></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethod() {
        console.log('测试');
      }
    }
  };
</script>

 

子组件

<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    methods: {
      childMethod() {
        this.$emit('fatherMethod');
      }
    }
  };
</script>



TypeScript语法中@emit

子组件

<template>
<section>
<el-table :data="tableData">
<el-table-column prop="parentId" label="父级编号"></el-table-column>
<el-table-column label="操作" width="320">
<template slot-scope="scope">
<el-link icon="el-icon-edit" type="primary" @click="editHandle(scope.row)">编辑</el-link>
</template>
</el-table-column>
</el-table>
</section>
</template>
<script lang="ts">
import {
Component,
Emit,
Prop,
Vue
} from "vue-property-decorator";
@Component
export default class DataDictionaryTable extends Vue {
@Prop() private tableData!: [];
//编辑
@Emit("editHandleEmit")
private editHandle(row) {
return row; // return将要传递的值
}
}
</script>

父组件

<ph-table :tableData="tableData" @editHandleEmit="editHandle"></ph-table>
//编辑
editHandle(row: any) {
    console.log(row)
}


使用总结:

1.在ts中首先引用并抛出:

attachments-2021-12-PveGVAy761ad89ea94dca.png


2.@emit使用方法与this.$emit对比, 父级完全一致,区别在于子组件(项目中截图代码,当前为子组件)

attachments-2021-12-tqp1G9pq61ad8b0c763ea.png


看上图注释了一行代码是 this.$emit('closeMainIndex'),目的是触发父级引用当前组件时@closeMainIndex等于的值(值代表父级要被触发的函数,可以与@后相同,也就是@closeMainIndex = “closeMainIndex”),可以参考最上面this.$emit的案例。

注释后调用了一个函数,this.editHandleIndex();在定义函数的上方,有一行@Emit("closemainindex"),此时closemainindex这个值和this.$emit('closeMainIndex')要触发的是一致的,完事。而this.editHandleIndex()这个函数内return的值是要传递的参数.

而使用 this.$emit('closeMainIndex')时,this.$emit('closeMainIndex', 'name', 'value'),这个方法name 和 value两个字符串才是要传递的参数,closeMainIndex触发父级的关键。


注意事项:

1.不论this.$emit('closeMainIndex')还是@Emit("closeMainIndex")都要切记,不要使用驼峰,this.$emit('closemainindex') @Emit("closemainindex")这么写才是对的,一定要全部小写,不要不信邪,今天发这篇文章的目的就是遇到了这个问题,在vue+ts项目中开发环境没问题,打包后线上就触发不了父级函数,也没有报错。其实之前没有在意过驼峰,也没有出现过问题,但这家公司的架子上真实遇到一次,写代码还是要按照规范来。


2.父级需要接收参数时,@closeMainIndex = “closeMainIndex(name, value)”,这么写是错误的,@closeMainIndex = “closeMainIndex”,不要加括号,在js区域中声明closeMainIndex函数时直接接收即可,closeMainIndex(name, value){}



题外拓展(网上找的例子,vue + ts 项目中Emit的用法,与本篇无太大关联,以上内容已经)


要使vue支持ts写法,我们需要用到vue-property-decorator,这个组件完全依赖于vue-class-componet


首先安装:

npm i -D vue-property-decorator

 @Emit(event?: string)

@Emit装饰器接收一个可选参数,作为事件名;如果没有提供这个参数,$emit会将回调函数的camelCase(驼峰式)转为kebab-case(短横线命名),并将其作为事件名;


@Emit会将回调函数的返回值作为第二个参数,如果返回值是一个Promise对象,$emit会将Promise对象状态为resolved之后触发;


@Emit的回调函数的参数,会放在其返回值之后,一起被$emit当作参数使用;


看下面例子:

import { Vue, Component, Emit } from 'vue-property-decorator'
 
@Component
export default class YourComponent extends Vue {
  count = 0
 
  @Emit()
  addToCount(n: number) {
    this.count += n
  }
 
  @Emit('reset')
  resetCount() {
    this.count = 0
  }
 
  @Emit()
  returnValue() {
    return 10
  }
 
  @Emit()
  onInputChange(e) {
    return e.target.value
  }
 
  @Emit()
  promise() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(20)
      }, 0)
    })
  }
}

以上代码等同于:

export default {
  data() {
    return {
      count: 0,
    }
  },
  methods: {
    addToCount(n) {
      this.count += n
      // 将addToCount转成add-to-count
      this.$emit('add-to-count', n)
    },
    resetCount() {
      this.count = 0
      this.$emit('reset')
    },
    returnValue() {
      this.$emit('return-value', 10)
    },
    onInputChange(e) {
      this.$emit('on-input-change', e.target.value, e)
    },
    promise() {
      const promise = new Promise((resolve) => {
        setTimeout(() => {
          resolve(20)
        }, 0)
      })
 
      promise.then((value) => {
        this.$emit('promise', value)
      })
    },
  },
}

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
admin
admin

651 篇文章

作家榜 »

  1. admin 651 文章
  2. 粪斗 185 文章
  3. 王凯 92 文章
  4. 廖雪 78 文章
  5. 牟雪峰 12 文章
  6. 李沁雪 9 文章
  7. 全易 2 文章
  8. 欢喜 0 文章