README.md 5.7 KB
Newer Older
DCloud-WZF's avatar
DCloud-WZF 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# uvue组件概述

uni-app x支持vue组件,不支持小程序wxml组件。

支持[easycom](/component/README.md#easycom)

uvue的组件,可以使用前端技术编写,也可以使用原生技术编写。

- 前端技术即新建一个vue或uvue文件,按vue组件规范编写代码。
- 原生的uts组件插件,指把原生的、需要在界面上显示的组件,编写uts代码,通过uni_modules插件的方式集成到uni-app项目中。比如
	* lottie组件,使用uts调用原生的lottie sdk来开发组件,再引入页面中。[详见](https://ext.dcloud.net.cn/plugin?name=uni-animation-view)
	* video组件,其实官方的video,也是用uts组件插件实现的
	
	之所以称之为`uts组件插件`,是相对于另一个分类`uts api插件`
	
	uts组件插件的开发教程,[详见](/plugin/uts-component.md)

**兼容性及注意事项:**

## props

- 仅支持[对象方式](https://cn.vuejs.org/guide/components/props.html#props-declaration)声明。
DCloud-WZF's avatar
DCloud-WZF 已提交
23
- 复杂数据类型需要通过 `PropType` 标记类型,[详见](https://cn.vuejs.org/guide/typescript/options-api.html#typing-component-props)
DCloud-WZF's avatar
DCloud-WZF 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
```ts
import { type PropType } from 'vue'

type Obj = { a: number }

export default {
	props: {
		num: {
			type: Number,
			required: true
		},
		str: {
			type: String,
			default: 'str',
			validator(value: string): boolean {
				return value.length > 0
      }
		},
		obj: {
			type: Object as PropType<Obj>,
			default: (): Obj => ({ a: 1 } as Obj)
		},
		arr: {
			type: Array as PropType<number[]>,
			default: (): number[] => [1, 2, 3]
		}
	}
}
```
DCloud-WZF's avatar
DCloud-WZF 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

## 自定义事件

- [v-model](tutorial/vue3-components.html#v-model-modifiers) 暂不支持 `capitalize` 修饰符。

## 计算属性和侦听器

- [watch deep](https://uniapp.dcloud.net.cn/tutorial/vue3-basics.html#%E9%80%89%E9%A1%B9-deep) 不支持
- [监听对象中单个属性](https://uniapp.dcloud.net.cn/tutorial/vue3-basics.html#%E7%9B%91%E5%90%AC%E5%AF%B9%E8%B1%A1%E4%B8%AD%E5%8D%95%E4%B8%AA%E5%B1%9E%E6%80%A7) 不支持

## 作用域插槽的类型

作用域插槽需在组件中指定插槽数据类型
```ts
// components/Foo.uvue
<view>
    <slot msg="test msg" />
</view>

import { SlotsType } from 'vue'
export default {
  slots: Object as SlotsType<{
    default: { msg: string }
  }>
}
// page.uvue
<view>
	<Foo>
		<template v-slot="slotProps">
			<text>{{ slotProps.msg }}</text>
		</template>
	</Foo>
</view>
```

DCloud-WZF's avatar
DCloud-WZF 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
## refs

`uni-app js 引擎版`中,`refs` 的类型是 `Object``DOM 节点`的类型是 `Element`\
`uni-app x` 中,`refs` 的类型是 `Map<string, any>``DOM 节点`的类型是 `INode`

::: preview

> uni-app js 引擎版

```ts
<template>
	<view>
		<text ref="text">text node</text>
		<Foo ref="foo" />
	</view>
</template>

<script lang="ts">
	export default {
		onReady() {
			const text = this.$refs.text as Element
			const foo = this.$refs.foo as ComponentPublicInstance
		}
	}
</script>
```

> uni-app x

```ts
<template>
	<view>
		<text ref="text">text node</text>
		<Foo ref="foo" />
	</view>
</template>

<script lang="uts">
	export default {
		onReady() {
			const text = this.$refs.get("text") as INode
			const foo = this.$refs.get("foo") as ComponentPublicInstance
		}
	}
</script>
```

:::

DCloud-WZF's avatar
DCloud-WZF 已提交
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
## 监听页面生命周期

目前暂不支持在组件内监听页面生命周期,待后续支持组合式 API 后,可通过组合式 API 实现。

## vue 与 uvue 不同文件后缀的优先级 @priority

新建组件时,默认组件的后缀名为.vue。而不是.uvue。

.vue里面写uvue的语法,可以正常被.uvue页面引用和编译。

.vue里写条件编译,可以制作同时满足uni-app和uni-app x的组件。

但是uni-app x也支持.uvue文件的组件。

当你手动import或easycom手动配置规则,可以指定文件名后缀。比如`import PageHead from '@/components/page-head.uvue'`

但如果未明确指定组件后缀名的情况,且同一个组件目录下即存在.vue文件、又存在.uvue文件,
此时 `vue` 组件和 `uvue` 组件的优先级如下:
-`uni-app x` 中,优先使用 `uvue` 组件,如果不存在 `uvue` 组件,则使用 `vue` 组件。
-`uni-app` 中,只支持使用 `vue` 组件。
W
x  
wanganxp 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185


## 如何开发同时兼容 uni-app x 和 uni-app 的组件

目前有两种方案:

- 目录下同时提供uvue,vue文件,分别适配 uni-app x 和 uni-app

组件作者在 uvue 和 vue 文件中可以自由使用各自的特性,比如 vue 中可以任意使用 js 或 ts 来书写代码,

如果部分组件逻辑被抽离为单独的文件,需要分别命名为各自环境支持的文件类型,导入时不同平台支持的文件类型也不同,

比如 uvue 文件目前不支持引入js或ts,而 vue 文件不能引入 uts 文件

对于现有的 uni-app 组件,通过新建 uvue 文件来渐进式支持 uni-app x,可以避免对已有 uni-app 项目造成影响

- 仅提供一个vue文件,同时适配 uni-app x 和 uni-app

该方案,需要script节点配置lang="ts",这样才可以在 uni-app 项目中正常书写带有类型的代码,而在 uni-app x 项目中,则会忽略 lang="ts",当做 uts 代码编译。

当需要区分平台或项目类型时,可以使用对应的条件编译。

<!-- 比如,当需要在 css 中区分原生渲染和webview渲染时

可以通过 APP-UVUE(表示在 uni-app x 项目app端的Android和iOS原生渲染)、APP-NVUE(表示在 uni-app 项目app端的nvue页面原生渲染) 区分,

`#ifdef APP-UVUE || APP-NVUE` 可以表示原生渲染,使用 `ifndef` 则可以取反表示为webview渲染,如 `#ifndef APP-UVUE || APP-NVUE`
 -->
比如通过 UNI-APP-X 来区分项目类型,更多条件编译见:[详情](https://uniapp.dcloud.net.cn/tutorial/platform.html)