当前位置:首页 > 人工智能

Vite+Vue2+Composition-api++TypeScript搭配如何开发项目?

  

前言

Vite相信大家都用过,配何它是项目一种新型前端开发与构建工具,能够显著提升前端开发体验。配何我们在搭建Vite项目,项目选择Vue模板之后,配何默认会下载Vue3模板。项目如果你的配何公司现在还没有准备使用Vue3,而在使用Vue2,项目那么这篇文章值得你继续看下去。配何下面,项目我将带大家如何搭建一个 Vite+Vue2+Composition-api+<script setup>+TypeScript  搭配使用的配何项目。这篇文章很干,项目请大家点点赞哦!配何

安装所需依赖

又到了实战环节,项目下面可以一步步跟着我哦!配何我这里使用的是yarn 依赖管理工具。

初始化项目

这里使用快捷初始化命令:

yarn init -y 

创建完package.json文件之后,我们可以手动修改下项目名称字段name:vitevue2p。

初始化Vite

安装Vite。

yarn add vite -D 

初始化Vue2

我们需要安装Vue2,所以直接这样安装。

yarn add vue 

目前,我安装的版本是^2.6.14。

另外,我们还需要安装vue-template-compiler这个依赖,此包可用于将Vue 2.0模板预编译为渲染函数,以避免运行时编译开销和CSP限制。云南idc服务商在编写具有非常特定需求的构建工具时,才需要单独使用它。所以,我们这里单独安装。

yarn add vue-template-compiler -D 

最后,如果想让Vite支持Vue2,就必须安装这个依赖vite-plugin-vue2。

yarn add vite-plugin-vue2 -D 

支持Composition-api

Composition-api字面意思是组合API,它是为了实现基于函数的逻辑复用机制而产生的。这也是Vue3亮点之一,那么我们如何才能够在Vue2项目中使用呢?这需要安装@vue/composition-api依赖。

yarn add @vue/composition-api 

支持<script setup>语法

<script setup>是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖,是Vue3.2新加入的语法。那么,我们也可以在Vue2项目中使用它。

你需要安装unplugin-vue2-script-setup依赖。

yarn add unplugin-vue2-script-setup -D 

了解更多,可以查看https://github.com/antfu/unplugin-vue2-script-setup。

在Vue2项目中使用Volar

以下是官方的解释:

我们建议将 VS Code 与 Volar 结合使用以获得最佳体验(如果您拥有 Vetur,您可能希望禁用它)。使用 Volar 时,服务器托管您需要安装 @vue/runtime-dom 作为 devDependencies 以使其在 Vue 2 上工作。

yarn add @vue/runtime-dom -D 

支持TypeScript语法

随着应用的增长,静态类型系统可以帮助防止许多潜在的运行时错误,所以我们推荐使用TypeScript。

yarn add typescript -D 

最后,我把安装的所有依赖列出来,可以参照有没有漏的。

"dependencies": {    "@vue/composition-api": "^1.1.5",   "vue": "^2.6.14" }, "devDependencies": {    "@vue/runtime-dom": "^3.2.11",   "typescript": "^4.4.3",   "unplugin-vue2-script-setup": "^0.6.4",   "vite": "^2.5.7",   "vite-plugin-vue2": "^1.8.1",   "vue-template-compiler": "^2.6.14" } 

搭建项目架构

首先,我先列出我自己搭建的项目文件目录,我是参照Vite默认模板而创建的文件目录。

- public   -- favicon.ico - src   -- assets     --- logo.png   -- components     --- Async.vue     --- Bar.vue     --- Foo.vue     --- HelloWorld.vue   -- App.vue   -- main.ts   -- shims-vue.d.ts - index.html - package.json - ref-macros.d.ts - tsconfig.json - vite.config.ts 

下面,我们按排列顺序分别看下文件中都放了什么东西?

public文件夹中放着一个ico图标文件,这个不再说明。src文件夹中文件有点多,我们放在最后讨论。

index.html

谈到index.html这个文件,我们需要引入Vite官网一段话:

你可能已经注意到,在一个 Vite 项目中,index.html 在项目最外层而不是在 public 文件夹内。这是有意而为之的:在开发期间 Vite 是一个服务器,而 index.html 是该 Vite 项目的源码库入口文件。

Vite 将 index.html 视为源码和模块图的一部分。Vite 解析 <script type="module" src="..."> ,这个标签指向你的 JavaScript 源码。甚至内联引入 JavaScript 的 <script type="module"> 和引用 CSS 的 <link href> 也能利用 Vite 特有的功能被解析。另外,index.html 中的 URL 将被自动转换,因此不再需要 %PUBLIC_URL% 占位符了。

<!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <link rel="icon" href="/favicon.ico" />   <meta name="viewport" content="width=device-width, initial-scale=1.0">   <title>Vite App</title> </head> <body>   <div id="app"></div>   <script type="module" src="/src/main.ts"></script> </body> </html> 

package.json

这个文件定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。这里,需要注意的是我们自定义了"scripts"字段,有三个命令:"vite --open"、"vite preview"、"vite build"。

{    "name": "vitevue2p",   "version": "0.1.1",   "description": "",   "keywords": [],   "license": "MIT",   "main": "dist/index.js",   "module": "dist/index.mjs",   "scripts": {      "dev": "vite --open",     "serve": "vite preview",     "build": "vite build"   },   "dependencies": {      "@vue/composition-api": "^1.1.5",     "vue": "^2.6.14"   },   "devDependencies": {      "@vue/runtime-dom": "3.2.11",     "typescript": "^4.4.3",     "unplugin-vue2-script-setup": "^0.6.4",     "vite": "^2.5.7",     "vite-plugin-vue2": "^1.8.1",     "vue-template-compiler": "^2.6.14"   } } 

ref-macros.d.ts

以d.ts后缀结尾的是TypeScript中的类型定义文件。我们知道自从引入 Composition API 以来,一个主要未解决的问题是 refs 与reactive的使用,到处使用 .value可能很麻烦,如果不使用类型系统,很容易错过。一些用户特别倾向于只使用reactive,这样他们就不必处理refs。

为了优化,官方提出了一个RFC,大家可以打开下面这个网址 https://github.com/vuejs/rfcs/discussions/369 了解一下。

下面,可以看下一个简单的例子。

// declaring a reactive variable backed by an underlying ref let count = $ref(1) // no need for .value anymore! console.log(count) // 1 function inc() {    // assignments are reactive   count++ } 

另外,这是一项实验性功能。实验性功能可能会改变补丁版本之间的行为。建议将您的 vue 依赖项固定到确切的版本以避免损坏。

言归正传,我们来看下ref-macros.d.ts文件中的内容。

import type {    Ref,   UnwrapRef,   ComputedRef,   WritableComputedOptions,   WritableComputedRef,   ShallowUnwrapRef, } from @vue/composition-api declare const RefMarker: unique symbol   type RefValue<T> = T & {  [RefMarker]?: any } declare const ComputedRefMarker: unique symbol   type ComputedRefValue<T> = T & {  [ComputedRefMarker]?: any } declare const WritableComputedRefMarker: unique symbol   type WritableComputedRefValue<T> = T & {  [WritableComputedRefMarker]?: any }   type ToRawRefs<T extends object> = {      [K in keyof T]: T[K] extends ComputedRefValue<infer V>       ? ComputedRefValue<V>       : T[K] extends WritableComputedRefValue<infer V>         ? WritableComputedRef<V>         : T[K] extends RefValue<infer V>           ? Ref<V>           : T[K] extends object             ? T[K] extends             | Function             | Map<any, any>             | Set<any>             | WeakMap<any, any>             | WeakSet<any>               ? T[K]               : ToRawRefs<T[K]>             : T[K];   } /**    * Vue ref transform macro for binding refs as reactive variables.    */ declare function _$<T>(arg: ComputedRef<T>): ComputedRefValue<T> declare function _$<T>(   arg: WritableComputedRef<T> ): WritableComputedRefValue<T> declare function _$<T>(arg: Ref<T>): RefValue<T> declare function _$<T extends object>(arg?: T): ShallowUnwrapRef<T> /**    * Vue ref transform macro for accessing underlying refs of reactive varaibles.    */ declare function _$$<T>(value: T): ComputedRef<T> declare function _$$<T>(   value: WritableComputedRefValue<T> ): WritableComputedRef<T> declare function _$$<T>(value: RefValue<T>): Ref<T> declare function _$$<T extends object>(arg: T): ToRawRefs<T> declare function _$ref<T>(arg?: T | Ref<T>): RefValue<UnwrapRef<T>> declare function _$shallowRef<T>(arg?: T): RefValue<T> declare function _$computed<T>(   getter: () => T,   // debuggerOptions?: DebuggerOptions ): ComputedRefValue<T> declare function _$computed<T>(   options: WritableComputedOptions<T>,   // debuggerOptions?: DebuggerOptions ): WritableComputedRefValue<T> declare global {    const $: typeof _$   const $$: typeof _$$   const $ref: typeof _$ref   const $shallowRef: typeof _$shallowRef   const $computed: typeof _$computed } 

tsconfig.json

tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。

我们这里需要注意如果您的 IDE 缺少全局类型。

{    "compilerOptions": {      "types": [       "unplugin-vue2-script-setup/types"     ]   } } 

Volar 优先支持 Vue 3。Vue 3 和 Vue 2 模板有些不同。您需要设置 ExperimentCompatMode 选项以支持 Vue 2 模板。

{    "compilerOptions": {      ...   },   "vueCompilerOptions": {      "experimentalCompatMode": 2   }, } 

最后,文件内容如下:

{    "compilerOptions": {      "target": "es2017",     "module": "esnext",     "moduleResolution": "node",     "esModuleInterop": true,     "strict": true,     "strictNullChecks": true,     "resolveJsonModule": true,     "types": [       "unplugin-vue2-script-setup/types"     ]   },   "vueCompilerOptions": {      "experimentalCompatMode": 2   } } 

vite.config.ts

这个文件是Vite的配置文件。当以命令行方式运行 vite 时,Vite 会自动解析项目根目录下名为 vite.config.js(或vite.config.ts) 的文件。

这里需要注意 refTransform 现在是插件根级选项,需要手动定义为true。(为什么配置refTransform,可以看上面ref-macros.d.ts文件中对refs处理,不使用.value的介绍)。

另外,如果想支持<script setup>语法,必须在这里以插件的形式配置。

import {  defineConfig } from vite import {  createVuePlugin as Vue2 } from vite-plugin-vue2 import ScriptSetup from unplugin-vue2-script-setup/vite export default defineConfig({    plugins: [     Vue2(),     ScriptSetup({        refTransform: true,     }),   ], }) 

介绍完这些文件,剩下的就是src文件夹中的文件了,因为文件过多,我们把它单独放在Src文件夹栏目中。

Src文件夹

assets文件中只有logo.png一个图片,你可以把静态文件放在当中,这里不多过介绍。

main.ts

这是Vue2的入口文件,我们可以看到这里VueCompositionAPI被当做插件引入。另外,我们引入的App.vue以及其他*.vue为后缀的文件,需要有专门的类型定义文件进行声明,在下面的shims-vue.d.ts文件中我们会讲到。

import Vue from vue import VueCompositionAPI from @vue/composition-api import App from ./App.vue Vue.use(VueCompositionAPI) const app = new Vue({  render: h => h(App) }) app.$mount(#app) 

shims-vue.d.ts

declare module *.vue {    import Vue from vue   export default Vue } 

App.vue

这个文件是页面入口文件。我们来看下它是如何写的,这是Vue2项目,但是写法与Vue3项目无异,只不过在Vue2项目中需要@vue/composition-api使用Composition-api,而Vue3项目直接引入vue。

另外,这里看到我们直接使用<script setup>语法,替换了之前setup()方法,使代码更简洁。还有我们可以直接引入组件,直接在模板中使用。

更多关于<script setup>语法的内容可以看看https://v3.cn.vuejs.org/api/sfc-script-setup.html,了解更多使用方法。

<template>   <div id="app">     <img alt="Vue logo" src="./assets/logo.png">     <hello-world name="Vue 2 + TypeScript + Vite" @update="onUpdate" />     <async-component />   </div> </template> <script setup lang="ts"> import {  defineAsyncComponent } from @vue/composition-api import HelloWorld from ./components/HelloWorld.vue const AsyncComponent = defineAsyncComponent(() => import(./components/Async.vue)) function onUpdate(e: any) {    console.log(e) } </script> <script lang="ts"> export default {    name: App, } </script> <style> #app {    font-family: Avenir, Helvetica, Arial, sans-serif;   -webkit-font-smoothing: antialiased;   -moz-osx-font-smoothing: grayscale;   text-align: center;   color: #2c3e50;   margin-top: 60px; } </style> 

HelloWorld.vue

然后,我们再看下这个文件中什么内容。这里需要注意的是$ref()、$computed()方法,这就是之前提到的refTransform语法,不得不说,这比以前使用.value处理方便多了。

<template>   <div>     <h1>{ {  msg }}, { {  name }}</h1>     <button @click="inc">       Inc     </button>     <div>{ {  count }} x 2 = { {  doubled }}</div>     <button @click="dec()" v-html="decText" />     <component :is="count > 2 ? Foo : Bar" />   </div> </template> <script setup lang="ts"> import {  watch } from @vue/composition-api import Foo from ./Foo.vue import Bar from ./Bar.vue const props = withDefaults(defineProps<{  msg: string; name: string | number }>(), {  msg: Hello }) const emit = defineEmits([update]) let count = $ref(1) // eslint-disable-next-line prefer-const let doubled = $computed(() => count * 2) function inc() {    count += 1 } function dec() {    count -= 1 } const decText = <b>Dec</b> watch(()=>count, value => emit(update, value)) </script> <style scoped> button{    margin: 20px 0; } </style> 

其他文件就不过多介绍了,就只是简单的模板文件。

Foo.vue

<template>   <div>Foo</div> </template> 

Bar.vue

<template>   <div>Bar</div> </template> 

Async.vue

<template>   <div>Async Component</div> </template> 

结语

最后,我们启动下项目。

yarn dev 

如上图所示,启动成功。

相信这样可以在一定程度上提升你 Vue 2 的开发体验,赶快来!

以下是本篇文章的源码地址:

https://github.com/maomincoding/viteVue2p 

如果觉得这篇文章对你有帮助,感谢点赞哦~

本文转载自微信公众号「前端历劫之路」,可以通过以下二维码关注。转载本文请联系前端历劫之路公众号。

分享到:

滇ICP备2023006006号-16