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);
});
}
}