一、问题环境
使用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.$createElementreturn [{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,大多数的问题,实际上开发者们都会遇到,通过搜索关键词,去看下面的回答,解决问题、完成开发任务之后,可以再回过头来学习思考,看看问题本身,为什么会出现,等等。