Vue3在IOS下的一個小坑

自從Vue3 Beta發佈以來(點擊查看如何建立Vue3 beta項目),我就開始嘗試在小項目中使用它了,不得不說真是香,雖然對新手可能不太友好,可是對於用過React Hooks的人來講簡直不要太爽,解決了React Hooks屢次運行以及性能優化等多項心智負擔,可是就在剛剛作好的一個動效在本身手機上完美運行,美滋滋的拿去給同事測試,然而同事的蘋果手機卻沒有任何動態效果: javascript

而在個人手機效果是這樣的:
這個特效的邏輯是這樣的:首先獲取後置攝像頭權限進行拍攝,而後在視頻上方循環播放幀動畫( 其實就是仿AR),因爲公司無力開發AR模型,只能讓美工渲圖而後web端作個僞AR,那麼問題來了,若是是WebGL作出來的模型即便代碼量很大,也依然就幾百K頂多1M,可是幀動畫就不同了,美工給了我幾百張圖,每一張大概在50k左右,加在一塊兒十多M二十來M的,加載時間太長了,因此須要一個等待動畫,這個等待動畫就是一個當心心,當心內心面是你攝像頭目前拍攝到的畫面,這個當心心會隨着你加載的圖片的數量而愈來愈大,當加載完畢後當心心佔滿全屏( 也就是看不到當心心啦)。若是仍是不明白究竟是個什麼樣的效果,能夠微信掃碼進行體驗:

注意:最好用瀏覽器打開,還沒開發完,可能會有bug!html

組件間傳值

在幀動畫那個組件裏請求的圖片,可是圖片請求了多少張這個數值須要傳遞到當心心那個組件去,發現$emit這種vue2傳值法竟然很差使了!vue

// 子組件
import { defineComponent } from 'vue'

export default defineComponent((props, ctx) => {
    ctx.$emit('event', '來自子組件的值')
    return {}
})
複製代碼
<!--父組件-->
<Child @event="getChildValue"/>
複製代碼

那個ctx就至關於vue2.x的thisjava

然而這種在vue2.x中十分常見的傳值方法在這裏卻沒有任何效果。web

Vue3傳值方式

那麼該如何傳值呢?用React Hooks的那種自定義Hook再試試:瀏覽器

//抽取出來一個js文件
import { ref } from 'vue'

const count = ref(0)

export default number => {
  count.value = number || count.value
  return { count }
}
複製代碼
<!--子組件A-->
<template>
  <span>{{count}}</span>
</template>

<script> import { defineComponent } from 'vue' import useCount from '../use/useCount' export default defineComponent(_ => { const { count } = useCount() return { count } }) </script>
複製代碼
<!--子組件B-->
<template>
  <button @click="addCount">+</button>
  <a href="#">{{count}}</a>
</template>

<script> import { defineComponent } from 'vue' import useCount from '../use/useCount' export default defineComponent(_ => { const { count } = useCount() const addCount = _ => count.value++ return { count, addCount } }) </script>
複製代碼
<!--父組件-->
<template>
  <A/>
  <B/>
</template>

<script> import A from './A' import B from './B' export default { components: { A, B } } </script>
複製代碼

能夠看到和React Hooks的自定義Hook用法很類似。

watch + onMounted在IOS下的坑

原本是須要監聽請求圖片那個組件傳回來的值來給當心心組件,每多請求回來一張圖,當心心就放大一些,直到當心心充滿屏幕。 因而乎我這樣寫了:性能優化

import { onMounted } from 'vue'
import { useXxx } from '../use/useXxx'
// 只貼出了關鍵代碼
setup () {
    const { val } = useXxx()
    onMounted(_ => {
        // 此處省略若干行業務代碼
        watch(val, v => console.log(v))
    })
}
複製代碼

這段代碼在個人PC端和移動端都運行良好打印出值來,而且沒有任何的報錯,因此我才自信滿滿的去給別人看,結果一遇見蘋果手機就……微信

解決方案

把watch函數提到生命週期函數外部使用。函數

import { onMounted } from 'vue'
import { useXxx } from '../use/useXxx'
// 只貼出了關鍵代碼
setup () {
    const { val } = useXxx()
    watch(val, v => console.log(v))
    onMounted(_ => {
        // 此處省略若干行業務代碼
    })
}
複製代碼

建議不要將watch函數與各類生命週期函數放在一塊兒混用,不然可能會出現意想不到的bug。post

相關文章
相關標籤/搜索