前面已经完成了Vue登录第1版,仅仅是使用JS进行了前端登录验证。下面将在第1版的基础上,使用SpringBoot完成后端程序,通过状态码的传输实现登录认证。这里称其为Vue登录第2.1版。

Vue登录第2.1版采用传输状态码的形式进行登录认证,具体是:

(1)使用Vue完成登录界面,用户输入用户名和密码,向后端程序发送登录请求,并将输入的用户名和密码一起发送到后端程序。

(2)后端程序接受发送的用户名和密码,与事先给出的用户名为“admin”和密码为“123456”,然后进行登录验证。

(3)如果用户输入的用户名和密码与事先设置的用户名和密码相等,返回一个登录成功的状态码;如果都为空,提示输入用户名和密码;如果不相等,则提示用户名或密码错误,则返回一个不成功的状态码。

(4)前端接受状态码,登录成功,则返回灯塔的主界面;不成功,则发出提示信息。

下面分前端程序和后端程序进行讲解。

2.2 Vue登录第2.1版前端程序

Vue登录第2.1版前端程序采用Vue登录第1版的程序,因为要向后端程序发送请求,并接受返回的数据,需要修改main.js和Login.vue这两个文件。

2.2.1  在main.js文件中增加axios库

在main.js文件中增加axios库之前,先复习一下跨域这个知识点。

什么是跨域?

要了解跨域,先要说说同源策略。同源策略是由 Netscape 公司提出的一个安全策略,其含义简单地说:为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下,是不能读写对方资源的。可以这么说同源策略是浏览器安全的基石。这里的同源是指域名、协议和端口相同的资源。当页面在执行一个脚本时会检查访问的资源是否同源,如果非同源,那么在请求数据时,浏览器会报送一个异常,提示拒绝访问。

为了更好地理解同源,下面用一个例子进行说明:

判断下面的资源或URL与 http://www.a.com/dir/index.html 是否同源的?

http://www.a.com/dir1/index2.html,协议、域名和端口(都是80端口),故同源。

http://www.b.com/dir/index.html,域名不同,不同源。

https://www.a.com/index.html, 不同的协议(https,http),故不同源。

http://www.a.com:8080/dir/index.html,不同的端口(一个是80,一个是8080),故不同源。

理解了同源策略,对什么是跨域,就很清楚了。所谓跨域就是指的是从一个域名去请求另外一个域名的资源,即跨域名请求。但浏览器的同源策略这一安全基石是不允许的。

为了解决浏览器跨域请求的问题,W3C提出了跨域资源共享方案(Cross-origin resource sharing,CORS)。下面的几篇博客关于跨域说得更详细。

https://blog.csdn.net/qq_38128179/article/details/84956552。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS。

https://www.jianshu.com/p/f880878c1398。

https://www.jb51.net/article/161075.htm。

前后端分离的系统中,前端的URL地址和后端的URL地址是不同源的,涉及到跨域请求。

在Vue前端中,可以增加axios库来解决。

在SpringBoot项目中,可以通过配置添加CORS跨域来解决,后面就会加以介绍。

下面首先在Vue前端增加axios库。

在src目录下的main.js文件中,增加axios库进行发送跨域请求,具体代码如下:

程序清单2.1  main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
//等效于:
// import router from './router/index.js'// 导入全局样式表
import '@/assets/css/global.css'// 引用axios库,向服务器端发送请求,等同于:
// import axios from 'axios'
var axios = require('axios')
// 设置请求的接口,简单地说就是发送请求的URL地址
axios.defaults.baseURL = 'http://localhost:8082/'
// 将axios挂载到vue原型身上即全局注册,
// 之后可在其他组件中通过this.$axios发送数据
Vue.prototype.$axios = axios// 设置为“false” 用于关闭生产模式下给出的提示
Vue.config.productionTip = falsenew Vue({router,render: h => h(App),
}).$mount('#app')

2.2.2  修改登录视图文件Login.vue

在src目录下,修改views视图目录下的登录视图文件Login.vue,使用this.$axios库向后端程序发送登录请求。具体代码如下:

程序清单2.2  Login.vue

<template lang=""><div class="login" id="login"><div class="input-wrap"><label for="male">账  号:</label><input type="text" v-model="username" placeholder="请输入账号"/></div><div class="input-wrap"><label for="male">密  码:</label><input type="password" v-model="password" placeholder="请输入密码"/></div><div class="input-wrap"><!-- <button v-on:click="login">登录账号</button>&nbsp;&nbsp; --><button @click="login">登录</button>&nbsp;&nbsp;<button @click="login">注册</button></div></div>
</template>
<script>
export default {data() {return {username: "",password: "",};},methods: {login() {const { username, password } = this;// 等同于如下语句:// const username = this.username// const password = this.passwordif (username.length == 0 || password.length == 0) {alert("请输入用户名或密码!");return;}// 发送登录请求this.$axios.post("/login", {username: username,password: password,}).then((resp) => {console.log(resp);let code = resp.data.code;// alert(code)if (code === 200) {alert("登录成功!");this.$router.push({ path: "/index" });} else {alert("登录失败!");}});},},
};
</script><style>
.login {position: absolute;top: 0;right: 0;bottom: 0;left: 0;width: 300px;height: 80px;padding: 10px;margin: auto;/*margin: 20% auto;*/
}
.input-wrap {margin: 20px auto;
}
</style>

2.2.3  前端程序的运行

前端程序还是Vue登录第1版的程序,只是修改了以上几个文件,运行与Vue登录第1版一样,在终端中运行命令:npm run serve,此处省略。

2.3  Vue登录第2.1版后端程序

Vue登录第2.1版后端程序采用SpringBoot来实现。

关于如何创建SpringBoot项目的博客太多,有的写得很用心,这里推荐几篇,大家可参考。

https://blog.csdn.net/sunnyzyq/article/details/108666480。

https://blog.csdn.net/qq_26071319/article/details/106209405。

下面简要介绍灯塔管理系统Vue登录第2.1版后端程序创建过程。

2.3.1 创建后端项目lighthouse-code

打开IDEA 2020.3.1编辑器,如图1是打开创建项目的界面。

图1

在图1中单击按钮【New Project】,打开新建项目的窗口,如图2所示。

图2

在图2的左边选择【Spring Initializr】,右边保持Default,单击按钮【Next】,打开图3所示的界面。

注:如果网络情况不好,可以选择右边的定制【Custom】,在地址栏输入:https://start.aliyun.com/,点击 “Next”,也可以完成SpringBoot项目的创建。还可以在https://start.spring.io/网上生成项目信息后,下载到本地磁盘打开,此处省略。

图3

图3中几个地方的说明如下。

Group:项目组织的唯一标识符,一般采用域名的反写。比如:这里我填写的是com.solo,com是域名,solo是根据自己的爱好而取得,很早很早以前就觉得写程序的人就像一个孤独的舞者,故而取了solo。

Artifact:项目的名称,唯一标识符。注意只能小写,可以用短划线连接单词,试图用数字肯定通不过。

在图3中,单击按钮【Next】,打开图4所示的界面。

图4

在图4中,可以增加依赖包,也就是相当于在pom.xml配置依赖关系。只不过这个是图形界面的。在图中,单击按钮【Next】,打开图5所示的界面。

图5

在图5中,显示了创建后端程序项目命名、保存的路径等信息。在图中,单击按钮【Next】,打开图6所示的界面。

图6

在图6中,是后端程序的整个基础结构。左边是项目的文件目录,中间是左边对应的源文件,右边是Maven的结构。

下面重点分析左边文件的目录结构和几个重点的文件。为了清楚起见,将左边的图单独截取出来进行说明,如图7所示。

图7

图7中的目录结构和文件都是前面自动创建的。这里重点说明几个。

(1)pom.xml:这是用Maven管理项目的配置文件,简单地说,项目中会用到很多jar包,通过这个配置文件引入其坐标,Maven就会帮我们去下载安装,不需要我们手动去添加。关于其详细配置,其官网https://maven.apache.org/pom.html说得非常详细。

(2)src文件目录:保存源代码的文件夹,包含了两个子目录main和test,前面一个是开发最主要的代码,后面一个是测试用的。在main目录中,包含java和resource。

(3)java目录:存放包和java源代码的地方。com.solo就是上面创建的包名,还可以在它的下面在创建若干个子包,在包和子包下创建java类文件,这是java的基础知识,省略。在java下面还有一个LighthouseCodeApplication.java文件,这个在下面单独说明。

(4)resource目录:存放资源文件的地方。由于是前后端分离项目,这里的两个文件夹static和templates都不会用到。在resource目录下还有一个application.properties配置文件, 这个在下面单独说明。

(5)LighthouseCodeApplication.java:这是一个程序启动类,程序唯一的入口。每次创建SpringBoot项目时,都会自动创建这个文件,名称为*Application.java,星号*为项目名称,其中首字母大写,如多个单词,则每个单词的首字母都要大写。这个启动类或入口类有一个main方法,它其实就是一个标准的Java应用程序的入口方法。在main方法中使用SpringApplication.run()启动SpringBoot应用项目。LighthouseCodeApplication.java最基本的代码如程序清单2.3。

程序清单2.3  LighthouseCodeApplication.java

package com.solo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class LighthouseCodeApplication {public static void main(String[] args) {SpringApplication.run(LighthouseCodeApplication.class, args);}}

程序清单2.3  LighthouseCodeApplication.java在SpringBoot应用程序中有两个作用:第一个是完成组件扫码和自动配置;第二个是启动应用程序运行。

第6行:@SpringBootApplication开启Spring的组件扫码和SpringBoot自动配置功能,是SpringBoot的核心注解。

第9行:负责启动引导应用程序。

      (6)application.properties:这是一个配置文件,每次创建SpringBoot项目时,都会自动创建这个文件。关于这个文件后面还会继续讲解,此处省略。

到此,完成了创建后端项目lighthouse-code,可以直接运行LighthouseCodeApplication.java,此处省略。

下面提供几篇博客和书籍。

https://spring.io/guides

https://spring.io/projects/spring-boot

https://maven.apache.org/pom.html。

https://www.javatpoint.com/spring-boot-application。

https://blog.csdn.net/qq_45173404/article/details/108627349。

https://spring.io/guides

https://spring.io/projects/spring-boot

《Spring实战》、《Spring Boot实战》、《JavaEE开发的颠覆者:Spring Boot实战》。

接下来在此基础上,开始完成灯塔管理系统Vue登录第2.1版的后端程序。

2.3.2  创建Vue登录第2.1版的后端程序的包结构

灯塔管理系统是以前做项目使用的一个脚手架,最早是基于SSH框架的项目开发,经历过Spring MVC和SpringBoot项目的开发,这次为了写博客,抽取其中权限部分,总的架构如图8所示。

图8

图8中有关包的说明如下:

(1)com.solo下面的base包用于存放系统基础的部分。base包下面包括rbac和security包,前者用于权限管理,后者用于数据安全传输等。

(2)com.solo下面的common包用于存放工具类和配置的部分。common包下面包含config和utils包,前者用于配置跨域等,后者是一些工具类。

2.3.3  pom.xml

由于目前没有引入其他依赖关系,还是保持创建项目的pom.xml配置。下面简要说明如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.3</version><relativePath/> <!-- lookup parent from repository --></parent><!--    项目信息的配置  --><groupId>com.solo</groupId><artifactId>lighthouse-code</artifactId><version>2.1.0</version><name>lighthouse-code</name><description>lighthouseV2.1</description><properties><java.version>1.8</java.version></properties><!-- 定义项目的依赖关系,后面添加依赖关系,就在这里面增加 --><dependencies><!-- 自动配置模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 测试模块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.3.4  在application.properties配置端口

application.properties是SpringBoot的一个全局配置文件,其作用是修改SpringBoot自动配置的默认值,比如:服务器的端口、日志、数据源等。本次只配置服务器的端口号,具体如下:

#配置服务器的端口号
server.port=8082

注意:.properties配置文件的格式,采用的等号=赋值的形式,等号左边是配置属性的名称,等号右边是值。

配置文件除了支持.properties后缀名外,还支持.yml后缀名的配置文件。

2.3.5  修改LighthouseCodeApplication.java

尽管运行LighthouseCodeApplication.java后,能够提示系统是否运行成功的信息,但为了更清晰的显示运行是否成功的信息,可以添加一些个性化的输出信息,下面在该文件中增加了一条输出语句,运行成功后,会输出一条“To the Lighthouse......”的信息。

package com.solo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class LighthouseCodeApplication {public static void main(String[] args) {SpringApplication.run(LighthouseCodeApplication.class, args);System.out.println("To the Lighthouse......");}}

运行该程序,运行结果如图9所示。

图9

2.3.6  在com.solo.base.security下创建LoginDTO

在com.solo.base.security下创建LoginDTO.java类,用于接受用户登录数据传输对象,代码如下:

package com.solo.base.security;/** FileName: LoginDTO.java* Description: // 用户登录数据传输对象(Data Transfer Object)* Author:   woolflighthouse@163.com* Date:     2022/2/8 20:54*/
public class LoginDTO {/*** 用户名或登录账户*/private String username;/*** 密码*/private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

数据传输对象(Data Transfer Object,DTO),简单地说就是用户封装数据和安全传输数据。这是一种设计模式,而非必须这样做。在下面会了解其使用过程。

2.3.7  配置跨域

在前面已经对跨域进行了说明,在后端程序也需要进行跨域的配置,不然也会发生跨域请求失败的异常。在SpringBoot可以通过@Configuration创建一个配置类来实现。

在com.solo.common.config下创建一个配置类CorsConfig.java来实现,具体代码如下:

package com.solo.common.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;/** FileName: CorsConfig.java* Description: // 跨域配置* Author:   woolflighthouse@163.com* Date:     2022/2/8 21:03*/
@Configuration
public class CorsConfig {private CorsConfiguration buildConfig() {CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("*"); // * 表示对所有的地址都可以访问corsConfiguration.addAllowedHeader("*"); // 跨域的请求头corsConfiguration.addAllowedMethod("*"); // 跨域的请求方法return corsConfiguration;}@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", buildConfig());return new CorsFilter(source);}
}

2.3.8  封装返回数据结果

对于前端请求的响应,会返回状态、信息和数据,对这些返回的数据进行封装,封装为一个返回数据的结果类Result。

在com.solo.common.utils下创建一个Result.java类,代码如下:

package com.solo.common.utils;import java.io.Serializable;/** FileName: Result.java* Description: // 返回数据集封装* Author:   woolflighthouse@163.com* Date:     2022/2/8 20:58*/
public class Result  implements Serializable {private static final long serialVersionUID = 1L;///*** 响应码或状态码*/private Integer code;/*** 信息*/private String message;/*** 返回数据*/private Object data;public Result(Integer code) {this.code = code;}public Result(Integer code, String message, Object data) {this.code = code;this.message = message;this.data = data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}}

2.3.9  创建登录控制器

控制器简单地说就是用于处理请求的类。基于Web的编程,其核心就是HTTP协议的请求/响应模型,这种请求/响应模型贯穿于编程的始终,前端发送来请求,后端接受请求,并作出响应,控制器就是做这个事情的。
       为了完成Vue登录前端发送请求的响应,需要一个登录控制器来处理这个请求。
       在com.solo.base.rbac包下创建一个存放控制器的子包,并在该子包下创建一个登录控制器LoginController.java,代码如下:

package com.solo.base.rbac.controller;import com.solo.base.security.LoginDTO;
import com.solo.common.utils.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;/** FileName: LoginController.java* Description: // 登录控制器* Author:   woolflighthouse@163.com* Date:     2022/2/8 21:06*/
@RestController
public class LoginController {@RequestMapping(value = "/login", method = RequestMethod.POST)public Result login(@RequestBody LoginDTO loginDTO) {String username = loginDTO.getUsername();String password = loginDTO.getPassword();if (username.equals("admin") && password.equals("123456")) {return new Result(200);} else {return new Result(400);}}}

第16行:@RestController是一个由Spring 4.0引入的更加便捷的注解,等效于@Controller + @ResponseBody。在LoginController类上面加上@RestController,一方面表示这是一个controller类;另一方面还具有@Responsebody注解的作用。@Responsebody注解的作用是将控制器中方法返回的对象转换为指定的格式之后,写入到response对象的body区,通常用来返回json等数据,简单地说使用此注解之后返回的不是视图,而是数据。因为前后端分离不会直接返回视图,而是返回数据,比如json格式的数据,所以使用@RestController进行注解。
       第18行:@RequestMapping是一个用来处理请求地址映射的注解。
       第19~27行:定义了一个登录login()方法。返回值是一个Result类,参数是一个loginDTO对象,使用@RequestBody进行注解,表示以loginDTO对象接收前端传过来的json数据。

2.3.10  运行前后端程序

在终端运行前端程序,运行命令和信息如下:

Microsoft Windows [版本 10.0.19043.1466]
(c) Microsoft Corporation。保留所有权利。D:\vue-project\lighthouse\lighthouse-vue>npm run serve> lighthouse-vue@0.1.0 serve D:\vue-project\lighthouse\lighthouse-vue
> vue-cli-service serveINFO  Starting development server...
98% after emitting CopyPluginDONE  Compiled successfully in 2163ms                                                                                                                                          下午8:53:29App running at:- Local:   http://localhost:8080/- Network: http://192.168.0.102:8080/Note that the development build is not optimized.To create a production build, run npm run build.

在浏览器中输入http://localhost:8080/地址,打开如图10所示的登录界面。

图10

运行后端程序如图9所示。在图10中输入账号:admin,密码:123456,登录验证成功,打开如图11所示的界面。

显示的页面表示登录成功。

至此,完成了Vue登录第2.1版。

君问归期未有期,巴山夜雨涨秋池。

Vue登录第2.1版相关推荐

  1. 基于 SpringBoot + Vue 框架开发的网页版聊天室项目

    ‍ ‍简介 微言聊天室是基于前后端分离,采用SpringBoot+Vue框架开发的网页版聊天室.使用了Spring Security安全框架进行密码的加密存储和登录登出等逻辑的处理,以WebSocke ...

  2. 天联高级版客户端_天联客户端登录的KIS旗舰版打印单据问题

    如何解决天联客户端登录的KIS旗舰版打印单据问题 用户通过天联高级客户端访问服务器端的KIS旗舰版,但是反应两边单据打印出来的结果不一致,现在以KIS旗舰版打印外购入库单为例具体介绍一下如何操作 1. ...

  3. 桔子浏览器电脑版如何登录 桔子浏览器PC版账号登录教程

    桔子浏览器电脑版如何登陆?桔子浏览器支持账号登录功能,能够帮助用户收藏自动备份,不用担心丢失的情况,今天我们就来讲讲怎么登录账号. 桔子浏览器PC版账号登录教程 1.打开桔子浏览器点击[工具]-[登录 ...

  4. vue 数值 拼接字符串_【Vue原理】Compile - 白话版

    写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 [2.5.17] 如果你觉得排版难 ...

  5. v-model双向绑定原理_【Vue原理】VModel 白话版

    ↑点击上方 "神仙朱" 一起研究Vue源码吧 专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版让大家可以轻松理解工作原理,源码版让大家更清楚内部操作和 Vu ...

  6. Springboot Vue Login(从零开始实现Springboot+Vue登录)

    实现前端后端分离,在 Github 上有一个很好的开源项目:mall,正所谓百看不如一练,自己动手实现了一个 Springboot+Vue 的登录操作,在此记录一下踩过的坑. 文章最后补充两端的 Gi ...

  7. vue init失败解决方案-终极版

    vue init失败解决方案-终极版 参考文章: (1)vue init失败解决方案-终极版 (2)https://www.cnblogs.com/suger-life/p/8084368.html ...

  8. Vue登录注册,并保持登录状态

    关于vue登录注册,并保持登录状态,是vue玩家必经之路,网上也有很多的解决方法,但是有一些太过于复杂,新手可能会看的一脸懵逼,现在给大家介绍一种我自己写项目在用而且并不难理解的一种方法. 项目中有一 ...

  9. Vue登录注册,并保持登录状态 1

    关于vue登录注册,并保持登录状态,是vue玩家必经之路,网上也有很多的解决方法,但是有一些太过于复杂,新手可能会看的一脸懵逼,现在给大家介绍一种我自己写项目在用而且并不难理解的一种方法. 项目中有一 ...

最新文章

  1. 手机归属地和ip定位
  2. gradle工程环境搭建---从SVN上导出项目源码
  3. 成功解决极其刁钻bug之SyntaxError: invalid character in identifier
  4. checkbox控件的checked属性作用是_VB6基本控件的使用,制作一个数据输入窗口
  5. boost::sort模块实现spreadsort 双排序示例
  6. linux 内核 核心代码,8分钟掌握Linux内核分析的核心科技
  7. 定时器驱动数码管c语言程序,用c语言编写,实用定时器实现数码管15倒计时
  8. 玩转Web之servlet(一)---怎样创建一个servlet
  9. Linux中Docker的yum源与镜像加速器
  10. JSONObject和JSONArray使用
  11. win11可以支持win10驱动吗 Windows11更新驱动的步骤方法
  12. SQL:postgreSQL借助日期函数Extract按照时间区分查询结果
  13. java的map的方法_Java中Map集合(接口)的基本方法程序演示
  14. 学校计算机组管理制度,校园一卡通管理结算中心机房管理制度
  15. Unity3D使用talkingData应用数据统计
  16. Kotlin 初体验
  17. 低熵加壳malware
  18. 【stm32f4 C++与C混合开发】建立keil5的ARM Compiler 6(AC6)标准库开发工程
  19. 如何重新启动Windows的Explorer.exe(以及任务栏和“开始”菜单)
  20. python导入包时有下划红线

热门文章

  1. 直面W5100发热问题
  2. 广州Java培训机构排名榜单亲身经历说说看
  3. 设计模式在程序中的使用
  4. 精心整理的70+款免费AI工具,总有适合你的(建议收藏)
  5. directshow捕获摄像头数据
  6. Scrapy框架学习(四)爬取360摄影美图
  7. viewpager嵌套viewpager
  8. LNMP架构搭建过程(超详细!)
  9. 老人皮肤和面部表情,角色模型制作必看!
  10. minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁