美文网首页
Vue3在IOS下的一个小坑

Vue3在IOS下的一个小坑

作者: 交互动效 | 来源:发表于2020-04-30 17:43 被阅读0次

    自从Vue3 Beta发布以来,我就尝试在小项目中使用它了,不得不说真是香,虽然对新手可能不太友好,但是对于用过React Hooks的人来说简直不要太爽,解决了React Hooks多次运行以及性能优化等多项心智负担,但是就在刚刚做好的一个动效在自己手机上完美运行,美滋滋的拿去给同事测试,然而同事的苹果手机却没有任何动态效果:

    image
    而在我的手机效果是这样的:
    image
    这个特效的逻辑是这样的:首先获取后置摄像头权限进行拍摄,然后在视频上方循环播放帧动画(其实就是仿AR),由于公司无力开发AR模型,只能让美工渲图然后web端做个伪AR,那么问题来了,如果是WebGL做出来的模型即使代码量很大,也依然就几百K顶多1M,但是帧动画就不一样了,美工给了我几百张图,每一张大概在50k左右,加在一起十多M二十来M的,加载时间太长了,所以需要一个等待动画,这个等待动画就是一个小心心,小心心里面是你摄像头目前拍摄到的画面,这个小心心会随着你加载的图片的数量而越来越大,当加载完毕后小心心占满全屏(也就是看不到小心心啦)。

    组件间传值

    在帧动画那个组件里请求的图片,但是图片请求了多少张这个数值需要传递到小心心那个组件去,发现$emit这种vue2传值法居然不好使了!

    // 子组件
    import { defineComponent } from 'vue'
    
    export default defineComponent((props, ctx) => {
        ctx.$emit('event', '来自子组件的值')
        return {}
    })
    
    <!--父组件-->
    <Child @event="getChildValue"/>
    

    那个ctx就相当于vue2.x的this

    然而这种在vue2.x中十分常见的传值方法在这里却没有任何效果。

    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>
    
    image

    可以看到和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。

    相关文章

      网友评论

          本文标题:Vue3在IOS下的一个小坑

          本文链接:https://www.haomeiwen.com/subject/nrjtghtx.html