包阅导读总结
1.
关键词:Vue3、组件编写、语法糖、复用、最佳实践
2.
总结:文章探讨了 Vue3 多组件的多种编写方式,包括 SFC 单文件组件、多模板方案、多组件(无状态/有状态)方案、Vue Vine 等,并对各方案的特点、使用场景和稳定性进行了分析,最后给出了不同情况下的推荐方案。
3.
– SFC 单文件组件
– 是 Vue 官方默认的组件化开发方式
– 但在某些简单或父组件代码量不多的情况下,拆分可能繁琐
– 多模板方案
– 强调在一个单文件组件中提取复用模板代码
– 如 createReusableTemplate(VueUse 提供)和 namedTemplate(Vue Macros 提供)
– 多组件(无状态)方案
– 常见方案为 JSX
– 包括 defineComponent render、defineRender、setupSFC 等
– 多组件(有状态)方案
– 包括多次定义 defineComponent render 和 setupComponent 两种方式
– Vue Vine
– 支持 Vue3 + Vite + TS
– 函数作为组件,用 vine 标记的模板字符串声明组件模板
– 总结
– 多数情况首选 SFC 单文件组件
– 模板复用建议采用 VueUse 的 createReusableTemplate
– 多组件情景建议首选 defineComponent render,尝鲜可选 setupComponent 或 Vue Vine
思维导图:
文章地址:https://juejin.cn/post/7394476656758947878
文章来源:juejin.cn
作者:pany
发布时间:2024/7/23 6:37
语言:中文
总字数:2384字
预计阅读时间:10分钟
评分:88分
标签:Vue3,组件编写,前端框架,SFC,JSX
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
Vue 越来越像 React 了?不,是 Vue 越来越好用了。
Vue 本身以及周边生态在设计语法糖上几乎没让我失望过,包括本次在 VueConf 2024 深圳盛会上正式亮相的 Vue Vine。
它的出现引起了我对 Vue3 组件编写方式的好奇,以及哪一种方式更接近「最佳实践」?
那么 Vue Vine 究竟是一个什么有意思的工具?以及与这个工具类似的其他工具都有哪些?它们分别对应的场景是什么?该如何选择?
下面让我来为大家一一道来:
SFC 单文件组件
我们在用编写代码时,经常是会出现重复的代码,就比如:
<template> <dialog v-if="showInDialog"> </dialog> <div v-else> </div></template>
如果我们不想将「代码片段」这部分重复的写两遍该怎么办?
这时候,我们往往会将这个代码片段拎出来放在一个新建的 .vue
子组件中:
<template> <dialog v-if="showInDialog"> <Content /> </dialog> <div v-else> <Content /> </div></template><template> </template>
这本身是 Vue 官方默认的一种组件化开发方式,也就是 SFC 单文件组件。
但是在某些情况下,我们可能并不想将这部分「代码片段」拆分成独立的单文件,比如「代码片段」非常的简单的时候,又或者父组件代码量并不多的时候…
并且强行拆分带来的一系列繁琐操作有时也挺烦人,这时候我们就得找一些方案来解决这种单文件组件解决不了的情况。
多模板方案
多模板方案强调的是在一个单文件组件中提取出能复用的模板代码,换句话说就是提取出公共的 HTML 代码。
createReusableTemplate
VueUse 是一个提供了非常多实用的 Vue3 组合式函数(Composables)的工具库,其中便提供了一个创建可重用模板的 createReusableTemplate
方法,文档链接是 vueuse.org/core/create…
使用方式非常简单:
<script setup>import { createReusableTemplate } from '@vueuse/core'const [DefineTemplate, ReuseTemplate] = createReusableTemplate()</script><template> <DefineTemplate> </DefineTemplate> <dialog v-if="showInDialog"> <ReuseTemplate /> </dialog> <div v-else> <ReuseTemplate /> </div></template>
用导入的 DefineTemplate
组件注册模板(注意此时不会渲染内容),然后再用 ReuseTemplate
组件来渲染刚才注册的模板(注意 DefineTemplate 必须在 ReuseTemplate 之前使用)即可。
namedTemplate
Vue Macros 像魔法一样,能让你在 Vue3 项目中体验到更多超前的语法糖。并且它还是一块 Vue 语法的试验田,里面诸多的语法都有机会被 Vue 官方收录!
它提供了一个命名模板 namedTemplate
特性,文档链接是 vue-macros.dev/zh-CN/featu…
使用方式如下:
<script setup>const showInDialog = ref(false)</script><template name="reusable"> </template><template> <template v-if="showInDialog"> <dialog> <template is="reusable" /> </dialog> </template> <template v-else> <div> <template is="reusable" /> </div> </template></template>
多组件(无状态)方案
多组件(无状态)方案强调的是在一个文件中定义单个有状态组件 + 多个无状态组件
JSX
JSX 是多组件实践中最常见的一个方案,霸榜了「多组件(无状态)方案」,并且 JSX 方案中写法非常多,涉及到有状态的「组件」和无状态的「函数组件」的知识。
我这里挑选三个常见的方案:defineComponent render
、defineRender
、setupSFC
,其他写法并不主流,我们就不在这里提及了。
defineComponent render
这是 Vue3 中最朴实无华的使用 JSX 的方式!属于 Vue3 + JSX 梦开始的地方
import { defineComponent, ref } from "vue"export default defineComponent({ setup() { const showInDialog = ref(false) function Content() { return <div>代码片段</div> } return () => ( <div> {showInDialog.value ? ( <dialog> <Content /> </dialog> ) : ( <div> <Content /> </div> )} </div> ) }})
defineComponent
方法用于定义组件,在 setup
方法内部我们可以利用「函数组件」来定义一些需要复用的「无状态组件」,最后直接返回 render 函数即可。
本质上就是「defineComponent + render + 无状态函数组件 + JSX」的配合使用
defineRender
而 defineRender 则可以看作是 defineComponent render
的升级版,它也是 Vue Macros 提供的方法。
使用defineRender
可以直接在<script setup>
中定义渲染函数:
<script setup lang="jsx">const showInDialog = ref(false)function Content() { return <div>代码片段</div>}defineRender( <div> {showInDialog.value ? ( <dialog> <Content /> </dialog> ) : ( <div> <Content /> </div> )} </div>)</script>
这种方式虽然告别了 defineComponent
和 Options API
使得代码更加轻量,但是在 .vue
中写 jsx
还是不够优雅。
于是又有了关于它的升级版 setupSFC
!
setupSFC
setupSFC 是我比较喜欢的在 Vue3 中编写 JSX 组件的方案之一(它依旧是 Vue Macros 提供的方法)。
我们开发时需要定义后缀为 .setup.tsx / .setup.jsx
的文件:
const showInDialog = ref(false)function Content() { return <div>代码片段</div>}export default () => ( <div> {showInDialog.value ? ( <dialog> <Content /> </dialog> ) : ( <div> <Content /> </div> )} </div>)
告别了 defineComponent
和 Options API
,将 setup
和 jsx
完美的融合。
多组件(有状态)方案
多组件(有状态)方案强调的是在一个文件中定义多个有状态组件
JSX
没错,JSX 霸榜了「多组件(无状态)方案」后,也活跃在「多组件(有状态)方案」中!
defineComponent render
其实,我们把前文提到的「defineComponent render」多定义几遍,也就是本方案了。
import { defineComponent, ref } from "vue"const Content = defineComponent({ setup() { return () => <div>代码片段</div> }})const App = defineComponent({ setup() { const showInDialog = ref(false) return () => ( <div> {showInDialog.value ? ( <dialog> <Content /> </dialog> ) : ( <div> <Content /> </div> )} </div> ) }})export default App
在一个文件中堆砌 defineComponent
即可,这个形式类似于 React 中的 “类组件”
setupComponent
既然 “类组件” 有了,那么有没有 “有状态的函数组件” 呢?
于是 Vue Macros 它又又又提供了一个非常酷的语法 setupComponent,可以在 .jsx
文件中书写多个 “有状态函数组件”,这也是我最喜欢的在 Vue3 中编写 JSX 组件的方案。
const Content = defineSetupComponent(() => { return <div>代码片段</div>})const App = defineSetupComponent(() => { const showInDialog = ref(false) return ( <div> {showInDialog.value ? ( <dialog> <Content /> </dialog> ) : ( <div> <Content /> </div> )} </div> )})export default App
Vue Vine
有没有发现,文章到目前为止的多组件方案中,全是基于 JSX 的。那有没有一种既用模板又能支持多组件的方案呢?
那就得说说 Vue Vine 了。
值得注意的是 Vine 仅支持 Vue3 + Vite + TS
,然后我们建立一个 .vine.ts
文件:
function Content() { return vine`<div>代码片段</div>`}function App() { const showInDialog = ref(false) return vine` <div> <template v-if="showInDialog"> <dialog> <Content /> </dialog> </template> <template v-else> <div> <Content /> </div> </template> </div> `}export default App
一个函数就是一个组件,然后用 vine
标记的模板字符串声明组件模板。
这种书写方式和刚刚提到的 setupComponent
非常相似,都属于 “有状态的函数组件”,但区别就是一个返回 JSX,一个返回模板,模板的优势就在于 Vue 对其有编译时优化。
总结
- 大多数情况下,依旧首选
SFC 单文件组件
方案就行 - 针对模板的复用,我虽然更喜欢 Vue Macros 提供的
namedTemplate
方案,但是鉴于目前的稳定性,还是建议采用 VueUse 提供的createReusableTemplate
方案 - 针对多组件情景,现阶段还是建议首选 JSX 方案下稳妥的
defineComponent render
方案。喜欢尝鲜的开发者可以大胆尝试 Vue Macros 提供的setupComponent
或选择Vue Vine
End
感谢阅读,如有帮助可以点赞评论支持一下~