VUE 3 将 prop 传递给观看组合 API

Ale*_*chi 2 typescript vue.js vuejs3 vue-composition-api

我正在努力使用 Vue 3 Composition API。我试图按逻辑问题拆分我的代码,但我无法弄清楚如何传递要在可组合函数中监视的属性。

这是组件:

export default defineComponent({
  props: {
    collapseY: {
      type: Boolean,
      required: false,
      default: false
    },
    barcodePulse: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  setup(props) {
    const pulse = ref(props.barcodePulse)
    const {getRandomVerticalScaleValue, getRandomAnimationDuration} = usePulse(pulse)

    return {
      getRandomVerticalScaleValue,
      getRandomAnimationDuration
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

这是usePulse可组合函数:

export interface usePulseData {
    getRandomVerticalScaleValue: () => number;
    getRandomAnimationDuration: () => number;
}

export const usePulse: (pulse: Ref<boolean>) => usePulseData = (pulse) => {
    const stopBarcodeAniation = (event: Event) => {
        (event.target as Element).classList.remove('MY:brand-logo:bar-code:pulse');
        (event.target as Element).removeEventListener('animationiteration', stopBarcodeAniation);
    }

    watch(pulse, (value) => {
        console.log("Prop change")
        const rectangles = document.querySelectorAll('.MY\\:brand-logo\\:bar-code\\:rectangle')
        if (value) {
            for (let index = 0; index < rectangles.length; ++index) {
                rectangles[index].classList.add('MY:brand-logo:bar-code:pulse')
            }
        } else {
            for (let index = 0; index < rectangles.length; ++index) {
                rectangles[index].addEventListener('animationiteration', stopBarcodeAniation)
            }
        }
    })

    const getRandomVerticalScaleValue: () => number = () => {
        return (Math.floor(Math.random() * (10 - 4 + 1) + 4) * 0.1) - 0.1;
    }

    const getRandomAnimationDuration: () => number = () => {
        return Math.floor(Math.random() * (20 - 10 + 1) + 10) * 0.15
    }


    onMounted(() => {
        const rectangles = document.querySelectorAll('.MY\\:brand-logo\\:bar-code\\:rectangle')
        for (let index = 0; index < rectangles.length; ++index) {
            (rectangles[index] as HTMLElement).style.setProperty('--animation-duration', `${getRandomAnimationDuration()}s`);
            (rectangles[index] as HTMLElement).style.setProperty('--scale-factor', `${getRandomVerticalScaleValue()}`);
        }
    })

    return {
        getRandomVerticalScaleValue,
        getRandomAnimationDuration
    } as usePulseData
}
Run Code Online (Sandbox Code Playgroud)

由于某种原因,第二个代码片段console.log('Prop changed')中的 不执行。

你们中的任何人都可以解释为什么这种情况没有发生吗?

ton*_*y19 11

问题出在下面的代码中:

\n
const pulse = ref(props.barcodePulse) // \xe2\x9d\x8c loses props reactivity\n\nusePulse(pulse)\n
Run Code Online (Sandbox Code Playgroud)\n

props是一个reactive对象,但是props.barcodePulse是一个文字值(非反应性)。用 a 包裹文字值并ref不会恢复 的反应性props,而是创建一个新的独立ref.

\n

要保持可组合项中的反应性,请使用toRefstoRef获取barcodePulse

\n
const { barcodePulse } = toRefs(props) // \xe2\x9c\x85\n// or\nconst barcodePulse = toRef(props, \'barcodePulse\') // \xe2\x9c\x85\n\nusePulse(barcodePulse)\n
Run Code Online (Sandbox Code Playgroud)\n

演示

\n