【问题标题】:Invalid attempt to destructure non-iterable instance对不可迭代实例的解构尝试无效
【发布时间】:2021-02-10 09:03:09
【问题描述】:

我已经问过这个问题,但我认为标题是错误的。

我是 VueJs 的新手,我使用 vue-aplayer 在我的网站上播放音频文件。播放器需要资产文件夹中的 svg 图标,但运行时出现错误。

const requireAssets = require.context('../assets', false, /\.svg$/)
  console.log(requireAssets.keys())
  const SVGs = requireAssets.keys().reduce((svgs, path) => {
    const inlineSvg = requireAssets(path)
    const [raw, viewBox, d] = inlineSvg.match(/^<svg.+?viewBox="(.+?)".*><path.+?d="(.+?)".*><\/path><\/svg>$/)

    svgs[path.match(/^.*\/(.+?)\.svg$/)[1]] = {
      viewBox,
      d
    }
    return svgs
  }, {})

它显示的错误是

app.js:6489 Uncaught TypeError: Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.
    at _nonIterableRest (app.js:6489)
    at _slicedToArray (app.js:6487)
    at app.js:6514
    at Array.reduce (<anonymous>)
    at Module../node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue-aplayer/components/aplayer-icon.vue?vue&type=script&lang=js& 

我记录了 requireAssets,它正在获取类似的值

0: "./loading.svg"
1: "./lrc.svg"
2: "./menu.svg"
3: "./no-repeat.svg"

我尝试使用 keys.map() 和 Object.keys(requireAssets).map 但没有什么能接近解决方案。如果我注释图标导入代码,播放器加载正常但没有图标。

整页代码:

<template>
  <svg xmlns:xlink="http://www.w3.org/1999/xlink" height="100%" version="1.1" :viewBox="svg.viewBox" width="100%"
       :style="style">
    <use xlink:href="#aplayer-${type}"></use>
    <path class="aplayer-fill" :d="svg.d"></path>
  </svg>
</template>

<script>
  const requireAssets = require.context('../assets/', false, /\.svg$/)
  // console.log(requireAssets.keys())
  console.log(requireAssets.keys())
  const SVGs = requireAssets.keys().reduce((svgs, path) => {
    const inlineSvg = requireAssets(path)
    const svgMatches = inlineSvg.match(/^<svg.+?viewBox="(.+?)".*><path.+?d="(.+?)".*><\/path><\/svg>$/)
    if(!svgMatches) return [];
    const [raw, viewBox, d] = svgMatches
    svgs[path.match(/^.*\/(.+?)\.svg$/)[1]] = {
      viewBox,
      d
    }
    return svgs
  }, {})

  export default {
    props: ['type'],
    computed: {
      svg () {
        let icon = this.type
        if (this.type === 'prev' || this.type === 'next') {
          icon = 'skip'
        }
        return SVGs[this.type] || {}
      },
      style () {
        if (this.type === 'next') {
          return {
            transform: 'rotate(180deg)',
          }
        }
      }
    }
  }
</script>

【问题讨论】:

  • inlineSvg.match(...) 可能返回 null
  • 我赞成你的回答,但我不明白。您需要有关代码的更多信息吗? PS。它返回 null 但我不知道为什么。

标签: javascript arrays vue.js svg vuejs2


【解决方案1】:

如果您的正则表达式与 svg 语法不匹配,它将返回 null。所以你应该在解构之前测试你的结果以避免运行时错误。

const requireAssets = require.context('../assets', false, /\.svg$/)
  console.log(requireAssets.keys())
  const SVGs = requireAssets.keys().reduce((svgs, path) => {
    const inlineSvg = requireAssets(path)
    const svgMatches = inlineSvg.match(/^<svg.+?viewBox="(.+?)".*><path.+?d="(.+?)".*><\/path><\/svg>$/)
    if(!svgMatches) return [];
    const [raw, viewBox, d] = svgMatches
    svgs[path.match(/^.*\/(.+?)\.svg$/)[1]] = {
      viewBox,
      d
    }
    return svgs
  }, {})

【讨论】:

  • 我试过了,它加载了播放器,但没有加载它应该导入的图标。我将通过编辑我的问题发布整个代码以便于理解。
猜你喜欢
  • 1970-01-01
  • 2021-10-10
  • 2016-12-14
  • 2020-03-10
  • 1970-01-01
  • 2017-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多