vue基础回顾+进阶

课程内容

  • VUE 基础回顾

  • 路由 Vue-Router

  • 状态管理 vuex

  • TypeScript

1. VUE 基础回顾

1.1 基于脚手架创建前端工程

1.1.1 环境要求

要想基于脚手架创建前端工程,需要具备如下环境要求:

  • node.js 前端项目的运行环境

  • npm JavaScript的包管理工具

  • Vue CLI 基于Vue进行快速开发的完整系统,实现交互式的项目脚手架

安装完node.js后,可以通过命令行来查看版本号,如下:

安装 Vue CLI,命令如下:

1.1.2 操作过程

使用 Vue CLI 创建前端工程的方式:

  • 方式一:vue create 项目名称

  • 方式二:vue ui

重点介绍使用 vue ui 命令创建前端工程的过程:

第一步:在命令行输入命令 vue ui,在浏览器ui界面中选择前端工程存放的位置

第二步:点击“在此创建新项目”按钮,跳转到创建新项目设置页面

第三步:填写项目名称、选择包管理器为npm,点击“下一步”按钮

第四步:选择 Default(Vue 2),点击"创建项目"按钮,完成项目的创建

1.1.3 工程结构

工程目录结构:

重点文件或目录介绍:

  • node_modules:当前项目依赖的js包

  • assets:静态资源存放目录

  • components:公共组件存放目录

  • App.vue:项目的主组件,页面的入口文件

  • main.js:整个项目的入口文件

  • package.json:项目的配置信息、依赖包管理

  • vue.config.js:vue-cli配置文件

1.1.4 启动前端服务

使用VS Code打开创建的前端工程,启动前端工程:

访问前端工程:

注:要停止前端服务,可以在命令行终端使用 ctrl + C

前端项目启动后,服务端口默认为8080,很容易和后端tomcat端口号冲突。如何修改前端服务的端口号?

可以在vue.config.js中配置前端服务端口号:

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 7070  //指定前端服务端口号
  }
})

1.2 vue基本使用方式

本章节从如下几个方面进行vue回顾:

  • vue 组件

  • 文本插值

  • 属性绑定

  • 事件绑定

  • 双向绑定

  • 条件渲染

  • axios

1.2.1 vue 组件

Vue 的组件文件以 .vue 结尾,每个组件由三部分组成:

  • 结构 <template>

  • 样式 <style>

  • 逻辑 <script>

1.2.2 文本插值

作用:用来绑定 data 方法返回的对象属性

用法:{{插值表达式}}

示例:

1.2.3 属性绑定

作用:为标签的属性绑定 data 方法中返回的属性

用法:v-bind:xxx,简写为 :xxx

示例:

1.2.4 事件绑定

作用:为元素绑定对应的事件

用法:v-on:xxx,简写为 @xxx

示例:

1.2.5 双向绑定

作用:表单输入项和 data 方法中的属性进行绑定,任意一方改变都会同步给另一方

用法:v-model

示例:

1.2.6 条件渲染

作用:根据表达式的值来动态渲染页面元素

用法:v-if、v-else、v-else-if

示例:

1.2.7 axios

Axios 是一个基于 promise 的 网络请求库,作用于浏览器和 node.js 中。使用Axios可以在前端项目中发送各种方式的HTTP请求。

安装命令:npm install axios

导入:import axios from 'axios'

在script标签内导入

axios 的 API 列表:

参数说明:

  • url:请求路径

  • data:请求体数据,最常见的是JSON格式数据

  • config:配置对象,可以设置查询参数、请求头信息

注:在使用axios时,经常会遇到跨域问题。

为了解决跨域问题,可以在 vue.config.js 文件中配置代理:(配置完需要重启前端服务

(配置代理,前端发送的请求先请求到代理上,代理转发请求到后端服务)

target表示将以/api的请求转发到指定url, pathRewrite进行路径重写,将以/api路径开头的字符串替换成空字符

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 7070,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
})

axios的post请求

前端按钮:

<input type="button" value="发送post请求" @click="handleSendPost">

axios的post请求示例:

    //通过axios发送post请求
    handleSendPost() {
      axios.post('/api/admin/employee/login', {
        username: 'admin',
        password: '123456'
      }).then(res => {
        console.log(res.data)
      }).catch(error => {
        console.log(error.response)
      })
    }

测试(获取到了后端的响应结果)

会发现请求的是http://localhost:7070,因为配置了代理,请求会先到代理,由代理转发到后端

axios的get请求:

 前端按钮:

<input type="button" value="发送get请求" @click="handleSendGet">

axios的get请求示例:

    //通过axios发送get请求
    handleSendGet() {
      axios.get('/api/admin/shop/status',{
        headers:{
          token:'eyJhbGciOiJIUzI1NiJ9.eyJlbXBJZCI6MSwiZXhwIjo4OTYyNjA5NTk4fQ.PiUUfvLfOEcm-h31zjVg72EF6gSNAZ6r5mJJW44mQ64'
        }
      }
      ).then(res => {
        console.log(res.data)
      })
    }

测试:

axios提供的统一使用方式

axios中文官网:https://www.axios-http.cn/docs/req_config

请求配置:(只用知道主要的的,其他的了解)

{
  // `url` 是用于请求的服务器 URL
  url: '/user',

  // `method` 是创建请求时使用的方法
  method: 'get', // 默认值

  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: 'https://some-domain.com/api/',

  // `transformRequest` 允许在向服务器发送前,修改请求数据
  // 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
  // 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
  // 你可以修改请求头。
  transformRequest: [function (data, headers) {
    // 对发送的 data 进行任意转换处理

    return data;
  }],

  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    // 对接收的 data 进行任意转换处理

    return data;
  }],

  // 自定义请求头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // `params` 是与请求一起发送的 URL 参数
  // 必须是一个简单对象或 URLSearchParams 对象
  params: {
    ID: 12345
  },

  // `paramsSerializer` 是一个可选配置,允许您自定义序列化 `params`。
  paramsSerializer: {

    //自定义编码器函数,以迭代方式发送键/值对。
    encode?: (param: string): string => { /* 在这里进行自定义操作并返回转换后的字符串 */ }, 
    
    // 整个参数的自定义序列化器函数。允许用户模仿 1.x 之前的行为。
    serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ), 
    
    //用于格式化参数中数组索引的配置。
    indexes: false // 三个可用选项:
    // (1) indexes: null (导致没有括号), 
    // (2) (default) indexes: false (导致空括号),
    // (3) indexes: true (引导空字符串).    
  },

  // `data` 是作为请求体被发送的数据
  // 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
  // 在没有设置 `transformRequest` 时,则必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属: FormData, File, Blob
  // - Node 专属: Stream, Buffer
  data: {
    firstName: 'Fred'
  },
  
  // 发送请求体数据的可选语法
  // 请求方式 post
  // 只有 value 会被发送,key 则不会
  data: 'Country=Brasil&City=Belo Horizonte',

  // `timeout` 指定请求超时的毫秒数。
  // 如果请求时间超过 `timeout` 的值,则请求会被中断
  timeout: 1000, // 默认值是 `0` (永不超时)

  // `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: false, // default

  // `adapter` 允许自定义处理请求,这使测试更加容易。
  // 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
  adapter: function (config) {
    /* ... */
  },

  // `auth` HTTP Basic Auth
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // `responseType` 表示浏览器将要响应的数据类型
  // 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
  // 浏览器专属:'blob'
  responseType: 'json', // 默认值

  // `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
  // 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
  // Note: Ignored for `responseType` of 'stream' or client-side requests
  responseEncoding: 'utf8', // 默认值

  // `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
  xsrfCookieName: 'XSRF-TOKEN', // 默认值

  // `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
  xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值

  // `onUploadProgress` 允许为上传处理进度事件
  // 浏览器专属
  onUploadProgress: function (progressEvent) {
    // 处理原生进度事件
  },

  // `onDownloadProgress` 允许为下载处理进度事件
  // 浏览器专属
  onDownloadProgress: function (progressEvent) {
    // 处理原生进度事件
  },

  // `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
  maxContentLength: 2000,

  // `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
  maxBodyLength: 2000,

  // `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。
  // 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
  // 则promise 将会 resolved,否则是 rejected。
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 默认值
  },

  // `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
  // 如果设置为0,则不会进行重定向
  maxRedirects: 5, // 默认值

  // `socketPath` 定义了在node.js中使用的UNIX套接字。
  // e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
  // 只能指定 `socketPath` 或 `proxy` 。
  // 若都指定,这使用 `socketPath` 。
  socketPath: null, // default

  // `httpAgent` 和 `httpsAgent` 分别定义了在 node.js 中执行 http 和 https 请求时使用的自定义代理。
  // 这允许添加诸如 `keepAlive` 之类的选项,这些选项在 Node.js v19.0.0 之前默认未启用。
  // 在 Node.js v19.0.0 之后,不再需要自定义代理来启用 `keepAlive`,
  // 因为 `http.globalAgent` 已经默认启用了 `keepAlive`。
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // `proxy` 定义了代理服务器的主机名,端口和协议。
  // 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
  // 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
  // `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
  // 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
  // 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
  proxy: {
    protocol: 'https',
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // see https://axios-http.com/zh/docs/cancellation
  cancelToken: new CancelToken(function (cancel) {
  }),

  // `decompress` indicates whether or not the response body should be decompressed 
  // automatically. If set to `true` will also remove the 'content-encoding' header 
  // from the responses objects of all decompressed responses
  // - Node only (XHR cannot turn off decompression)
  decompress: true // 默认值

}

axios提供的统一使用方式示例:

 前端按钮:

<input type="button" value="统一请求方式" @click="handleSend">

axios的get请求示例:

    //使用axios提供的统一调用方式发送请求
    handleSend() {
      axios({
        url: '/api/admin/employee/login',
        method: 'post',
        data: { //data表示通过请求体传参
          username: 'admin',
          password: '123456'
        }
      }).then(res => {
        console.log(res.data.data.token)
        axios({
          url: '/api/admin/shop/status',
          method: 'get',
          headers: {
            token: res.data.data.token
          }
        })
      })
    }

测试:


2. 路由 Vue-Router

2.1 Vue-Router 介绍

vue 属于单页面应用,所谓路由,就是根据浏览器路径不同,用不同的视图组件替换这个页面内容。

如上图所示:不同的访问路径,对应不同的页面展示。

新建项目vue-router-demo

选择手动配置项目:

在vue应用中使用路由功能,需要安装Vue-Router:

按照以下选择:

注:创建完带有路由功能的前端项目后,在工程中会生成一个路由文件,如下所示:

关于路由的配置,主要就是在这个路由文件中完成的。

为了能够使用路由功能,在前端项目的入口文件main.js中,创建Vue实例时需要指定路由对象:

如果是已经创建了应用,需要通过vue-router实现路由功能,需要安装js库,通过命令:

npm install vue-router

2.2 路由配置

首先了解一下路由组成:

  • VueRouter:路由器,根据路由请求在路由视图中动态渲染对应的视图组件

  • <router-link>:路由链接组件,浏览器会解析成<a>

  • <router-view>:路由视图组件,用来展示与路由路径匹配的视图组件

具体配置方式:

1、在路由文件(src/router/index.js)中配置路由路径和视图的对应关系:


import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

//维护路由表,某个路由路径对应哪个视图组件
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = new VueRouter({
  routes
})

export default router

2、在视图组件中配置 router-link标签,用于生成超链接

3、在视图组件汇总配置router-view标签

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> 
    </nav>
    <!--视图组件展示的位置-->
    <router-view />
  </div>
</template>

要实现路由跳转,可以通过标签式和编程式两种:

  • 标签式:<router-link to="/about">About</router-link>

  • 编程式:this.$router.push('/about')

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <input type="button" value="编程式路由跳转" @click="jump" />
    </nav>
    <!--视图组件展示的位置-->
    <router-view />
  </div>
</template>

<script>
export default {
  methods: {
    jump() {
      //使用编程式路由跳转
      this.$router.push('/about')
    }
  }
}
</script>

问题思考:如果用户访问的路由地址不存在,该如何处理?

比如:配置了/test的路由标签,但是index.js中未配置相应的路由表

<router-link to="/test">Test</router-link> 

点击Test后url地址栏会显示/test,但是对应的路由组件展示位置无响应

可以通过配置一个404视图组件,当访问的路由地址不存在时,则匹配到的path就为*,则重定向到此视图组件,具体配置如下:

index.js中路由表中加入:

  {
    path: '/404',
    component: () => import('../views/404View.vue')
  },
  {
    path: '*',
    redirect: '/404' //重定向
  }

配置 404View.vue视图:

<template>
  <div class="about">
    <h1>您请求的资源不存在</h1>
  </div>
</template>

点击Test后

2.3 嵌套路由

嵌套路由:组件内要切换内容,就需要用到嵌套路由(子路由),效果如下:

在App.vue视图组件中有<router-view>标签,其他视图组件可以展示在此

ContainerView.vue组件可以展示在App.vue视图组件的<router-view>位置

ContainerView.vue组件进行了区域划分(分为上、左、右),在右边编写了<router-view>标签,点击左侧菜单时,可以将对应的子视图组件展示在此

实现步骤:

vue2的ElementUI库:https://element.eleme.cn/#/zh-CN

第一步:安装并导入 elementui,实现页面布局(Container 布局容器)---ContainerView.vue

安装elementui:
npm i element-ui -S


导入elementui:

在 main.js 中写入以下内容:
import ElementUI from 'element-ui'; 
import 'element-ui/lib/theme-chalk/index.css'; 
Vue.use(ElementUI);



src/views/container下新建ContainerView.vue页面
<template>
  <el-container>
    <el-header>Header</el-header>
    <el-container>
      <el-aside width="200px">Aside</el-aside>
      <el-main>Main</el-main>
    </el-container>
  </el-container>
</template>

<script>
export default {

}
</script>

<style>
.el-header,
.el-footer {
  background-color: #B3C0D1;
  color: #333;
  text-align: center;
  line-height: 60px;
}

.el-aside {
  background-color: #D3DCE6;
  color: #333;
  text-align: center;
  line-height: 200px;
}

.el-main {
  background-color: #E9EEF3;
  color: #333;
  text-align: center;
  line-height: 160px;
}

body>.el-container {
  margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
  line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
  line-height: 320px;
}
</style>

第二步:src/views/container下提供子视图组件,用于效果展示 ---P1View.vue、P2View.vue、P3View.vue

<template>
    <div>
        这是P1 View
    </div>
</template>

<script>
export default {

}
</script>

<style>
.el-header,
.el-footer {
    background-color: #B3C0D1;
    color: #333;
    text-align: center;
    line-height: 60px;
}

.el-aside {
    background-color: #D3DCE6;
    color: #333;
    text-align: center;
    line-height: 200px;
}

.el-main {
    background-color: #E9EEF3;
    color: #333;
    text-align: center;
    line-height: 160px;
}

body>.el-container {
    margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
    line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
    line-height: 320px;
}
</style>

第三步:在 src/router/index.js 中配置路由映射规则(嵌套路由配置)

  {
    path: '/c',
    component: () => import('../views/container/ContainerView.vue'),
    //嵌套路由(子路由),对应的组件会展示在当前组件内部
    children: [ //通过children属性指定子路由相关信息(path、component)
      {
        path: '/c/p1',
        component: () => import('../views/container/P1View.vue')
      },
      {
        path: '/c/p2',
        component: () => import('../views/container/P2View.vue')
      },
      {
        path: '/c/p3',
        component: () => import('../views/container/P3View.vue')
      }
    ]
  }

第四步:在ContainerView.vue 布局容器视图中添加<router-view>,实现子视图组件展示

<el-main>
    <router-view/>
</el-main>

第五步:在ContainerView.vue 布局容器视图中添加<router-link>,实现路由请求

<el-aside width="200px">
    <router-link to="/c/p1">员工管理</router-link><br>
    <router-link to="/c/p2">菜品管理</router-link><br>
    <router-link to="/c/p3">套餐管理</router-link><br>
</el-aside>

注意:子路由变化,切换的是【ContainerView 组件】中 <router-view></router-view> 部分的内容

测试:

问题思考:

1.对于前面的案例,如果用户访问的路由是 /c,会有什么效果呢?

2.如何实现在访问 /c 时,默认就展示某个子视图组件呢?

配置重定向,当访问/c时,直接重定向到/c/p1即可,如下配置:

3. 状态管理 vuex

3.1 vuex 介绍

  • vuex 是一个专为 Vue.js 应用程序开发的状态管理库

  • vuex 可以在多个组件之间共享数据,并且共享的数据是响应式的,即数据的变更能及时渲染到模板

  • vuex 采用集中式存储管理所有组件的状态

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

安装vuex:npm install vuex@next --save

vuex中的几个核心概念:

  • state:状态对象,集中定义各个组件共享的数据

  • mutations:类似于一个事件,用于修改共享数据,要求必须是同步函数

  • actions:类似于mutation,可以包含异步操作,通过调用mutation来改变共享数据

3.2 使用方式

本章节通过一个案例来学习vuex的使用方式,具体操作步骤如下:

第一步:创建带有vuex功能的前端项目

注:在创建的前端工程中,可以发现自动创建了vuex相关的文件(src/store/index.js),并且在main.js中创建Vue实例时,需要将store对象传入,代码如下:

import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,  //使用vuex功能
  render: h => h(App)
}).$mount('#app')

第二步:在src/store/index.js文件中集中定义和管理共享数据

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
​
//集中管理多个组件共享的数据
export default new Vuex.Store({
  //集中定义共享数据
  state: {
    name: '未登录游客'
  },
  getters: {
  },
  //通过当前属性中定义的函数修改共享数据,必须都是同步操作
  mutations: {
  },
  //通过actions调用mutation,在actions中可以进行异步操作
  actions: {
  },
  modules: {
  }
})

第三步:在视图组件中展示共享数据

src/App.vue

<template>
  <div id="app">
    欢迎你,{{ $store.state.name }}
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

修改视图组件src/components/HelloWorld.vue

<template>
  <div class="hello">
    <h1>欢迎你,{{ $store.state.name }}</h1>
  </div>
</template>

注:$store.state为固定写法,用于访问共享数据

目前显示效果:

第四步:在mutations中定义函数,用于修改共享数据

  //通过当前属性中定义的函数修改共享数据,必须都是同步操作
  mutations: {
    setName(state, newName) {
      state.name = newName
    }
  },

第五步:在视图组件中调用 mutations 中定义的函数

注:mutations中定义的函数不能直接调用,必须通过状态对象的 commit 方法来调用

效果:

第六步:如果在修改共享数据的过程中有异步操作,则需要将异步操作的代码编写在actions的函数中

需要先在控制台安装axiox

npm install axios

  actions: {
    setNameByAxios(context) {
      axios({
        url: '/api/admin/employee/login',
        method: 'post',
        data: {
          username: 'xuezhiqian',
          password: '123456'
        }
      }).then(res => {
        if (res.data.code == 1) {
          //异步请求后需要更改共享数据
          //在actions中调用mutations中定义的setName函数
          context.commit('setName', res.data.data.name)
        }
      })
    }
  },

在配置文件vue.config.js中配置代理

devServer: {
    port: 7070,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }

注:在actions中定义的函数可以声明context参数,通过此参数可以调用mutations中定义的函数

第七步:在视图组件中调用actions中定义的函数

注:在actions中定义的函数不能直接调用,必须通过 this.$store.dispatch('函数名称') 这种方式调用

测试:

后端请求日志:

前端请求:

响应回来的结果:

4. TypeScript

4.1 TypeScript 介绍

  • TypeScript(简称:TS) 是微软推出的开源语言

  • TypeScript 是 JavaScript 的超集(JS 有的 TS 都有)

  • TypeScript = Type + JavaScript(在 JS 基础上增加了类型支持)

  • TypeScript 文件扩展名为 ts

  • TypeScript 可编译成标准的 JavaScript,并且在编译时进行类型检查

  • TypeScript完全兼容JavaScript,ts文件中可以完全写js

在前端项目中使用TS,需要进行安装,命令为:npm install -g typescript

查看TS版本:

TS初体验:

1.创建 hello.ts 文件,内容如下:

//定义一个函数 hello,并且指定参数类型为string
function hello(msg:string) {
      console.log(msg)
}
​
//调用上面的函数,传递非string类型的参数
hello(123)

2.使用 tsc 命令编译 hello.ts 文件

可以看到编译报错,提示参数类型不匹配。这说明在编译时TS会进行类型检查。需要注意的是在编译为JS文件后,类型会被擦除。

3.修改正确 hello.ts,重新编译

//通过ts代码,指定函数的参数类型为string
function hello(msg:string){
	console.log(msg)
}

//传入的参数类型为number
hello('123')

编译前为hello.ts,编译后文件为hello.js

编译为JS文件后,类型会被擦除。

思考:TS 为什么要增加类型支持 ?

  • TS 属于静态类型编程语言,JS 属于动态类型编程语言

  • 静态类型在编译期做类型检查,动态类型在执行期做类型检查

  • 对于 JS 来说,需要等到代码执行的时候才能发现错误(晚)

  • 对于 TS 来说,在代码编译的时候就可以发现错误(早)

  • 配合 VSCode 开发工具,TS 可以提前到在编写代码的同时就发现代码中的错误,减少找 Bug、改 Bug 的时间

在前端项目中使用TS,需要创建基于TS的前端工程:

4.2 TypeScript 常用类型

TS中的常用类型如下:

类型 备注
字符串类型 string
数字类型 number
布尔类型 boolean
数组类型 number[],string[], boolean[] 依此类推
任意类型 any 相当于又回到了没有类型的时代
复杂类型 type 与 interface
函数类型 () => void 对函数的参数和返回值进行说明
字面量类型 "a"|"b"|"c" 限制变量或参数的取值
class 类 class Animal
4.2.1 类型标注的位置

基于TS进行前端开发时,类型标注的位置有如下3个:

  • 标注变量

  • 标注参数

  • 标注返回值

4.2.2 字符串、数字、布尔类型

字符串、数字、布尔类型是前端开发中常用的类型

4.2.3 字面量类型

字面量类型用于限定数据的取值范围,类似于java中的枚举

4.2.4 interface 类型

interface 类型是TS中的复杂类型,它让 TypeScript 具备了 JavaScript 所缺少的、描述较为复杂数据结构的能力。

可以通过在属性名后面加上?,表示当前属性为可选,如下:

4.2.5 class 类型

使用 class 关键字来定义类,类中可以包含属性、构造方法、普通方法等

在定义类时,可以使用 implments 关键字实现接口,如下:

在定义类时,可以使用 extends 关键字 继承其他类,如下:

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐