初识uniapp

uniapp产品

   uni-app 是一个DCloud出品的、使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。DCloud另一个有名的产品是HBuilderX。

     根据官网顶部的tab,我们可以发现DCloud的产品包括 uni-app、uni-app x、uniCloud、HBuilder、uni 小程序 sdk。HBuilder自不必说,它是一款ide。uni 小程序 sdk是为原生打造的、可运行基于 uni-app 开发的小程序前端项目的框架,从而帮助原生App快速获取小程序的能力。uniCloud则提供了类似微信云开发的能力,只不过是微信云和阿里云提供了实际的云服务,uniCloud则做了一个适配层。

        作为前端开发部分,我们更多的是使用uni-app或者uni-app x。这两者有什么区别呢?根本的区别是渲染引擎不同,uni-app是基于webview渲染的,而uni-app x是基于原生渲染的。

uni-appuni-app x
渲染引擎webview原生
开发语言js,tsuts
界面框架vueuvue
css完整的css受限的css

当然uni-app也不仅仅是只有webview渲染,依靠weex的能力,它也实现了类似RN的原生渲染能力。

界面框架vuenvue
渲染引擎webview改进的weex
css完整的css受限的css
api比较丰富比较有限
性能一般较好

接下来再看看各框架的组件和api支持情况:

uniapp h5uniapp小程序uniapp 原生nvueuniapp 原生uniapp x h5uniapp x app
内置基础组件
基于内置的自定义组件
原生ui嵌入--nvue组件--uts组件插件
标准API部分不支持,用nvue api替代
语言相关ECMAScriptECMAScriptECMAScriptECMAScriptuts apiuts api
h5+ api----
native.js----

使用UI组件库

uni-app支持的组件分为vue组件和小程序自定义组件。vue组件分为内置组件、扩展组件uni-ui以及第三方组件。小程序自定义组件:其规范不是vue规范,而是小程序规范。

扩展组件有很多概念,比如easycom规范、uni_moduledatacom原生组件uniCloud组件。详见:组件使用的入门教程 | uni-app官网

uni-app的插件市场,有很多扩展组件,有的是单独的,有的是成套的。 uni ui是DCloud官方出了一套扩展组件,这些扩展组件支持单个组件从插件市场下载,也支持npm引入uni ui,当然更方便的是在HBuilderX新建项目时直接选择uni ui项目模板。npm安装请参考:uni-app官网

插件市场,https://ext.dcloud.net.cn,有各种玲琅满目的组件、模板。 其中成套的全端兼容ui库包括:

uViewUI:整合了非常多组件,功能丰富、文档清晰,但不支持nvue(2.x已支持nvue)。但是不支持vue3。uv-ui支持vue2+3。
colorUI css库:颜值很高,css库而非组件。
unify UI:全端支持的组件库,侧重nvue(商城已下架)
mypUI:全端支持的组件库,侧重nvue
ThorUI组件库
graceUI商业库

使用TypeScript

1.安装类型声明文件

pnpm i -D @dcloudio/types @uni-helper/uni-ui-types @uni-helper/uni-app-types

2.配置类型声明文件

// tsconfig.json
{
  "compilerOptions": {
    // ...
    "types": [
      "@dcloudio/types", // uni-app API 类型
      //"miniprogram-api-typings", // 原生微信小程序类型
      "@uni-helper/uni-app-types", // uni-app 组件类型
      "@uni-helper/uni-ui-types" // uni-ui 组件类型  
    ]
  },
  // vue 编译器类型,校验标签类型
  "vueCompilerOptions": {
    "nativeTags": ["block", "component", "template", "slot"]
  }
}

实战

这里我们实现一个基础的登录页面:

代码如下:

<template>
	<view class="app">
		<uni-popup ref="popup" type="message">
			<uni-popup-message type="error" :message="message" :duration="1000"></uni-popup-message>
		</uni-popup>
		<view class="logo">
			<image src="../../static/logo.png"></image>
		</view>
		<uni-segmented-control class="segments" :current="currentIndex" :values="items" @clickItem="onClickItem"
			styleType="button" activeColor="#07c160" inActiveColor="white"></uni-segmented-control>
		<!-- <view class="segments">
			<view :class="['segment', {'selected':accountType == 1}]" @click="onTapSegment" data-type="1">我是学生</view>
			<view :class="['segment', {'selected':accountType == 2}]" @click="onTapSegment" data-type="2">我是教师</view>
			<view :class="['segment', {'selected':accountType == 3}]" @click="onTapSegment" data-type="3">我是教务</view>
		</view> -->
		<view class="page__bd">
			<uni-forms ref="form" :modelValue="formData" :rules="rules">
				<uni-forms-item label="账号" name="account">
					<uni-easyinput type="text" v-model="formData.account" placeholder="请输入账号" />
				</uni-forms-item>
				<uni-forms-item label="姓名" name="name">
					<uni-easyinput type="text" v-model="formData.name" placeholder="请输入姓名" />
				</uni-forms-item>
				<uni-forms-item label="密码" name="password">
					<uni-easyinput type="password" v-model="formData.password" placeholder="请输入密码" />
				</uni-forms-item>
			</uni-forms>
		</view>
		<view class="weui-btn-area">
			<button class="weui-btn" type="primary" @click="submitForm">登录</button>
		</view>
	</view>
</template>

<script lang="ts" setup>
	import type { UniForms, UniPopup, UniSegmentedControlOnClickItemEvent } from '@uni-helper/uni-ui-types';
	import { reactive, ref } from 'vue';

	const popup = ref<UniPopup | null>(null)
	const form = ref<UniForms | null>(null)
	const rules = ref({
		account: {
			rules: [{
				required: true,
				errorMessage: '请输入账号',
			}]
		},
		name: {
			rules: [{
				required: false,
				errorMessage: '请输入姓名',
			}]
		},
		password: {
			rules: [{
				required: true,
				errorMessage: '请输入密码',
			}]
		},
	})
	type LoginParams = {
		account : string,
		name? : string,
		password : string
	}
	const formData = reactive<LoginParams>({
		account: "",
		password: ""
	})
	
	const message = ref<string>("")
	const submitForm = () => {
		form.value?.validate().then((res : LoginParams) => {
			console.log(res)
			message.value = "错误"
			popup.value?.open()
		}).catch((error : any) => {
			console.log(error)
		})
	}

	const items = ['我是学生', '我是教师', '我是教务']
	const currentIndex = ref(0)
	const onClickItem = (e : UniSegmentedControlOnClickItemEvent) => {
		if (currentIndex.value != e.currentIndex) {
			currentIndex.value = e.currentIndex
		}
	}

	// const accountType = ref(1)
	// const onTapSegment = (e:UniHelper.BaseEvent)=>{
	// 	const { type } = e.currentTarget?.dataset!
	// 	accountType.value = parseInt(type)
	// 	console.log(e)
	// }
</script>

<style>
	.app {
		display: flex;
		flex-direction: column;
		align-items: center;
		box-sizing: border-box;
		padding: 40rpx 40rpx;
	}

	.logo image {
		width: 300rpx;
		height: 300rpx;
	}

	.segments {
		width: 500rpx;
		margin-top: 70rpx;
	}

	/* 	.segments {
		display: flex;
	}

	.segment {
		padding: 10rpx 38rpx;
		border: 2rpx solid #eee;
		background-color: #fff;
	}

	.segment.selected {
		color: #fff;
		background-color: #07c160;
	} */

	.page__bd {
		margin-top: 40rpx;
	}
</style>

注释掉的代码里我们自己实现了一个segmented control。这里要注意的一点是@onClick的参数类型是UniHelper.BaseEvent,花了很多时间,也没有在官方文档上找到相关说明,只是根据打印的数据结构,然后在对应的类型文件中,找到了这个看起来对的类型。另外这里用到了内置的segmented control,据文档所示,存在一个inActiveColor属性,设置后发现不生效,查看源码才发现根本就没有这个属性。uni ui看起来不是一个被精心设计、实现的组件库,目前有比较多的问题被反馈。HBuilderX也存在偶尔会乱报错误的问题,而且不显示错误的原因。

uniapp总体而言,是一个理念和商业化比较成功的产品,但是还是有诸多瑕疵,建议少点自嗨,多花点心思打磨产品和代码。

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值