写点什么

Vue3 Typescript + Axios 全栈开发教程:手把手教你写「待办清单」APP

作者:蒋川
  • 2022 年 5 月 30 日
  • 本文字数:9776 字

    阅读完需:约 32 分钟

Vue3 Typescript + Axios 全栈开发教程:手把手教你写「待办清单」APP

本文完整版:《Vue3 Typescript + Axios 全栈开发教程:手把手教你写「待办清单」APP


Vue3 的源码使用 TypeScript 编写,而 TypeScriptJS 的一个超集,主要提供对 ES6 的支持,以及更棒的代码可读性和高维护性。Axios 是基于 Promise 的 HTTP 请求库,它用在 node.js 和浏览器里,在本教程中我们使用 Vue3 Typescript 配合 Axios 通过 Get / Post / Put / Delete 请求与后端通讯。


本文通过手把手教你写一个前端「待办清单」app,带领大家详细理解 Vue3 Typescript 与 Axios 如何配置及如何与后端通讯,助你成为 Vue3 Typescript 与 Axios 全栈开发工程师。


本教程每段代码我都亲手测过,保证百分百没有错误,请打开你的 terminal 跟随本教程一起操作,从这里开始,成为一名全栈工程师。


如果你正在搭建后台管理工具,又不想处理前端问题,推荐使用卡拉云 ,卡拉云是新一代低代码开发工具,可一键接入常见数据库及 API ,无需懂前端,仅需拖拽即可快速搭建属于你自己的后台管理工具,一周工作量缩减至一天,详见本文文末。


##「待办清单」app 完成概览



我们搭建的「待办清单」app 包含以下几个功能/页面


1.首页:展示「待办清单」的列表,可点击查看清单详细及状态。


2.首页搜索:首页有搜索框,可搜索清单。


3.新增清单:可以新建一个清单。


4.编辑清单:可对清单内容进行增删改查



  • 「新增清单页」,提交新任务到数据库



「任务状态更新页」,修改待办任务的详情和状态并提交到数据库中


如果你跟随本教程一步步来,最终你也可以把 Vue3 Typescript + Axios +Vue Router 跑起来并发布自己对「待办清单」app


##前端部分 - Vue3 Typescript + Axios +Vue Router + 自己封装组件



我先来讲解一下前端各部分的功能,如果你没看懂也没关系,跟随教程一步一步走,全部完成后再回来看这个部分,你会豁然开朗。


  • App(应用本身):最外层,用户可看到的前端,用户指令从这里进入。

  • Vue Router(路由):路由根据用户指令选择指向三个组件(Components)中的一个。

  • Components(组件):组件是我们写的功能页,本教程带大家一起写三个组件。

  • TodoDataService:用户在组件中 CRUD 数据,数据根据 TodoDataService 中的规则进行组装。

  • axios(API 调取):axios 会根据 TodoDataService 中的规则与后端 API 通讯交换数据。

前端 Vue3 Typescript 项目结构


简单讲一下各文件的作用,本教程后文将手把手教你写每一个配置文件及他们所有的源码


  • package.json 包含 5 个主要模块:VuetypescriptVue-routeraxiosbootstrap

  • 有 3 个组件(功能页面):TodoListTodo、 AddTodo

  • router.js 为每个组件(功能页面)定义路由。

  • http-common.js 是 axios 初始化信息,标记了与后端 API 通讯的地址

  • TodoDataService 具有向 API 发送 HTTP 请求的方法。

  • vue.config.js 设置 Vue 访问端口


下面,我们正式进入前后端搭建实战环节,一定要跟随本教程一起操作,自己亲手实践是学会的基础,打开你的 terminal ,我们一起来。


##Vue3 Typescript 安装教程及配置


本教程适用于 Win / Linux / MacOS

安装 Vue3 ,使用 npm 安装 Vue

sudo npm install -g @vue/cli
复制代码


接着我们创建一个 Vue 的项目,运行命令:

vue create vue3-ypescript-axios-todolist-kalacloud
复制代码



运行起来,你会看到几个选项,选择 Manually select features,我们来自定义安装,这样可以选择 Vue3 + Typescript 安装。



注意选择 TypeScript,默认是 Vue3 安装



安装完成后,会生成一个「vue3-ypescript-axios-todolist-kalacloud」目录,我们所有的前端代码都会存在这里。


cd vue-kalacloud-comroot@kalacloud.com:~/vue3-ypescript-axios-todolist-kalacloud$
复制代码


cd 到这个目录下,接下来我们要开始配置 Vue 的开发环境。


扩展阅读《顶级开源 vue 表单设计器测评推荐


##在 Vue3 Typescript 中安装使用 Bootstrap


Bootstrap 最初是由 Twitter 两名工程师开发的响应式开源框架,简洁优雅,自适应 PC 和移动端。现在已经是全球使用最受欢迎的独立 CSS 框架之一。


我们先来把它安装到 Vue 中,在「vue3-ypescript-axios-todolist-kalacloud」根目录执行安装命令:


npm install bootstrap jquery popper.js
复制代码


然后打开 /src/main.ts 文件,导入 Bootstrap:


import { createApp } from 'vue'import App from './App.vue'import 'bootstrap'import 'bootstrap/dist/css/bootstrap.min.css'
复制代码


**特别提示:**为了避免奇怪的错误,请完整复制本教程中的全部代码,使用完全替换的方式将教程中的代码粘贴到对应的文件中。


处理前端问题太麻烦?

试试卡拉云,仅需拖拽组件连接 API 和数据库直接生成后台管理系统,将两个月的工期降低至两天


##在 Vue3 Typescript 中安装使用 Vue Router


Vue Router 是 Vue 的官方路由,与 Vue 深度整合,让构建响应式单页面变得非常简单快捷。


在项目根目录执行安装 Vue Router 的命令:


然后在 /src 文件夹中新建一个文件 router.ts 并定义一下 Vue 的路由


(在 Terminal 里,你可以使用 nano router.ts 的方式新建 js 文件并打开编辑器粘贴代码)


import { createWebHistory, createRouter } from "vue-router";import { RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [ { path: "/", alias: "/todo", name: "todo", component: () => import("./components/TodoList.vue") }, { path: "/todo/:id", name: "todo-details", component: () => import("./components/Todo.vue") }, { path: "/add", name: "add", component: () => import("./components/AddTodo.vue") }];
const router = createRouter({ history: createWebHistory(), routes,});
export default router;
复制代码


router.ts 中我们为每个页面创建一个路由:


  • path:路由指向的 URL 路径

  • name:路由指向这个页面时使用的名字

  • component:路由调用此页面时,要加在的组件(这个组件我们马上一起动手写)


然后我们打开 /src/main.ts,在这里加上 router 路由信息 (最后一行):


import { createApp } from 'vue'import App from './App.vue'import 'bootstrap'import 'bootstrap/dist/css/bootstrap.min.css'import router from './router'
createApp(App).use(router).mount('#app')
复制代码


最后一步,在/src目录下创建 shims-vue.d.ts


import VueRouter, { Route } from 'vue-router'
/* eslint-disable */declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<{}, {}, any> export default component}
declare module 'vue/types/vue' { interface Vue { $router: VueRouter }}
复制代码


现在,Vue 声明了 $router 这样就不会报错了。


扩展阅读《5款开源vue 移动端 ui 组件库测评推荐


##在 Vue3 Typescript 中添加导航栏和 Router View


接下来,我们打开 /src/App.vue 删掉里面全部代码,然后加入咱们自己项目的导航栏和 Router View :


<template>  <div id="app">    <nav class="navbar navbar-expand navbar-dark bg-dark">      <router-link to="/" class="navbar-brand">卡拉云_kalacloud.com</router-link>      <div class="navbar-nav mr-auto">        <li class="nav-item">          <router-link to="/todo" class="nav-link">任务清单</router-link>        </li>        <li class="nav-item">          <router-link to="/add" class="nav-link">新增任务</router-link>        </li>      </div>    </nav>
<div class="container mt-3"> <router-view /> </div> </div></template>
<script lang="ts">import { defineComponent } from "vue";export default defineComponent({ name: "App",});</script>
复制代码


**特别提示:**为了避免奇怪的错误,请完整复制本教程中的全部代码,使用完全替换的方式将教程中的代码粘贴到对应的文件中。


扩展阅读《12款开源 vue ui 组件库框架测评推荐


##在 Vue3 Typescript 安装 Axios 并初始化 HTTP 客户端


Axios 是一个基于 Promise 的 HTTP 请求库,它用在 node.js 和浏览器里,在本教程中我们使用 Axios 通过 Get / Post / Put / Delete 请求与后端进行交互。


我们先来安装 Axios:


然后,在 /src 文件夹下,创建一个 http-common.ts 文件并复制以下代码进去:


import axios from "axios";export default axios.create({  baseURL: "http://localhost:8080/api",  headers: {    "Content-type": "application/json"  }});
复制代码


这里的 baseURL 是后端的 REST API url ,记得改成你的服务器配置。


如果你是萌新,没看懂,也没有关系,这里不用改。我们将在本教程的「后端」部分,教你配置后端服务器。


##让 Vue3 Typescript 可以通过 Axios 发送 HTTP 请求


我们要给 Axios 建立一套与后端服务器沟通的规则,告诉 Axios 使用这套规则去后端拿那数据。


我们要在 /src/services/ 创建一个TodoDataService.ts


如果没有 services 文件夹,先建一个,然后在文件夹里新建TodoDataService.ts 并复制以下代码。


(文件位置:/src/services/TodoDataService.ts


import http from "@/http-common";
class TodoDataService { getAll(): Promise<any> { return http.get("/todos"); }
get(id: any): Promise<any> { return http.get(`/todos/${id}`); }
create(data: any): Promise<any> { return http.post("/todos", data); }
update(id: any, data: any): Promise<any> { return http.put(`/todos/${id}`, data); }
delete(id: any): Promise<any> { return http.delete(`/todos/${id}`); }
deleteAll(): Promise<any>{ return http.delete(`/todos`); }
findByTitle(title: string): Promise<any> { return http.get(`/todos?title=${title}`); }}
export default new TodoDataService();
复制代码


最后一步,创建「待办事宜」界面和相应数据接口


新建 types/todo.ts 并定义 Todo 接口


export default interface Todo {  id: null;  title: string;  description: string;  published: boolean;}
复制代码


新建 types/ResponseData.ts 并定义 ResponseData 接口


export default interface ResponseData {  data: any;}
复制代码


扩展阅读《如何在 vue 中加入图表 - vue echarts 使用教程


##创建 Vue3 Typescript 组件


Vue3 Typescript 与旧版本不同,需要给 ts 分配 lang 属性标签。


Vue 一般是这么来定义组件:


而现在,我们这么定义,这种形式,大家应该在前文已经看到了。


import { defineComponent } from 'vue'export default defineComponent({ ... })
复制代码


接着我们来写 Vue Router 中定义的三个组件,也就是我们 app 页面上会显示的三个响应页。

「新增 ToDo 组件」 - AddTodo.vue


上图为「AddTodo.vue」最终样式


这个组件用于向数据库中新增 ToDo 数据,它包含 2 个字段:titledescription


用它来调用咱们前一节写的 TodoDataService.create()


在 components 文件夹下创建 AddTodo.vue ,填入以下代码:


文件位置:/src/components/AddTodo.vue


<template>  <div class="submit-form">    <div v-if="!submitted">      <div class="form-group">        <label for="title">任务</label>        <input          type="text"          class="form-control"          id="title"          required          v-model="todo.title"          name="title"        />      </div>
<div class="form-group"> <label for="description">详情</label> <input class="form-control" id="todo" required v-model="todo.description" name="description" /> </div>
<button @click="saveTodo" class="btn btn-success">提交</button> </div>
<div v-else> <h4>提交成功</h4> <button class="btn btn-success" @click="newtodo">添加</button> </div> </div></template>
<script lang="ts">import { defineComponent } from "vue";import TodoDataService from "@/services/TodoDataService";import Todo from "@/types/Todo";import ResponseData from "@/types/ResponseData";export default defineComponent({ name: "add-todo", data() { return { todo: { id: null, title: "", description: "", published: false, } as Todo, submitted: false, }; }, methods: { saveTodo() { let data = { title: this.todo.title, description: this.todo.description, }; TodoDataService.create(data) .then((response: ResponseData) => { this.todo.id = response.data.id; console.log(response.data); this.submitted = true; }) .catch((e: Error) => { console.log(e); }); }, newTodo() { this.submitted = false; this.todo = {} as Todo; }, },});</script><style>.submit-form { max-width: 300px; margin: auto;}</style>
复制代码


扩展阅读《5款开源 vue table 表格组件推荐

「ToDO 列表组件」 - TodoList.vue


上图为「TodoList.vue」最终效果


该组件调用 3 个 TodoDataService 方法:


  • getAll()

  • deleteAll()

  • findByTitle()


components 文件夹下创建 TodoList.vue,填入以下代码:


文件位置:/src/components/TodoList.vue


<template>  <div class="list row">    <div class="col-md-8">      <div class="input-group mb-3">        <input          type="text"          class="form-control"          placeholder="搜索待办清单"          v-model="title"        />        <div class="input-group-append">          <button            class="btn btn-outline-secondary"            type="button"            @click="searchTitle"          >            Search          </button>        </div>      </div>    </div>    <div class="col-md-6">      <h4>待办清单</h4>      <ul class="list-group">        <li          class="list-group-item"          :class="{ active: index == currentIndex }"          v-for="(todo, index) in todos"          :key="index"          @click="setActiveTodo(todo, index)"        >          {{ todo.title }}        </li>      </ul>      <button class="m-3 btn btn-sm btn-danger" @click="removeAllTodos">         删除所有清单      </button>    </div>    <div class="col-md-6">      <div v-if="currentTodo.id">        <h4>待办详情</h4>        <div>          <label><strong>任务:</strong></label> {{ currentTodo.title }}        </div>        <div>          <label><strong>详情:</strong></label>          {{ currentTodo.description }}        </div>        <div>          <label><strong>状态:</strong></label>          {{ currentTodo.published ? "Published" : "Pending" }}        </div>        <router-link          :to="'/todos/' + currentTodo.id"          class="badge badge-warning"          >编辑</router-link        >      </div>      <div v-else>        <br />        <p>点击右侧列表查看详情</p>      </div>    </div>  </div></template><script lang="ts">import { defineComponent } from "vue";import TodoDataService from "@/services/TodoDataService";import Todo from "@/types/Todo";import ResponseData from "@/types/ResponseData";export default defineComponent({  name: "todos-list",  data() {    return {      todos: [] as Todo[],      currentTodo: {} as Todo,      currentIndex: -1,      title: "",    };  },  methods: {    retrieveTodos() {      TodoDataService.getAll()        .then((response: ResponseData) => {          this.todos = response.data;          console.log(response.data);        })        .catch((e: Error) => {          console.log(e);        });    },    refreshList() {      this.retrieveTodos();      this.currentTodo = {} as Todo;      this.currentIndex = -1;    },    setActiveTodo(todo: Todo, index = -1) {      this.currentTodo = todo;      this.currentIndex = index;    },    removeAllTodos() {      TodoDataService.deleteAll()        .then((response: ResponseData) => {          console.log(response.data);          this.refreshList();        })        .catch((e: Error) => {          console.log(e);        });    },    searchTitle() {      TodoDataService.findByTitle(this.title)        .then((response: ResponseData) => {          this.todos = response.data;          this.setActiveTodo({} as Todo);          console.log(response.data);        })        .catch((e: Error) => {          console.log(e);        });    },  },  mounted() {    this.retrieveTodos();  },});</script><style>.list {  text-align: left;  max-width: 750px;  margin: auto;}</style>
复制代码


扩展阅读《7款开源 vue admin 后台管理框架推荐

「 ToDo 内容更新组件」 - Todo.vue


上图为「Todo.vue」最终完成效果


components 文件夹下创建 Todo.vue,填入以下代码:


文件位置:/src/components/Todo.vue


<template>  <div v-if="currentTodo.id" class="edit-form">    <h4>待办事宜</h4>    <form>      <div class="form-group">        <label for="title">任务:</label>        <input          type="text"          class="form-control"          id="title"          v-model="currentTodo.title"        />      </div>      <div class="form-group">        <label for="description">详情:</label>        <input          type="text"          class="form-control"          id="description"          v-model="currentTodo.description"        />      </div>      <div class="form-group">        <label><strong>状态:</strong></label>        {{ currentTodo.published ? "Published" : "Pending" }}      </div>    </form>    <button      class="badge badge-primary mr-2"      v-if="currentTodo.published"      @click="updatePublished(false)"    >      未完成    </button>    <button      v-else      class="badge badge-primary mr-2"      @click="updatePublished(true)"    >      完成    </button>    <button class="badge badge-danger mr-2" @click="deleteTodo">      删除    </button>    <button type="submit" class="badge badge-success" @click="updateTodo">      更新    </button>    <p>{{ message }}</p>  </div>  <div v-else>    <br />    <p>Please click on a Todo...</p>  </div></template><script lang="ts">import { defineComponent } from "vue";import TodoDataService from "@/services/TodoDataService";import Todo from "@/types/Todo";import ResponseData from "@/types/ResponseData";export default defineComponent({  name: "todo",  data() {    return {      currentTodo: {} as Todo,      message: "",    };  },  methods: {    getTodo(id: any) {      TodoDataService.get(id)        .then((response: ResponseData) => {          this.currentTodo = response.data;          console.log(response.data);        })        .catch((e: Error) => {          console.log(e);        });    },    updatePublished(status: boolean) {      let data = {        id: this.currentTodo.id,        title: this.currentTodo.title,        description: this.currentTodo.description,        published: status,      };      TodoDataService.update(this.currentTodo.id, data)        .then((response: ResponseData) => {          console.log(response.data);          this.currentTodo.published = status;          this.message = "状态修改成功";        })        .catch((e: Error) => {          console.log(e);        });    },    updateTodo() {      TodoDataService.update(this.currentTodo.id, this.currentTodo)        .then((response: ResponseData) => {          console.log(response.data);          this.message = "信息更新成功";        })        .catch((e: Error) => {          console.log(e);        });    },    deleteTodo() {      TodoDataService.delete(this.currentTodo.id)        .then((response: ResponseData) => {          console.log(response.data);          this.$router.push({ name: "todos" });        })        .catch((e: Error) => {          console.log(e);        });    },  },  mounted() {    this.message = "";    this.getTodo(this.$route.params.id);  },});</script><style>.edit-form {  max-width: 300px;  margin: auto;}</style>
复制代码


##设置 Vue3 Typescript 项目访问端口


在 Vue3 项目根目录创建 vue.config.js 文件,代码如下:


文件位置:根目录/vue.config.js


module.exports = {  devServer: {    port: 8081  }}
复制代码


我们已经设置了我们的应用程序在端口上运行 8081


扩展阅读《Element Plus for Vue 3 入门教程


##运行 Vue3 Typescript 并在浏览器里查看效果



至此,前端部分就全部完成了,我们来运行一下刚刚搭建的 Vue 前端代码,在浏览器里欣赏一下你自己的开发成果。


在项目根目录执行:npm run serve 然后打开浏览器,输入http://localhost:8081/,在浏览器中我们可以看到前端页面已经显示出来了。


如果你也看到和下图类似的界面,这说明你的 Vue3 Typescript 已经搭建完成,恭喜。



因为我们的后端还没有搭建,前端界面还没有连接数据,所以只有轮廓没有数据。


我将在下一篇文章中讲解如何使用 node.js + Express + Sequelize + MySQL 搭建后端框架,使前后端联通,最终完成「待办事宜」ap


##Vue3 Typescript + Axios 教程总结


本文详细讲解新版 Vue3 Typescript 与旧版 Vue 有什么区别及代码上的不同,以及 Axios 怎么与后端通讯。其实如果你根本不想处理复杂的前端问题,完全可以使用卡拉云来搭建前端工具,卡拉云内置多种常用组件,无需懂任何前端,仅需拖拽即可快速生成。不需要配置 Axios ,一键连接后端数据源。


卡拉云可帮你快速搭建企业内部工具,下图为使用卡拉云搭建的内部广告投放监测系统,无需懂前端,仅需拖拽组件,10 分钟搞定。你也可以快速搭建一套属于你的后台管理工具,了解更多



卡拉云是新一代低代码开发平台,与前端框架 Vue、React 等相比,卡拉云的优势在于不用首先搭建开发环境,直接注册即可开始使用。开发者完全不用处理任何前端问题,只需简单拖拽,即可快速生成所需组件,可一键接入常见数据库及 API,根据引导简单几步打通前后端,数周的开发时间,缩短至 1 小时。立即免费试用卡拉云


扩展阅读:


发布于: 2022 年 05 月 30 日阅读数: 26
用户头像

蒋川

关注

我的微信:HiJiangChuan 2020.09.08 加入

卡拉云 CMO 卡拉云是一套帮助后端程序员搭建企业内部工具的系统,欢迎试用 www.kalacloud.com

评论

发布
暂无评论
Vue3 Typescript + Axios 全栈开发教程:手把手教你写「待办清单」APP_typescript_蒋川_InfoQ写作社区