一、问题环境

使用Ant-design-vue组件库的Vue2项目。

二、问题描述

原期望减少单页面中的代码,于是在每个路由单Vue页面中的data()函数中抽离表格表头的配置columns数组到外部JS,通过export暴露为引用对象,再经过import调用进页面使用,但是控制台报错ReferenceError: h is not defined。

三、问题解决

蚂蚁文档中实际上是没有提到,customRender是需要Vue的this和this.$createElement的,只书写了使用,并且没有进行对h实例的自动注入。而写在Vue的data()函数中,Vue的编辑器会自动为其加入h的定义。

所以我们只需要想办法解决拿不到this和this.$create的问题即可,并且就算它不报错h is not defined,我们也一样需要想办法传递this给外部JS。因为我们在表格等组件中,一定会遇到有操作栏的情况,会用到button按钮,点击调用的函数也是存在在this中的。

那么我们期望传递this给外部JS文件,因为要传参,所以这个JS一定得是一个函数,不可以再是单纯抽离出去的数组或对象。

OK,我们现在明白了原因和解决方向,举个简单的代码例子:

// 这里是我们抽离出去的columns
// 文件路径是单页面同级的utils文件夹下的index.js和columns.js

// columns.js
const columns = cxt => {
  // cxt就是传递进来的this,可以往下看下个代码块,那里是Vue的文件,我们会在那里把this传递进来
  // 所以在拿到this的情况下,我们需要使用$createElement来创建h的定义
  // 如果你使用了eslint来限制你得代码规范,那么要把下面的注释也写进去

  /* eslint-disable-next-line */
  const h = cxt.$createElement

  return [
    {
      title: '余额',
      dataIndex: 'money',
      customRender: (text, record) => {
        if (!text && text !== 0) return ''
        return <span>{Number(text).toFixed(2)}</span>
      }
    },
    {
      title: '考勤',
      dataIndex: 'workDays',
      customRender: (text, record) => {
        if (!text && text !== 0) return ''
        // 这里注意的是,我们的参数cxt就是传递来的this
        // 那么我们期望调用页面中的函数,就是cxt.函数名()来调用即可
        return <a-button type="link" onClick={e => cxt.openCalendar(record, e)}>
          {text}
        </a-button>
      }
    },
    // 多余的数据就不写了,上面两个例子数据就够了
    {...}
  ]
}

export {
  columns
}


// index.js
import { columns } from './columns'
import ...
import ...

const dataConfigs = {
  columns,
  ...
}

export default dataConfigs
// 其他不重要的代码,以省略号形式越过
<template>
  // 这是我封装的ant-design-vue的table组件
  // 它接收原本就存在的一些属性和配置
  // 同时也可以接收一些自定义的slot和配置
  // 我们只需要知道它跟很多组件一样,接收一个数组属性columns作为渲染表头
  <SearchTable
    ...
    columns="columns"
  />
</template>

<script>
// 接收外部暴露出来的js文件
import dataConfigs from './utils'

export default {
  name: 'xxx',
  ...
  // 这是重要的地方,我们需要在computed钩子中传递this给外部JS函数
  computed: {
    columns() {
      return dataConfigs.columns(this)
    }
  }
}
</script>

 四、问题解决途径

这个项目实际上是一年之前的项目,最近又新的迭代,所以重新将代码切分支pull下来,发现很多冗余代码和无必要的代码书写,本来两行代码能搞定,却为了所谓的“健壮性”写了好几行。

这个columns的抽离,一年前也报了h is not defined,自己排查不出来,所以只能都堆在单页面的data()函数里。一年之后算是成长了,不止是知识在增长,解决问题的途径也在变多。比如:GitHub的issues。

当你在使用一个node_modules包时,你要知道的是,组件库一样是别人在开发后通过node发布给别人使用的,那么就意味着,他们的代码也是有一些没考虑到的地方的。就比如这里的h定义问题。那么在你遇到问题的时候,你应该先想起去他们的Github仓库下查看issues,大多数的问题,实际上开发者们都会遇到,通过搜索关键词,去看下面的回答,解决问题、完成开发任务之后,可以再回过头来学习思考,看看问题本身,为什么会出现,等等。

Logo

前往低代码交流专区

更多推荐