外部定义的JS,引入后Vue报错ReferenceError: h is not defined

一、问题环境

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中提到的解决方法是在vue.config.js中添加一些配置,其中使用了webpack的ProvidePlugin插件来提供全局的jquery变量。这样就能解决报错"ReferenceError: $ is not defined"的问题。中提到的报错提示不是由于没有使用lib:["dom"]造成的,而是在类型注释中使用了MouseEvent。在这种情况下,没有问题的。中指出,如果项目中引用了.eslintrc.js文件,还需要在文件的module.exports中为env添加一个键值对jquery: true,然后重新启动项目。这样也可以解决报错"ReferenceError: $ is not defined"的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Vue引入JQuery报错caught ReferenceError: jQuery is not defined](https://blog.csdn.net/qq_46034741/article/details/130032090)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [vue ssr 报错 ReferenceError: MouseEvent is not defined / window is not defined 等等](https://blog.csdn.net/qq_28550263/article/details/130152398)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Vue小知识: $ is not defined错误解决](https://blog.csdn.net/weixin_43945983/article/details/88294052)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值