I am upgrading an app from vue 2 to vue 3 and I am having some issues with composables. I'd like to use props in the composable but it doesn't seem to be working. The code sample is pulled from a working component and works fine when I leave it in the component.
I assume defineProps
isn't supported by composables, but then I am unclear how to handle it. When I pass the src
in the parameters it loses its reactivity.
// 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 }
}
Edit
This method worked for me, but the two methods mentioned in the comments below did not.
I have a new question here.
// loadImage.js
import { onMounted, ref, watch } from 'vue'
// by convention, composable function names start with "use"
export function useLoadImage(props) {
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>
src
variable so return{ loadingImage, showImage, src }
will cause an errorconst {loadingImage, showImage} = useLoadImage(props.src)
and src would not update once the property was set. passing in the entire props object solved the issue.