美文网首页
Vue3+Vite+TS+VueRouter+Element-p

Vue3+Vite+TS+VueRouter+Element-p

作者: 锋叔 | 来源:发表于2024-08-27 21:34 被阅读0次
    本篇内容

    环境搭建、依赖安装、路由基本结构创建、界面展示、记录遇到的问题和解决方式

    环境搭建

    Node、Npm、Vue3、Vite、TS、VueRouter、Element-Plus等依赖和插件安装。

    Node安装

    参照官网安装最新Node
    使用nvm管理和安装
    (PS:mac和window对于nvm的安装顺则顺,不顺会很难整,给进阶者使用,不建议小白硬整。)

    Npm安装镜像

    Node装好了就自带了,但是需要使用国内镜像。

    npm config set registry https://registry.npm.taobao.org
    

    顺带把yarn装上。(yarn最大的用处就是,npm有时候装不了的它可以,算是一个补充优化的包管理安装工具。)

    安装yarn
    npm install -g yarn
    

    开始真正创建项目

    创建一个项目文件夹,在目录下初始化npm项目:

    npm init -y
    

    继续安装必要的依赖,安装 Vite:

    npm install -D vite
    

    安装 Vue 3:

    npm install vue
    

    安装 TypeScript:

    npm install -D typescript
    

    安装 Element-Plus:

    npm install element-plus
    

    安装 Vue Router:

    npm install vue-router
    

    安装 TypeScript 类型定义:
    安装 Vue 和 Vue Router 的 TypeScript 类型定义:

    npm install -D @types/vue @types/vue-router
    
    如果一切顺利你就可以继续创建项目了,而如果不顺利我大概讲一下可能遇到的问题。
    • npm的镜像问题,可以自行搜索,mac可能还有权限问题,可以搜索mac如何

    开始建立项目结构

    这只是当前最简单的结构,后续还会更新。

    • src/:存放源代码
      —— assets /: 存放图片/svg/fonts等静态资源
      —— compoments /: 公共组件等
      —— router :/ 路由文件
      —— styles :/ 样式文件
      —— views :/ 主要功能组件
      —— App.vue
      —— main.ts
    • index.html :/入口html
    • tsconfig.json :/ typescript配置文件
    • vite.config.mjs :/ vite项目的主要配置文件

    以下是每个文件简单的结构

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>V3ViteTS项目</title>
    </head>
    <body>
      <div id="app"></div>
      <script type="module" src="/src/main.ts"></script>
    </body>
    </html>
    

    tsconfig.json

    {
      "compilerOptions": {
        "moduleResolution": "nodenext", // 或 "node" 对于较旧的 Node.js 版本
        "module": "nodenext",
        "target": "esnext",
        "strict": true,
        "jsx": "preserve",
        "esModuleInterop": true,
        "sourceMap": true,
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
        },
        "types": ["vue"] // 添加 "vue" 到 types 数组中
      },
      "include": [
        "src/**/*.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "tests/**/*.ts",
        "tests/**/*.tsx"
      ],
      "exclude": [
        "node_modules",
        "**/*.spec.ts"
      ]
    }
    

    文件部分常用熟悉属性解释:

    compilerOptions:包含编译选项。
    target: 目标 JavaScript 版本,这里是 esnext。
    module: 模块系统,这里是 esnext。
    lib: 应该包含的标准库类型声明。
    allowJs: 是否允许编译 JavaScript 文件。
    skipLibCheck: 是否跳过类型声明文件的类型检查。
    esModuleInterop: 启用 ES 模块互操作性。
    allowSyntheticDefaultImports: 允许从模块默认导入没有默认导出的对象。
    strict: 开启所有严格的类型检查选项。
    forceConsistentCasingInFileNames: 强制在文件名中使用一致的大小写。
    noFallthroughCasesInSwitch: 禁止 switch 语句中的 fall-through。
    moduleResolution: 模块解析策略,这里是 node。
    resolveJsonModule: 允许导入 .json 文件。
    isolatedModules: 将每个文件作为一个独立的模块进行编译。
    noEmit: 不生成输出文件。
    jsx: JSX 处理模式。

    include:要包含在编译过程中的文件路径。
    ["src"]: 包含 src 目录下的所有文件。
    exclude:要排除在编译过程之外的文件路径。
    ["node_modules", "*/.spec.ts"]: 排除 node_modules 目录下的所有文件和所有的测试文件。


    vite.config.mjs

    // vite.config.mjs
    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    import Components from 'unplugin-vue-components/vite';
    import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
    import path from 'path';
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [
        vue(),
        Components({
          resolvers: [ElementPlusResolver()],
        }),
      ],
      css: {
        preprocessorOptions: {
          scss: {
            additionalData: `@import "@/styles/variables.scss";`, // 引入全局 SCSS 文件
          },
        },
      },
      server: {
        host: '0.0.0.0',
        port: 5173,
        strictPort: true,
        open: true, // 自动打开浏览器
      },
      build: {
        outDir: 'dist',
        assetsDir: 'static',
        rollupOptions: {
          input: {
            main: path.resolve(__dirname, 'index.html'),
          },
        },
      },
    });
    

    文件扩展名为 .mjs 表示它是 ES 模块,为什么要用mjs:
    .mjs 文件扩展名是专门为 ECMAScript 模块 (ESM) 设计的。ESM 是一个较新的模块系统,它被设计来兼容浏览器和服务器端的 JavaScript 环境。使用 import 和 export 语句来管理依赖和导出,ESM 支持异步加载,这对于前端代码分割和延迟加载非常有用。

    与 CommonJS(也就是常见的.js) 相比,ESM 提供了更为静态的结构,它要求所有的 import 和 export 语句都位于文件的顶部,这使得 JavaScript 引擎可以在执行代码之前分析出整个文件的依赖结构。这种静态结构不仅使得代码的静态分析和打包更有效,还允许 JavaScript 引擎优化模块的加载时间。

    文件内容简单讲解:

    导入了一些必要的模块:

    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    import Components from 'unplugin-vue-components/vite';
    import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
    import path from 'path';
    

    defineConfig: 从 Vite 主包中导入,用于定义配置对象。
    vue: Vue.js 的官方 Vite 插件。
    Components: 一个 Vite 插件,用于自动按需引入组件。
    ElementPlusResolver: 用于 Components 插件来识别 Element Plus 组件。
    path: Node.js 的内置模块,用于处理文件路径。

    以上有两个模块没有安装:unplugin-vue-components、vitejs/plugin-vue,自行安装一下

    npm install @vitejs/plugin-vue
    
    npm install unplugin-vue-components
    

    unplugin-vue-components 是一个 Vue.js 的 Vite 插件,用于自动按需引入 Vue 组件。它的主要目的是为了减少应用程序的体积,通过仅引入实际使用的组件,而不是整个组件库。这有助于提高应用程序的性能,特别是在使用大型 UI 库(如 Element Plus 或 Vuetify)时。

    vitejs/plugin-vue 是 Vite 构建工具的一个官方插件,用于支持 Vue.js 的开发和构建。这个插件提供了 Vue.js 项目所需的各种功能,包括 .vue 单文件组件的支持、模板编译、TypeScript 集成等。

    配置项

    export default defineConfig({
      // 配置项
    });
    

    插件配置

    plugins: [
      vue(), // 使用 Vue.js 插件
      Components({
        resolvers: [ElementPlusResolver()], // 自动按需引入 Element Plus 组件
      }),
    ],
    

    vue(): 启用 Vue.js 支持。这会告诉 Vite 如何处理 .vue 文件,并且提供一些有用的构建优化。
    Components: 用于按需引入 Vue 组件。这里配置了 ElementPlusResolver,意味着当你的 Vue 组件引用了 Element Plus 的组件时,Vite 将自动引入所需的样式和脚本文件,而不是整个库。

    CSS 预处理器配置

    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@import "@/styles/variables.scss";`, // 引入全局 SCSS 文件
        },
      },
    },
    

    scss: 配置 SCSS 预处理器。这里的 additionalData 选项会将指定的 SCSS 文件内容添加到所有 SCSS 文件的头部,通常用来引入全局变量或混合宏。

    开发服务器配置

    server: {
      host: '0.0.0.0',
      port: 5173,
      strictPort: true,
      open: true, // 自动打开浏览器
    },
    

    host: 开发服务器绑定的 IP 地址。0.0.0.0 表示服务器可被任何设备访问。
    port: 开发服务器监听的端口。
    strictPort: 如果指定端口已被占用,则 Vite 不会尝试自动更换端口,而是直接报错。
    open: 当服务器启动时自动在默认浏览器中打开应用程序。

    构建配置

    build: {
      outDir: 'dist',
      assetsDir: 'static',
      rollupOptions: {
        input: {
          main: path.resolve(__dirname, 'index.html'),
        },
      },
    },
    

    outDir: 构建输出的目录。
    assetsDir: 静态资源的目录。
    rollupOptions: Rollup 构建器的配置选项。
    input: 构建过程中的入口文件。这里使用 __dirname 和 path.resolve 来确保正确的文件路径。

    SO!你知道上述那些文件其实主要是这边怎么定义就得怎么命名了吗?所以!如果有问题,你先根据这边的定义配置好好看看你的文件名字,如果想要自定义,你也可以对应修改即可。

    定义简单的布局,头部导航加侧边栏。

    侧边栏以动态路由导航生成,不要写死。头部先包含logo、搜索框、国际化、用户信息。

    先定义路由,在router文件下生成index.ts文件:
    (包含四个路由,其中第一个为首页,其他为表格、表单、图像。)

    // router/index.ts
    import { createRouter, createWebHistory } from 'vue-router';
    import Home from '../views/Home.vue';
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home,
        meta: {
          title: 'Home',
          icon: 'el-icon-s-home'
        }
      },
      {
        path: '/table',
        name: 'About',
        component: () => import('../views/tables/index.vue'),
        meta: {
          title: 'About',
          icon: 'el-icon-user-solid'
        }
      },
      {
        path: '/form',
        name: 'Form',
        component: () => import('../views/form/index.vue'),
        meta: {
          title: 'Form',
          icon: 'el-icon-user-solid'
        }
      },
      {
        path: '/chart',
        name: 'Chart',
        component: () => import('../views/chart/index.vue'),
        meta: {
          title: 'Chart',
          icon: 'el-icon-user-solid'
        }
      },
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes,
    });
    
    export default router;
    

    同时创建对应组件,在views目录下:

    • views
      ——chart
      ————index.vue
      ——tables
      ————index.vue
      ——form
      ————index.vue
      chart/index.vue
    <template>
        <div>
          <h1>图表</h1>
        </div>
      </template>
      
      <script lang="ts">
      import { defineComponent } from 'vue';
      
      export default defineComponent({
        name: 'ChartView',
      });
      </script>
    

    tables/index.vue

    <template>
        <div>
          <h1>表格</h1>
        </div>
      </template>
      
      <script lang="ts">
      import { defineComponent } from 'vue';
      
      export default defineComponent({
        name: 'TablesView',
      });
      </script>
    

    form/index.vue

    <template>
        <div>
          <h1>表单</h1>
        </div>
      </template>
      
      <script lang="ts">
      import { defineComponent } from 'vue';
      
      export default defineComponent({
        name: 'FormView',
      });
      </script>
    

    生成头部导航和侧边懒,在src/components下生成Header.vue、Label.vue、Sidebar.vue、SidebarItem.vue

    Header.vue

    <template>
      <div class="header">
        <el-row type="flex" justify="space-between" align="middle">
          <el-col :span="6">
            <el-link href="/" type="primary">Logo</el-link>
          </el-col>
          <el-col :span="12">
            <el-input placeholder="Search" prefix-icon="el-icon-search" v-model="searchInput"></el-input>
          </el-col>
          <el-col :span="6" class="right-section">
            <el-link @click="toggleLang">{{ lang }}</el-link>
            <el-dropdown trigger="click">
              <span class="el-dropdown-link">
                User Info<i class="el-icon-arrow-down el-icon--right"></i>
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item>Profile</el-dropdown-item>
                  <el-dropdown-item>Settings</el-dropdown-item>
                  <el-dropdown-item divided @click="logout">Logout</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </el-col>
        </el-row>
      </div>
    </template>
    
    <script setup lang="ts">
    import { ref } from 'vue';
    
    const searchInput = ref('');
    const lang = ref('EN');
    const toggleLang = () => {
      lang.value = lang.value === 'EN' ? 'CN' : 'EN';
    };
    
    const logout = () => {
      console.log('User logged out');
    };
    </script>
    
    <style scoped>
    .header {
      background-color: #f0f0f0;
      padding: 10px;
    }
    .right-section {
      display: flex;
      justify-content: flex-end;
    }
    .el-dropdown-link {
      cursor: pointer;
      color: #409eff;
    }
    </style>
    </script>
    
    <style scoped>
    .header {
      background-color: #f0f0f0;
      padding: 10px;
    }
    .right-section {
      display: flex;
      justify-content: flex-end;
    }
    .el-dropdown-link {
      cursor: pointer;
      color: #409eff;
    }
    </style>
    

    Label.vue

    <template>
      <div id="app">
        <Header />
        <el-container>
          <el-aside width="200px">
            <Sidebar />
          </el-aside>
          <el-main>
            <router-view />
          </el-main>
        </el-container>
      </div>
    </template>
    
    <script lang="ts">
    import Header from './Header.vue';
    import Sidebar from './Sidebar.vue';
    
    export default {
      components: {
        Header,
        Sidebar,
      },
    };
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    </style>
    

    Sidebar.vue

    <template>
      <el-menu
        :default-active="$route.path"
        class="el-menu-vertical-demo"
        mode="vertical"
        unique-opened
        router
        background-color="#545c64"
        text-color="#fff"
        active-text-color="#ffd04b"
      >
        <sidebar-item
          v-for="route in routes"
          :key="route.name"
          :route="route"
        />
      </el-menu>
    </template>
    
    <script setup lang="ts">
    import { useRoute, useRouter } from 'vue-router';
    import SidebarItem from './SidebarItem.vue';
    
    // 获取当前路由
    const route = useRoute();
    // 获取 Vue Router 实例
    const router = useRouter();
    
    // 获取所有路由信息
    const routes = router.getRoutes().filter(route => {
      return route.meta && route.meta.title;
    });
    </script>
    

    SidebarItem.vue

    <template>
      <li v-if="!route.children || !route.children.length">
        <el-menu-item :index="route.path" :key="route.name">
          <i :class="route.meta.icon"></i>
          <span slot="title">{{ route.meta.title }}</span>
        </el-menu-item>
      </li>
      <li v-else>
        <el-sub-menu :index="route.path" :key="route.name">
          <template #title>
            <i :class="route.meta.icon"></i>
            <span>{{ route.meta.title }}</span>
          </template>
          <sidebar-item
            v-for="child in route.children"
            :key="child.name"
            :route="child"
          />
        </el-sub-menu>
      </li>
    </template>
    
    <script setup lang="ts">
    defineProps({
      route: {
        type: Object,
        required: true
      }
    });
    </script>
    

    开始构建最后的几个文件吧!

    App.vue

    // App.vue
    <template>
      <Layout />
    </template>
    
    <script setup lang="ts">
    import Layout from './components/Layout.vue';
    </script>
    
    

    *main.ts

    // main.ts
    import { createApp } from 'vue';
    import App from './App.vue';
    import router from './router';
    import ElementPlus from 'element-plus';
    import 'element-plus/dist/index.css'; // 引入 Element Plus 的样式
    
    const app = createApp(App);
    
    app.use(ElementPlus);
    app.use(router);
    
    app.mount('#app');
    
    

    大功告成、最后一步:

    再安装一下依赖:

    npm install
    

    如果报错就试试yarn

    yarn install
    

    没有报错就尝试启动:
    npm run dev

    如果报错就一步步解决吧!哈哈哈。

    实在解决不了就拿来主义:我把第一阶段在github上面打了一个tag,你直接下下来即可。完整项目地址:v3viteTsElement,点击查看。

    而命令行直接干:

    git clone --single-branch --depth 1 --branch tag1.0 https://github.com/RDzdf/v3viteTsElement.git
    

    干下来后:install一下就ok,npm版本比低于9.5就成。node也不要低于20.0.

    总结:

    写得有些潦草,估计会有很多问题,写多了就容易暴躁!开始乱搞,就这样吧!有问题可留言,我会耐心给你们解决的。

    相关文章

      网友评论

          本文标题:Vue3+Vite+TS+VueRouter+Element-p

          本文链接:https://www.haomeiwen.com/subject/hqlwkjtx.html