在可组合项 vue3 中使用道具

Use props in composables vue3

我正在将一个应用程序从 vue 2 升级到 vue 3,但我遇到了一些可组合项问题。我想在可组合项中使用道具,但它似乎不起作用。代码示例是从一个工作组件中提取的,当我将它留在组件中时工作正常。

我假设 defineProps 不受可组合项的支持,但我不清楚如何处理它。当我在参数中传递 src 时,它失去了反应性。

// loadImage.js
import { defineProps, onMounted, ref, watch } from 'vue'

// by convention, composable function names start with "use"
export function useLoadImage() {
  let loadingImage = ref(true)
  let showImage = ref(false)
  const props = defineProps({
    src: String,
  })
  const delayShowImage = () => {
    setTimeout(() => {
      showImage.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 (props.src) {
      loadImage(props.src)
    }
  })
  watch(
    () => props.src,
    (val) => {
      if (val) {
        loadingImage.value = true
        loadImage(val)
      }
    },
  )
  // expose managed state as return value
  return { loadingImage, showImage }
}

编辑

这个方法对我有用,但是下面评论中提到的两个方法都没有。

我有一个新问题

// loadImage.js
import { onMounted, ref, watch } from 'vue'

// by convention, composable function names start with "use"
export function useLoadImage℗ops) {
  let loadingImage = ref(true)
  let showImage = ref(false)

  const delayShowImage = () => {
    setTimeout(() => {
      showImage.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 (props.src) {
      loadImage(props.src)
    }
  })
  watch(
    () => props.src,
    (val) => {
      if (val) {
        loadingImage.value = true
        loadImage(val)
      }
    },
  )
  // expose managed state as return value
  return { loadingImage, showImage }
}

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

const props = defineProps({
  src: String
})
const { loading, show } = useLoadImage(props)

</script>

根据official docs

defineProps and defineEmits are compiler macros only usable inside <script setup>

您应该将 props 作为参数传递而不破坏它们,以免失去反应性:

export function useLoadImage(props) {
....

}