You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Vue中使用TextScrambler组件报错:length未定义求助

解决Vue组件中使用TextScrambler包的"TypeError: Cannot read property 'length' of undefined"错误

嘿,我仔细看了你的代码,很快就发现了问题所在——这是几个常见的小失误导致的,让我一步步帮你解决:

问题根源

  1. 变量名不匹配:你在randomChar方法里使用this.chars来获取随机字符集,但组件props里定义的字符集属性是scrambleCharacterSet,根本不存在chars这个属性!当代码尝试访问this.chars.length时,this.chars是undefined,直接抛出了你看到的错误。
  2. 未处理undefined边界情况:监听text变化时,第一次触发的oldValue可能是undefined,直接拼接字符串会出问题;同时props的text没有设置默认值,初始状态也可能是undefined。
  3. 导入路径可能错误:你写了import TextScrambler from 'text-scrambler',但看起来你是自己写了同名本地组件,这会导致导入冲突。

修复步骤

1. 修正字符集变量名

把randomChar方法里的this.chars全部替换成this.scrambleCharacterSet,和props定义的属性名保持一致。

2. 处理undefined的边界情况

  • 在watch的text监听回调里,把oldValue替换成oldValue || '',避免undefined参与字符串操作;
  • 给props的text添加默认值,确保初始状态不会是undefined。

3. 修正组件导入路径

把导入语句改成本地组件的路径(比如./TextScrambler.vue),避免和npm包冲突。

修复后的完整代码

TextScrambler.vue

<template>
  <span>{{ tweenedValue }}</span>
</template>
<script>
export default {
  name: 'TextScrambler',
  data() {
    return {
      queue: [],
      tweenedValue: '',
      frame: 0,
      frameRequest: null
    }
  },
  watch: {
    text(newValue, oldValue) {
      // 处理oldValue可能为undefined的情况
      this.setText(oldValue || '', `${newValue}`)
    }
  },
  mounted() {
    if (this.disableInitialScramble) {
      this.tweenedValue = `${this.text}`
    } else {
      // 初始调用用空字符串作为旧值,逻辑更清晰
      this.setText('', `${this.text}`)
    }
  },
  props: {
    text: {
      type: String,
      default: '' // 添加默认值,避免初始undefined
    },
    disableInitialScramble: {
      type: Boolean,
      default: false
    },
    scrambleDuration: {
      type: Number,
      default: 20
    },
    scrambleCharacterSet: {
      type: String,
      default: '!<>-_\\/[]{}—=+*^?#________'
    }
  },
  methods: {
    setText(oldText, newText) {
      const length = Math.max(oldText.length, newText.length)
      this.queue = []
      for (let i = 0; i < length; i++) {
        const from = oldText[i] || ''
        const to = newText[i] || ''
        const start = Math.floor(Math.random() * this.scrambleDuration)
        const end = start + Math.floor(Math.random() * this.scrambleDuration)
        this.queue.push({ from, to, start, end })
      }
      cancelAnimationFrame(this.frameRequest)
      this.frame = 0
      this.update()
    },
    randomChar() {
      // 修正为props定义的scrambleCharacterSet
      return this.scrambleCharacterSet[Math.floor(Math.random() * this.scrambleCharacterSet.length)]
    },
    update() {
      let output = ''
      let complete = 0
      for (let i = 0, n = this.queue.length; i < n; i++) {
        let { from, to, start, end, char } = this.queue[i]
        if (this.frame >= end) {
          complete++
          output += to
        } else if (this.frame >= start) {
          if (!char || Math.random() < 0.28) {
            char = this.randomChar()
            this.queue[i].char = char
          }
          output += char
        } else {
          output += from
        }
      }
      this.tweenedValue = output
      if (complete !== this.queue.length) {
        this.frameRequest = requestAnimationFrame(this.update)
        this.frame++
      }
    }
  }
}
</script>

调用组件的代码

<template>
  <TextScrambler :text="text" />
</template>
<script>
// 修正为本地组件的正确路径
import TextScrambler from './TextScrambler.vue'
export default {
  layout: 'basic',
  components: { TextScrambler },
  data() {
    return {
      text: Math.random().toString(36).substring(7)
    }
  },
}
</script>

内容的提问来源于stack exchange,提问作者Alit Indrawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:32:54