将单个 属性 传递给 Vue3 中的可组合项

Passing a single property to a composable in Vue3

我正在使用可组合项在 Vue3 中加载图像。我已经能够将所有道具作为一个对象成功传递,,但我无法传递我想要反应的那个 属性。我相当确定问题是未定义

中的属性
// loadImage.js
import { onMounted, ref, watch } from 'vue'

// by convention, composable function names start with "use"
export function useLoadImage(src) {
  let loading = ref(true)
  let show = ref(false)

  const delayShowImage = () => {
    setTimeout(() => {
      show.value = true
    }, 100)
  }
  const loadImage = (src) => {
    let img = new Image()
    img.onload = (e) => {
      loading.value = false
      img.onload = undefined
      img.src = undefined
      img = undefined
      delayShowImage()
    }
    img.src = src
  }
  onMounted(() => {
    if (src) {
      loadImage(src)
    }
  })
  watch(
    () => src,
    (val) => {
      if (val) {
        loading.value = true
        loadImage(val)
      }
    },
  )
  // expose managed state as return value
  /**
   * loading is the image is loading
   * show is a delayed show for images that transition.
   */
  return { loading, show }
}

下面的方法returns这个在console.log并没有报错。

Proxy {src: undefined} undefined

<script setup>
import { defineProps, computed } from 'vue'
import { useLoadImage } from '../../composables/loadImage'

const props = defineProps({
  src: String
})

console.log(props, props.src)
const srcRef = computed(() => props.src)
const { loading, show } = useLoadImage(srcRef)
</script>

下面的方法returns这个在console.log

Proxy {src: undefined} undefined

并给出以下错误

TypeError: Cannot read properties of undefined (reading 'undefined')

<script setup>
import { defineProps, toRef } from 'vue'
import { useLoadImage } from '../../composables/loadImage'

const props = defineProps({
  src: String
})

console.log(props, props.src)
const srcRef = toRef(props.src)
const { loading, show } = useLoadImage(srcRef)
</script>

如评论中所述,您的组件中似乎 srcundefined,因为您可能没有将 prop 正确传递给组件。

即使src设置了一个字符串,仍然会有一些其他问题:

  1. toRef 的第一个参数应该是一个 reactive 对象(即 props),第二个参数应该是一个键名(即 'src'):

    // MyComponent.vue
    
    const srcRef = toRef(props.src) ❌
    const srcRef = toRef(props, 'src') ✅
    

    注意:使用const srcRef = computed(() => props.src)也是有效的,就像你原来做的那样。

  2. watch 的第一个参数是 WatchSource。当 WatchSource 是处理 ref 的函数时,它应该 return ref 的展开值。或者,WatchSource 可以是 ref 本身:

    // loadImage.js
    
    watch(() => srcRef, /* callback */) ❌
    watch(() => srcRef.value, /* callback */) ✅
    watch(srcRef, /* callback */) ✅
    
  3. 可组合项在 ref 中接收图像源,并且您的 onMounted() 挂钩将 ref 传递给 loadImage(),这实际上是期待 ref 的展开值中的字符串:

    // loadImage.js
    
    onMounted(() => {
      if (src) { ❌ /* src is a ref in this composable */
        loadImage(src)
      }
    })
    
    onMounted(() => {
      if (src.value) { ✅
        loadImage(src.value)
      }
    })
    

demo