uniapp+vue3+ts(base-class)

threeperson
发布于 2025-07-05 / 3 阅读
0
0

uniapp+vue3+ts(base-class)

vue3针对ts支持要比vue2提升了很多,而且vue3的整体性能也提升了很多。所以在开发新的小程序,我就从uniapp+vue2
切换到了uniapp+vue3。当然,在这个切换的过程中,也是填了一些坑。



目前在国内大多数uniapp+vue3开发都是composition api 方式,base-class方式会少一些。我为什么喜欢base-class,主要
是因为我是一枚10年java老码农,所以更喜欢强类型的编程语言,而且基于class 结构更清晰。当然二者还有一些其他差异,
但是至于选择哪种方式主要是看个人或团队熟悉程度,掌控能力。我简单列举一下base-class 和composition api差异。

那么基于base-class 如何在uniapp框架下高效开发呢,需要借助一个插件vue-facing-decorator,我用的最新版本

    "vue-facing-decorator": "v4.0.0-beta.1",

代码整合方式也很简单,只需要继承该组件的vue即可,并构建一个基类,因为vue3生命周期和uniapp下存在一些差异。所以
需要在base类里进行mounted,下面列出代码。

import { onHide, onShow, onUnload, onLoad,onReady, onShareAppMessage } from "@dcloudio/uni-app";
import { Setup, Vue } from "vue-facing-decorator";
export class MyVue extends Vue {
    onLoad(option?: any) {
    }
    loadPost(option?: any) {
    }
    onHide() {
    }
    onReady(){}
    onUnload() {
    }
    shareAppMessage(option?: any){

    }
    //在mounted里激活下生命周期钩子,这样在单个page里直接定义对应函数就会生效了。
    mounted(option: any) {
        let that = this;
        this.onLoad(option);
        this.loadPost(option);

        onReady(() => {
            that.onReady();
        });
        onShow((option) => {
            that.loadPost(option);
        });
        onHide(() => {
            that.onHide();
        });
       
    }
}


那么具体的vue页面如何使用呢,其实很简单。下面给出依赖方式和子类代码结构。

vue页面里直接通过script引入外部ts。

<script  lang="ts" src="./post.ts"/>

ts代码中extends MyVue,同时通过@Component注解标记该组件。对于属性、函数定义就正常写就可以了,无需ref引用,也不用.value赋值,写起来是不是很舒服。

import { MyVue } from "@/common/MyVue";
import { CacheKeys } from "@/constant/CacheKeys";
import Constant, { GenerateResult, TopBar } from "@/constant/Constants";
import PostInfo from "@/model/PostInfo";
import { UserInfo } from "@/model/UserInfo";
import { PostRequest } from "@/protocol/request/PostRequest";
import PostService from "@/service/PostService";
import UserService from "@/service/UserService";
import DateUtil from "@/utils/DateUtil";
import LoggerUtil from "@/utils/LoggerUtil";
import UniUtil, { VideoAdOptions } from "@/utils/UniUtil";
import Util from "@/utils/Util";
import { Component, Setup } from "vue-facing-decorator";
@Component
export default class Post extends MyVue {
    user = new UserInfo.UserData();
    flowList = new Array<UserInfo.SimpleUser>();
    postList = new Array<PostInfo>();
    postMap = new Map<number, PostInfo>();
    cdnHost = Constant.cdnHost;
    screenWidth: string = "";
    mediaHeight: string = "320px";
    visible: boolean = false;
    request: PostRequest.QueryList = new PostRequest.QueryList();
    observer: UniNamespace.IntersectionObserver | null = null;
    async onLoad() {
        uni.setNavigationBarTitle({ title: TopBar.POST });

        uni.getSystemInfo({
            success: (res) => {
                this.screenWidth = res.screenWidth + "px"
                this.mediaHeight = res.screenWidth * 1.25 + "px";
            }
        });

        let params = Util.getPageParams();
        if(params){
            LoggerUtil.info("获取到参数:{}",JSON.stringify(params));
            this.request.uid = params.uid;
            this.user.uid = params.uid;
            UserService.cacheRefUid();
            this.request.postId = Number(params.postId) + 1;
            this.load();
        }

    }
    async load() {
        this.postList.length = 0;
        this.flowList.length = 0;
        this.request.pageIndex = 1;
        let post = await PostService.queryUserList(this.request);
        Util.copyList(this.postList, post.postList, PostInfo);
        let user = await UserService.public(this.user);
        Util.copy(this.user, user);
        this.postMap.clear();
        this.postList.forEach(element => {
            this.postMap.set(element.id, element);
        });
    }

}


评论