Vue3应用之使用Vite搭建Vue3项目以及TypeScript、Vue Router、Vuex、Ant Design的使用

18 篇文章 7 订阅
11 篇文章 1 订阅

尤大的 Vue3.0 已经发布有一阵子了, 已经很成熟了。今天想起来,是时候该上手体验分享一波了。

前言

大家都知道,在 Vue3 生态系统中有一个新构建工具 Vite ,它的开发服务器比 Vue CLI 快 10 ~ 100倍,是不是很好奇?具体的内容可以移步至:迟到的 Vue3.0 与 Vite 的体验学习总结 的 七、Vite 与 Vue CLI 阅读。

本文将主要分享如何使用 Vite 来创建一个 Vue3.0 的项目,并且结合相关内容(TypeScriptVue RouterVuexAnt Design等)编写一个简单的Demo。


使用 Vite 搭建 Vue3.0 项目

1. 全局安装 Vite

npm install -g create-vite-app

2. 使用 Vite 创建 Vue3 项目

create-vite-app vue3-vite

可以发现瞬间创建完成。

Done. Now run:
  cd vue3-vite
  npm install (or `yarn`)
  npm run dev (or `yarn dev`)

根据提示安装依赖运行项目

C:\Users\jingx\Desktop\vite\vue3-vite>yarn dev
yarn run v1.22.10
warning package.json: No license field
$ vite
[vite] Optimizable dependencies detected:
vue

  Dev server running at:
  > Network:  http://10.7.40.138:3000/
  > Local:    http://localhost:3000/

项目成功启动:
在这里插入图片描述

3. 配置 Vite

在项目中创建一个 vite.config.jsvite.config.ts 文件。如果在当前工作目录中找到 Vite,它将自动使用它。

vite.config.ts 基本配置:

const path = require("path")

function pathResolve(dir: string) {
    return path(__dirname, ".", dir);
}

module.exports = {
    // 服务端渲染
    ssr: false,
    // 是否开启 https
    https: false,
    // 设置目录别名
    alias: {
        // 键必须以斜线开始和结束
        '/@/': pathResolve('/src'),
        '/@components/': pathResolve('/src/components')
    },
    // 跨域设置
    proxy: {
        // 如果是 /api 开头,则访问如下地址
        '/api': 'http://10.7.40.138:8080',
    },
    // 引入第三方的配置
    optimizeDeps: {
        include: ["moment", "echarts", "axios", "mockjs", "@ant-design/icons-vue"]
    },
}

详细 config.ts 配置参考:Vite - config.ts

4. 插件依赖安装

  • eslint-plugin-vue

    yarn add -D eslint eslint-plugin-vue
    
  • TypeScript

    yarn add -D typescript
    

    参考文档:

  • Vue Router

    yarn add vue-router@next
    
  • Vuex

    yarn add vuex@@next
    
  • Ant Design Vue

    yarn add ant-design-vue@next
    
    • 完整引入组件

      import { createApp } from 'vue'
      import App from './App.vue'
      import './index.css'
      import Antd from 'ant-design-vue';
      import 'ant-design-vue/dist/antd.css'; 
      
      createApp(App).use(Antd).mount('#app');
      

      以上代码便完成了 Antd 的引入。需要注意的是,样式文件需要单独引入。

      注意:createApp(App).mount(’#app’).use(Antd)
      .mount(’#app’) 和 .use(Antd) 的顺序一定不要写错,否则会报:createApp(…).mount(…).use is not a function 的错误。
      这也是以为小伙伴提醒我的,非常感谢。

    • 按需引入组件

      # 需要使用 babel-plugin-import 来进行按需加载
      yarn add -D babel-plugin-import
      

      配置 .babelrc 文件

      {
        "plugins": [
          ["import", { "libraryName": "ant-design-vue", "libraryDirectory": "es", "style": "css" }] // `style: true` 会加载 less 文件
        ]
      }
      
      # 按需加载需要的组件
      import { Button } from 'ant-design-vue';
      
  • Sass

    yarn add -D sass
    

使用插件开发完整项目

  • 使用 TypeScript

    • TypeScriptJavaScript 类型的超集,它可以编译成纯 js
    • 我们在项目中要做的就是将 .js 文件更新成 .ts 文件即可,至于里面的细节内容可以去 TypeScript官网 阅读文档学习。
    • 当然,在项目中也可以不使用 ts,其他内容都是相同的,本项目是为了体验 ts 才使用的,如果不使用可以直接省略。
    • 将项目中的 mian.js 重命名为 main.ts,并且将项目中引用该文件的位置 index.html 也同步更新扩展名。
  • 使用路由 Vue Router

    • 新建文件: router/index.ts 用于配置路由信息

      import { createRouter, createWebHistory } from 'vue-router';
      const routes = [
        {
          path: '/',
          name: 'Login',
          component: () => import("/@/views/Login.vue"),
        }, {
          path: '/Home',
          component: () => import('/@/views/Home.vue'),
          children: [
            {
              path: '/index',
              component: () => import('/@/views/Index.vue'),
              meta: { title: '首页' },
            },
            {
              path: '/admin',
              component: () => import('/@/views/Admin.vue'),
              meta: { title: '状态管理' },
            },
            {
              path: '/center',
              component: () => import('/@/views/Center.vue'),
              meta: { title: '个人中心' },
            }
          ]
        }
      ]
      
      export default createRouter({
        history: createWebHistory(),
        routes,
      })
      
    • 需要在 main.ts 中注入该路由信息。

    • 可以在 .vue 页面中使用 <router-view><router-link> 等来使用路由。

  • 使用状态管理 Vuex

    Vuex 实例对象属性 主要有5个核心属性:statemutationsgettersactionsmodules。具体使用就不再赘述了,使用方法大家跟 Vue2 的一样。

    • 新建文件: store/index.ts 用于配置 vuex。其中statemutations 是一定要定义的,其他的三个属性对象根据实际需要。

      import { createStore } from 'vuex'
      export default createStore({
          state: {
              count: 0,
          },
          getters: {},
          mutations: {
              add(state) {
                  state.count++;
              }
          },
          actions: {
              add(ctx) {
                  ctx.commit('add')
              }
          },
          modules: {}
      })
      
    • 需要在项目的 main.ts 中将 Vuex 注册到全局实例中

    • 在文件中使用:通过 this.$store.state.xxx 来获取状态的值,可以直接使用状态,也可以在vue计算属性 computed 中使用。在页面的具体使用见 Admin.vue 内容。

  • 添加新页面 Views

    • Login.vue 登录页面

      <template>
        <div class="login-wrap">
          <div class="ms-login">
            <div class="ms-title">后台管理系统</div>
            <div class="ms-content">
              <a-form layout="inline" :model="formInline" @submit="handleSubmit">
                <a-form-item>
                  <a-input v-model:value="formInline.user" placeholder="Username">
                    <template #prefix
                      ><UserOutlined style="color: rgba(0, 0, 0, 0.25)"
                    /></template>
                  </a-input>
                </a-form-item>
                <a-form-item>
                  <a-input
                    v-model:value="formInline.password"
                    type="password"
                    placeholder="Password"
                  >
                    <template #prefix
                      ><LockOutlined style="color: rgba(0, 0, 0, 0.25)"
                    /></template>
                  </a-input>
                </a-form-item>
                <a-form-item>
                  <a-button
                    type="primary"
                    html-type="submit"
                    :disabled="formInline.user === '' || formInline.password === ''"
                  >
                    Log in
                  </a-button>
                </a-form-item>
              </a-form>
            </div>
          </div>
        </div>
      </template>
      
      <script>
      import { UserOutlined, LockOutlined } from "@ant-design/icons-vue";
      import { reactive, getCurrentInstance } from "vue";
      import { message } from "ant-design-vue";
      
      export default {
        setup() {
          const formInline = reactive({
            username: "",
            password: "",
          });
      
          const { ctx } = getCurrentInstance();
      
          const handleSubmit = () => {
            message.info("登录成功!");
      
            setTimeout(() => {
              ctx.$router.push("/index");
            }, 1000);
          };
      
          return {
            formInline,
            handleSubmit,
          };
        },
        components: {
          UserOutlined,
          LockOutlined,
        },
      };
      </script>
      <style scoped>
      // .... 具体代码见 Github
      </style >
      
    • Home.vue 后台页面

      <template>
        <a-layout id="components-layout-demo-custom-trigger">
          <a-layout-sider v-model:collapsed="collapsed" :trigger="null" collapsible>
            <div class="logo">
              <span>后台管理中心</span>
            </div>
            <a-menu theme="dark" mode="inline" v-model:selectedKeys="selectedKeys">
              <a-menu-item key="1">
                <router-link :to="{ path: '/index' }">首页</router-link>
              </a-menu-item>
              <a-menu-item key="2">
                <router-link :to="{ path: '/admin' }">状态管理Vuex</router-link>
              </a-menu-item>
              <a-menu-item key="3">
                <router-link :to="{ path: '/center' }">个人中心</router-link>
              </a-menu-item>
            </a-menu>
          </a-layout-sider>
          <a-layout>
            <a-layout-header style="background: #fff; padding: 0">
              <menu-unfold-outlined
                v-if="collapsed"
                class="trigger"
                @click="() => (collapsed = !collapsed)"
              />
              <menu-fold-outlined
                v-else
                class="trigger"
                @click="() => (collapsed = !collapsed)"
              />
            </a-layout-header>
            <a-layout-content
              :style="{
                margin: '24px 16px',
                padding: '24px',
                background: '#fff',
                minHeight: '280px',
              }"
            >
              <router-view></router-view>
            </a-layout-content>
          </a-layout>
        </a-layout>
      </template>
      
      <script>
      import {
        UserOutlined,
        VideoCameraOutlined,
        UploadOutlined,
        MenuUnfoldOutlined,
        MenuFoldOutlined,
      } from "@ant-design/icons-vue";
      
      export default {
        components: {
          UserOutlined,
          VideoCameraOutlined,
          UploadOutlined,
          MenuUnfoldOutlined,
          MenuFoldOutlined,
        },
        data() {
          return {
            selectedKeys: ["1"],
            collapsed: false,
          };
        },
      };
      </script>
      <style scoped>
      // .... 具体代码见 Github
      </style >
      
    • Index.vue 后台首页

      <template>
        <img class="img" src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2685630714,1375929910&fm=26&gp=0.jpg" alt="" srcset="">
      </template>
      
    • Admin.vue 状态管理页面Vuex

      <template>
        <h2>通过 Vuex 实现状态管理</h2>
        <h3>state from vuex: {{ count }}</h3>
        <br />
        <a-button type="primary" @click="add">add</a-button>
      </template>
      
      <script>
      import { computed, getCurrentInstance } from "vue";
      export default {
        setup() {
          const { ctx } = getCurrentInstance();
          const count = computed(() => ctx.$store.state.count);
          const add = () => {
            ctx.$store.commit("add");
          };
          return {
            count,
            add,
          };
        },
      };
      </script>
      
  • 根据实际更新 main.ts

    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import './styles/index.scss'
    import Antd from 'ant-design-vue';
    import 'ant-design-vue/dist/antd.css';
    
    const app = createApp(App)
    app.mount('#app')
    app.use(Antd)
    app.use(router)
    app.use(store)
    
    • 此处定义路由时可能会报找不到模块“xxx”或其相应的类型声明。ts(2307) 的错误,该解决方案请移至文章末尾查看。
  • 更新 App.vue

    <template>
      <div id="app">  
        <router-view></router-view>
      </div>
    </template>
    <script></script>
    <style>
      @import "./styles/index.scss";
    </style>
    

完整代码请移步至 GitHub 下载。


问题解决方案

1. 找不到模块“xxx”或其相应的类型声明。ts(2307)

  • 问题:在用 vue3 中使用 ts时,在 .ts 文件中引入 .vue 文件时出现以下报错:
    在这里插入图片描述

  • 原因:typescript 只能理解 .ts 文件,无法理解 .vue 文件

  • 解决方案:在项目根目录或 src 文件夹下创建一个后缀为 .d.tsshims-vue.d.ts 文件,告诉 TS 如何理解 .vue 文件,并写入以下内容:

    declare module '*.vue' {
        import { ComponentOptions } from 'vue'
        const componentOptions: ComponentOptions
        export default componentOptions
    }
    

    在次查看之前报错的地方,错误消失,问题解决。

    如果写了这个还是报错的话,新建一个 tsconfig.json 文件,也可以解决不需要总是打开 shims-vue.d.ts 来解决 TS 报错的问题

    {
      "compilerOptions": {
        "target": "esnext",
        "module": "esnext",
        "strict": false,
        "jsx": "preserve",
        "moduleResolution": "node"
      }
    }
    

至此,一个基本完整的小项目搭建完成,大家可以根据自己的需求进行项目的实际开发。


Vite2.0 已经发布了,如果想看一下具体内容,请参考:vite1.0还没学呢 这就出2.0了?

  • 8
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
以下是使用Vue3 + TypeScript + Vite + Element Plus + Router + Axios搭建前端项目框架的步骤: 1. 首先,确保你已经安装了Node.js和npm。你可以在命令行中运行以下命令来检查它们的版本: ```shell node -v npm -v ``` 2. 创建一个新的项目文件夹,并在该文件夹中打开命令行。 3. 在命令行中运行以下命令来初始化一个新的Vite项目: ```shell npm init vite ``` 在初始化过程中,你需要选择Vue作为模板,选择TypeScript作为语言,并填写项目名称。 4. 进入项目文件夹,并安装所需的依赖: ```shell cd your-project-name npm install ``` 5. 安装Vue RouterVuex和Axios: ```shell npm install vue-router@next vuex@next axios ``` 6. 在项目文件夹中创建一个新的文件夹,用于存放页面组件和路由配置文件。 7. 在src文件夹中创建一个新的文件夹,用于存放页面组件。 8. 在src文件夹中创建一个新的文件夹,用于存放路由配置文件。 9. 在src/router文件夹中创建一个新的文件,命名为index.ts,并在其中编写路由配置: ```typescript import { createRouter, createWebHistory } from 'vue-router'; import Home from '../views/Home.vue'; const routes = [ { path: '/', name: 'Home', component: Home, }, // 添加其他页面的路由配置 ]; const router = createRouter({ history: createWebHistory(), routes, }); export default router; ``` 10. 在src/main.ts文件中导入并使用Vue Router: ```typescript import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; createApp(App).use(router).mount('#app'); ``` 11. 在src/views文件夹中创建一个新的文件,命名为Home.vue,并在其中编写一个简单的页面组件: ```vue <template> <div> <h1>Welcome to Home Page</h1> </div> </template> <script> export default { name: 'Home', }; </script> ``` 12.src/App.vue文件中添加一个路由出口,用于显示组件: ```vue <template> <div id="app"> <router-view></router-view> </div> </template> <script> export default { name: 'App', }; </script> ``` 13. 在src/main.ts文件中导入并使用Element Plus: ```typescript import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; import ElementPlus from 'element-plus'; import 'element-plus/lib/theme-chalk/index.css'; createApp(App).use(router).use(ElementPlus).mount('#app'); ``` 14. 运行以下命令来启动开发服务器: ```shell npm run dev ``` 15. 打开浏览器,并访问http://localhost:3000,你将看到一个简单的页面,其中包含"Welcome to Home Page"的文本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值