关于uniapp + ts + vue3 + uview-plus 中使用ref的 经验记录

2,340 阅读1分钟

问题产生

在 uview-plus 上看到的例子 `uToast` 使用中 看到仍然是 vue2 的写法 但是我个人使用上出现了一些问题,官方上面使用ref 使用 this 但是我使用时 提示 并无此方法 且运行时报错,提示没有this.

问题解决

其实网上有好多帖子提示了vue3 取消 this,那么我下面就是我自己的总结及经验
  1. 使用proxy 代替 this
  2. 使用自定义的 类型 解决 ts 的报错,这个在android 中会提示 没有这个方法 但是在微信小程序中可以实现,具体等官方出来ts版本再修改此处.

下面我贴出一份 关于 uToast 的代码

<!--
 * @Description: 
 * @Version: 2.0
 * @Author: AICHEN
 * @Date: 2023-01-01 16:37:07
 * @LastEditors: AICHEN
 * @LastEditTime: 2023-01-01 16:42:58
-->
<template>
    <view>
        <u-toast ref="uToast"></u-toast>
        <u-cell-group title-bg-color="rgb(243, 244, 246)">
            <u-cell :titleStyle="{ fontWeight: 500 }" :title="item.title" v-for="(item, index) in list" :key="index"
                isLink :icon="item.iconUrl" @click="showToast(item)">
            </u-cell>
        </u-cell-group>
    </view>
</template>

<script lang="ts">
import {
    defineComponent,
    getCurrentInstance,
    ComponentInternalInstance, ref
} from "vue";
import { onShow } from '@dcloudio/uni-app';
interface IComponent {
    show: Function
}
interface ItemType {
    type: string,
    title: string,
    message: string,
    iconUrl: string,
    url?: string,
    icon?: boolean,

}
export default defineComponent({

    setup() {

        const list: Array<ItemType> = [{
            type: 'default',
            title: '默认主题',
            message: "锦瑟无端五十弦",
            iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/default.png'
        },
        {
            type: 'error',
            icon: false,
            title: '失败主题',
            message: "一弦一柱思华年",
            iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/error.png'
        },
        {
            type: 'success',
            title: '成功主题(带图标)',
            message: "庄生晓梦迷蝴蝶",
            iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
        },
        {
            type: 'loading',
            title: '正在加载',
            message: "正在加载",
            iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/loading.png'
        },
        {
            type: 'default',
            title: '结束后跳转标签页',
            message: "此情可待成追忆",
            url: '/pages/componentsB/tag/tag',
            iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/jump.png'
        }
        ]
        const { proxy } = getCurrentInstance() as ComponentInternalInstance;

        const uToast = ref<IComponent>({} as IComponent);

        onShow(() => {
            // 这个是为了解决 ts 提示 unknown 问题 非强迫症可以写成 proxy?.$refs.uToast 
            // 在android 不行 这个接口定义太简单 还是得写成  proxy?.$refs.uToast.show 调用
            uToast.value = proxy?.$refs["uToast"] as IComponent;
        });

        const showToast = (params: ItemType) => {
            if (uToast.value) {
                uToast.value.show({
                    ...params,
                    complete() {
                        params.url && uni.navigateTo({
                            url: params.url
                        })
                    }
                })
            }

        }


        return { list, showToast }
    }
})
</script>