跳转至

Admin 项目实战(二):Vue 全家桶

这是 Admin 练习项目的第二篇,练习如何为项目配置 Typescript + Vue。

准备环境

执行下列命令准备开发环境:

1
2
3
4
    pnpm i vue
    pnpm i @vitejs/plugin-vue
    pnpm i vue-router
    pnpm i pinia

其中,@vitejs/plugin-vue 可以使得 Vite 支持 vue。

为项目添加 Typescript 支持,新增 tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "module": "ESNext",
    "target": "es2016",
    "lib": ["DOM", "ESNext"],
    "strict": true,
    "esModuleInterop": true,
    "incremental": false,
    "skipLibCheck": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "noUnusedLocals": true,
    "strictNullChecks": true,
    "forceConsistentCasingInFileNames": true,
    "types": ["vite/client"],
    "paths": {
      "~/*": ["src/*"]
    }
  },
  "exclude": ["dist", "node_modules", "cypress"]
}

注意:上面的配置中 path 的内容可以支持在文件中以绝对路径 ~/src/filename 的方式访问文件。

实验目标

本次练习完成下列目标:

  • 能够正确加载 Vue 文件
  • 支持简单的路由:login, index 到不同的文件
  • 使用 Pinia 实现 user 状态存储

加载 Vue 组件

增加 shims-vue.d.ts 解析 Vue template:

1
2
3
4
5
    declare module "*.vue" {
      import { basicComponent } from "vue";
      const component: defineComponent<{}, {}, any>;
      export default component;
    }

在 index.html 中加载 main.ts:

1
2
3
4
5
    <body>
      <h1>Hello Vite !!!</h1>
      <div id="app"></div>
      <script src="./src/main.ts" type="module"></script>
    </body>

在 main.ts 中使用 Vue 进行渲染:

1
2
3
4
5
6
7
8
9
    import { createApp, h } from "vue";
    import App from "./App.vue";
    const App = {
      render() {
        // <div>Hello Vue</div>
        return h("div", null, [[String("Hello Vue")]]);
      },
    };
    createApp(App).mount("#app");

启动项目可以看到页面正常显示 “Hello Vue”。

支持简单路由

修改 main.ts 增加路由配置:

    import { createRouter, createWebHistory } from "vue-router";
    const router = createRouter({
      history: createWebHistory(),
      routes: [
        {
          path: "/",
          component: () => import("~/pages/index.vue"),
        },
        {
          path: "/login",
          component: () => import("~/pages/login.vue"),
        },
      ],
    });
    createApp(App).use(router).mount("#app");

上面的代码,配置了默认访问index.vue,/login 访问 login.vue。上述两个页面通过标题文字进行区分。

启动项目,可以看到标题显示 “Index Page”,打开 login url,标题显示 “Login Page”。

使用 Pinia 状态存储

新建 src/stores/user.ts

    import { defineStore, acceptHMRUpdate } from "pinia";
    import { ref } from "vue";

    export const useUserStore = defineStore("user", () => {
      const count = ref(0);
      function add(num: number = 0) {
        count.value = count.value + num;
      }
      return { add, count };
    });

    if (import.meta.hot) {
      import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot));
    }

上面的代码定义了名为 “user” 的状态存储,其中包含了 count 计数和 add 方法。

注意:最后两行代码实现了调试过程中的热更新支持。

修改 main.ts 加载 Pinia。

1
2
3
    import { createPinia } from "pinia";
    const pinia = createPinia();
    createApp(App).use(router).use(pinia).mount("#app");

修改 App.vue 使用存储中的计数。

1
2
3
4
5
6
7
8
    <template>
      <button @click="user.add(1)">{{ user.count }}</button>
      <router-view></router-view>
    </template>
    <script setup lang="ts">
    import { useUserStore } from "~/stores/user";
    const user = useUserStore();
    </script>

启动项目后,可以正确显示状态存储中的计数值,点击按钮会给计数加1。

支持,Vue 全家桶配置完毕。

上一课

Admin 项目实战(三):原子样式 Unocss

凡本网注明"来源:XXX "的文/图/视频等稿件,本网转载出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如涉及作品内容、版权和其它问题,请与本网联系,我们将在第一时间删除内容!
作者: 勃纳什
来源: https://zhuanlan.zhihu.com/p/644429775