Vue3 定制小程序开发的官方文档中大致介绍定制小程序开发了这三种全局API。定制小程序开发但是我看完过后,定制小程序开发对于一些点还是处于一定制小程序开发个比较懵逼的状态,定制小程序开发于是自己去查阅了一些定制小程序开发资料以及手写代码去尝试,定制小程序开发才渐渐领悟了过来。
定制小程序开发在看官方文档期间,我把自己在脑海中疑惑的问题整理了一下,然后写在了这篇文章中,并从网上和实践中去找寻到了一些答案。
咱们先来看文档中对于这三个全局API的介绍:
先来看下 defineComponent
文档中第一句话很容易看懂,说白了就是从实现上看,用了或者跟不用这个api没多大区别~~但是呢,第二句话说的好像又有一些区别,不过我没太看懂。。。于是我自己的第一个问题就来了:
问题一:defineComponent 这个API用起来到底和不用有什么区别???
1. 显示 Vue Options 提示。
这个API一般是在ts或者tsx文件中使用的,所以,当我们创建了一个这种类型的文件后,它是不知道我们是要去写 vue 实例代码的,所以在这种情况下,我们需要defineComponent来帮我们做内部的一些options的提示,我们可以看一个使用了defineComponent和没有使用defineComponent的例子:
当然这背后的原理是利用 TypeScript 定义了defineComponent 参数类型实现的。
2. 给予正确的参数类型推断。
拿 setup 来说,defineComponent 可以为 setup 函数的 props 传参做出正确的类型推断,看下图:
如果没有使用 defineComponent 的话,是没有办法推断出来的,需要自己显式地去定义类型。
3. 可返回一个合成类型的构造函数。
这也是官方文档中所说的,我在代码中尝试了一下,发现确实可以在其返回的构造函数中去定义一些钩子和属性等,如下图:
这就是目前我对这个API的一些理解吧~后续有新发现再补充
接下来来看下 defineAsyncComponent
这个API主要是用来定义异步组件的,先来看下官方文档的介绍:
其实关于这个API的话,我个人觉得官方文档中介绍得已经非常清楚了,就是用来定义一个异步组件,然后利用Promise将其在应该渲染的时候加载出来。
关于其高阶用法的相关配置,大家可以去文档中自寻查找。
最后来看下 defineCustomElement
最开始看到这个API的名字的时候,我有点懵,以为是和 api相同的功能:创建一个自定义组件就完事儿了。结果忽略了最后一个单词:Element。
这个API是用来创建原生的自定义元素的,由它创建出来的组件经过注册可以在其他框架(不只是Vue)甚至脱离框架去使用。我们先来看看它的官方介绍:
官方文档中介绍得非常简单。在文档中引出了一个原生API的概念:customElements。关于这个 API ,主要作用就是它能够使开发者能够将HTML页面的功能封装为 custom elements(自定义标签)。大家有兴趣可以去MDN上看看:
言归正传,在这里,我抛出了自己脑海里的第二个问题:
问题二:用 defineCustomElement 生成的标签可以实现和其他Vue组件一样的自身状态管理和事件处理吗?
先来看看是否有同样的状态管理能力:
import { createApp, h, defineCustomElement, ref } from 'vue'const app = createApp(App)const MyVueElement = defineCustomElement({ setup () { const count = ref(0) return () => h('div', { onClick: () => count.value++ }, `点击${count.value}`) }})customElements.define('my-vue-element', MyVueElement)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
我按照文档中所说的方式创建并注册了一个原生自定义元素 my-vue-element,然后我现在打开浏览器,直接在浏览器控制台中输入这两行代码:
然后我看到在页面中确实渲染出了我们刚刚注册的组件,并且点击元素,其设置的count会正常增加,说明它确实是实现了自身的状态管理功能的:
OK,自身状态管理没问题,那么再来看看是否支持事件。我们需要稍微修改一下代码,然后先测试一下,普通的Vue 组件的自定义事件是否能跑通,防止代码写错了:
import { createApp, h, defineComponent } from 'vue'const app = createApp(App)const MyVueElement = defineComponent({ props: { title: { type: String, required: true } }, emits: ['update:title'], setup (props, { emit }) { return () => h('div', [ h('div', props.title), h('input', { value: props.title, onInput: (e: any) => emit('update:title', e.target.value) }) ]) }})app.component('MyVueElement1', MyVueElement)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
OK,普通的Vue自定义组件没问题,接下来看看 defineCustomElement 创建的原生自定义元素是否支持:
import { createApp, h, defineCustomElement } from 'vue'const app = createApp(App)const MyVueElement = defineCustomElement({ props: { title: { type: String, required: true } }, emits: ['update:title'], setup (props, { emit }) { return () => h('div', [ h('div', props.title), h('input', { value: props.title, onInput: (e: any) => emit('update:title', e.target.value) }) ]) }})customElements.define('my-vue-element', MyVueElement)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
结果得出,由 defineCustomElement 创建出来的组件没办法支持事件处理的。
OK,三种API差不多介绍完啦~目前我只研究到了这个程度,如大佬们看到有问题的地方,请多多指教哈