ToB企服应用市场:ToB评测及商务社交产业平台

标题: 全栈教程:Spring Boot 和 Vue.js 入门 [打印本页]

作者: 络腮胡菲菲    时间: 2023-7-13 13:25
标题: 全栈教程:Spring Boot 和 Vue.js 入门
在本教程中,你将创建一个 CoffeeBot 应用程序。该应用程序就像机器人咖啡机的控制器。遗憾的是,它实际上不会为你提供咖啡,但它将演示大量有用的编程技术。该应用程序将有一个 Vue.js 客户端和一个 Spring Boot 资源服务器。它将使用 JHipster 进行引导,节省大量时间并演示一些最佳实践,包括在客户端和服务器中自动配置端到端 JWT 身份验证。你还将使用 Split 来展示如何分别使用 Split 的 Javascript SDK 和 Java SDK 在运行时动态地使用功能标志来管理前端和后端的功能集。
该应用程序本身提供饮料。服务器维护着一份饮料清单,主要是咖啡,附有尺寸、价格和名称。为简单起见,饮料列表将使用内存中的开发数据库进行保存,但如果需要,可以轻松地重新配置以实现持久性。客户端从服务器请求饮料列表,如果用户通过身份验证,则传递任何身份验证数据。
客户端接收此列表并将饮料列表显示为按钮列表。第二次分割纯粹与客户有关。添加了一项新功能:能够在饮料中添加奶油。正如你可以想象的那样,考虑到人们对咖啡中奶油的喜爱程度,虚拟骚乱已经开始要求此功能。人们在叫嚷。但经理们希望在广泛发布之前确保奶油功能正常工作(CoffeeBot 有时会失灵)。因此,根据经过身份验证的用户,添加奶油的能力被切换。你可以在这个链接:
看到如何使用 Split 的 Javascript SDK 来控制客户端的奶油功能,以及如何使用 Split 的 Java SDK 来控制服务器的饮料列表

Java + Vue.js 教程依赖项

Java:我在本教程中使用了 Java 12。你可以访问AdaptOpenJdk 网站下载并安装 Java 。或者你可以使用SDKMAN甚至Homebrew等版本管理器。
Node:按照 Node网站上的说明安装 Node 。本教程是使用 Node 12.14.0 编写的。
JHipster:一旦安装了 Java 和 Node,就可以安装 JHipster。按照其网站上的说明进行操作(如果出现问题,有助于排除故障)或只需运行此命令:npm install -g generator-jhipster@6.9.0使用npm.
拆分:如果你还没有免费的拆分帐户,请注册一个。这就是实现功能标志的方式。
使用 JHipster 引导你的 Spring Boot 应用程序

要创建示例 CoffeBot 应用程序,你将使用 JHipster。正如其网站上所述,“JHipster 是一个快速生成、开发和部署现代 Web 应用程序和微服务架构的开发平台。” 它允许你快速启动具有各种前端和服务器配置的基于 Java 的项目。本教程将使用 Vue.js。
JHipster 的优点之一是它为你创建了一个包含 Java 服务器应用程序和 Vue.js 前端应用程序的组合项目。它还包括将创建数据模型实体和 Web 服务控制器的生成器。它做了很多事情并创建了很多文件。如果你对这些平台相对陌生,那么项目结构可能看起来有点令人难以承受,但他们在网站上记录了所有内容,做得很好。他们布置的项目遵循当前的最佳实践,因此它是一个很好的学习工具。
打开 shell 并为你的项目创建一个根目录,例如    CoffeeBotApp. 导航到该目录。你将在此处生成项目文件。
通常,当你运行 JHipster 时,它会询问你许多有关你正在引导的项目的问题。但是,为了简化事情,你将使用此.yo-rc.json文件来预先配置项目,从而绕过询问。
在根项目目录中,创建一个.yo-rc.json包含以下内容的文件。此配置的一些亮点是:
applicationType:整体应用程序:典型的标准应用程序(本质上不是微服务)
baseName : coffeebot– 应用程序的名称
packageName : com.split.coffeebot– 基础 Java 包
authenticationType : jwt– JSON Web 令牌身份验证
devDatabaseType : h2Memory– 开发数据库使用内存中的 H2 数据库,该数据库不会跨会话持久化
**clientFramework **: vue– 使用Vue.js作为前端客户端框架
SkipFakeData : true– JHipster 默认情况下会为数据模型生成一组随机的假数据,我们希望在本教程中跳过这些数据
有很多选择。请参阅文档以深入了解这一点。
  1. {
  2.   "generator-jhipster": {
  3.     "promptValues": {
  4.       "packageName": "com.split.coffeebot"
  5.     },
  6.     "jhipsterVersion": "6.9.0",
  7.     "applicationType": "monolith",
  8.     "baseName": "coffeebot",
  9.     "packageName": "com.split.coffeebot",
  10.     "packageFolder": "com/split/coffeebot",
  11.     "serverPort": "8080",
  12.     "authenticationType": "jwt",
  13.     "cacheProvider": "ehcache",
  14.     "enableHibernateCache": true,
  15.     "websocket": false,
  16.     "databaseType": "sql",
  17.     "devDatabaseType": "h2Memory",
  18.     "prodDatabaseType": "mysql",
  19.     "searchEngine": false,
  20.     "messageBroker": false,
  21.     "serviceDiscoveryType": false,
  22.     "buildTool": "gradle",
  23.     "enableSwaggerCodegen": false,
  24.     "jwtSecretKey": "ZDg4ZjkzMDJkNWQ4YWJlMjUxOTY3YjE1MDNjY2ZkMzJjYWQwYjJiOTkyMWQ3YTE5ZTgwNWY3Y2E1ZDg0OWViZjM0Nzg1NDE3MjNlMGY1MDBkNTg4YWU1MmZmNTU1ZGEzOTJiMTVlMWZjZDc5NDUyMTlmZmRmYTU0NDJjMDdiODA=",
  25.     "embeddableLaunchScript": false,
  26.     "useSass": true,
  27.     "clientPackageManager": "npm",
  28.     "clientFramework": "vue",
  29.     "clientTheme": "none",
  30.     "clientThemeVariant": "",
  31.     "creationTimestamp": 1601147759112,
  32.     "testFrameworks": [],
  33.     "jhiPrefix": "jhi",
  34.     "entitySuffix": "",
  35.     "dtoSuffix": "DTO",
  36.     "otherModules": [
  37.       {
  38.         "name": "generator-jhipster-vuejs",
  39.         "version": "1.8.0"
  40.       }
  41.     ],
  42.     "enableTranslation": false,
  43.     "blueprints": [
  44.       {
  45.         "name": "generator-jhipster-vuejs",
  46.         "version": "1.8.0"
  47.       }
  48.     ],
  49.     "skipFakeData": true
  50.   }
  51. }
复制代码
通过运行以下命令(在包含该文件的根项目目录中.yo-rc.json)创建入门应用程序。
  1. jhipster
复制代码
当 JHipster 创建项目时,你将看到大量控制台输出。它应该以以下行结束。
  1. INFO! Congratulations, JHipster execution is complete!
复制代码
代码语言: Swift  (斯威夫特)
JHipster 已经创建了一个 Git 存储库并进行了初始提交。此时,你可以通过打开两个 shell(一个用于客户端,一个用于服务器)并运行以下命令来运行入门应用程序。
Spring Boot 服务器:
./gradlew
Vue.js 客户端:
npm start
生成 Spring Boot 数据模型

现在你想要使用 JHipster 生成数据模型或实体。它们定义了将存储在数据库中并由 REST 服务提供服务的数据结构。当你使用 JHipster 的生成器创建实体时,JHipster 和 Spring 会为你完成许多出色的幕后工作。它创建表示数据结构的 Java 类,并使用允许将数据保存到数据库的 JPA 注释进行注释。它还创建一个实现创建、读取、更新和删除 (CRUD) 功能的资源文件,该文件会自动受到所选身份验证方案(在我们的示例中为 JWT)的保护。
在前端,生成器创建必要的文件,允许你与实体的资源服务器进行交互,以及前端文件来创建、更新和检查持久数据实体(要访问它,你必须以管理员用户身份登录)。
在项目根目录中,创建一个新文件:entities.jdl. 该文件定义了一种具有四个属性的实体类型,以及该实体中使用的枚举类型。
  1. enum DrinkSize {
  2.     Small,
  3.     Medium,
  4.     Large,
  5.     XLarge,
  6.     XXLarge
  7. }
  8. entity Drink {
  9.     name String required,
  10.     size DrinkSize required,
  11.     caffeineMilligrams Integer required,
  12.     priceDollars Integer required,
  13. }
复制代码
通过运行生成实体文件:
  1. jhipster import-jdl entities.jdl
复制代码
当它询问你是否覆盖文件时,只需键入ato overwrite this and all others。
现在是运行入门应用程序并探索引导功能的好时机。请记住,你需要运行两个不同的进程。
** Spring Boot Java 服务器**```
  1. ./gradlew
复制代码
Vue.js 客户端(你可能需要等待一分钟左右服务器才能完成运行):
  1. npm start
复制代码
客户端应用程序应自动打开。如果没有,请打开 http://localhost:9000
使用默认凭据以管理员用户身份登录admin:admin。查看“管理”菜单下的所有功能。另请查看“实体”菜单。你可以在此处查看、添加和更新你创建的实体。在我们的例子中,这是Drink实体,它有四个属性:name、size、caffeine mgs和Price Dollars。
Vue.js 客户端使用 TypeScript 和类组件,并将模板和组件声明拆分为两个单独的文件。如果你习惯于更传统的.vue单文件结构,一开始这可能看起来有点奇怪,但大多数差异都是不言自明的。如果你需要帮助,请查看文档中的官方页面以获取更多信息。
将功能标志添加到你的 Spring Boot Java 服务器

你将使用 Split 在客户端和服务器上实现功能标志。你应该已经注册了一个免费帐户(如果没有,请立即注册)。目前,你要将 Java Split SDK 集成到 Spring Boot 应用程序中。我将引导你完成此过程,但如果你需要更多信息或遇到麻烦,请查看他们的 Java SDK 文档。
首先,将Split依赖添加到build.gradle文件中(在项目根目录中)。该build.gradle文件包含大量内容。只需在末尾附近添加以下行,就在开始的注释行上方//jhipster-needle-gradle-dependency。
  1. dependencies {
  2.     ....
  3.     compile 'io.split.client:java-client:4.0.1'
  4.     //jhipster-needle-gradle-dependency - JHipster will add additional dependencies here
  5. }
复制代码
你将需要你的 Split API 密钥。打开你的拆分仪表板。通过转到仪表板左上角的方形工作区图标(可能显示默认为DE)找到 API 密钥,单击它,然后单击Admin Settings。单击左侧面板中“工作区设置”下的“API 密钥”。
你将看到已创建四个 API 密钥,其中两个用于生产,两个用于暂存。服务器端 SDK 使用和客户端 Javascript 使用有不同的密钥。SDK和staging-default密钥是你稍后需要的。

将 API 密钥添加到配置文件的末尾application.yml。
src/main/resources/application.yml
  1. #application:
  2. split:
  3.     api-key: <yourSplitApiKey>代码语言: 小黄瓜 (gherkin )
复制代码
我只是指出,在这里你将其添加到全局配置文件中,但在更实际的用例中,你可能会使用两个不同的 API 密钥,一个用于暂存和生产,分别将它们添加到 和application-dev.yml文件application-prod.yml中。
创建一个名为 的 Java 文件,SplitConfig.java该文件将在 Spring Boot 应用程序中配置 Split 客户端。它创建了一个可用于依赖注入的 Spring Bean,并且由于 Bean 的默认行为是创建一个单例实例,因此这与 Split 自己的指导一致,建议只创建一个客户端实例。
src/main/java/com/split/coffeebot/config/SplitConfig.java
  1. @Configurationpublic class SplitConfig {
  2.     @Value("#{ @environment['split.api-key'] }")
  3.     private String splitApiKey;
  4.     @Bean
  5.     public SplitClient splitClient() throws Exception {
  6.         SplitClientConfig config = SplitClientConfig.builder()
  7.                 .setBlockUntilReadyTimeout(1000)
  8.                 .enableDebug()
  9.                 .build();
  10.         SplitFactory splitFactory = SplitFactoryBuilder.build(splitApiKey, config);
  11.         SplitClient client = splitFactory.client();
  12.         client.blockUntilReady();
  13.         return client;
  14.     }
  15. }
复制代码
你还需要向DrinkRepository. 它JPARepository为你提供了相当多的功能,无需任何自定义,但在这个应用程序中,你将需要一个自定义方法,该方法允许你从标准方法中排除一些饮料findAll()。该方法findByNameNotIn()是一个JPA查询方法,其语法和实现由Spring Boot提供。你所要做的就是定义方法以使其可供使用。有关更多信息,请参阅Spring Data JPA 查询方法的文档。
src/main/java/com/split/coffeebot/repository/DrinkRepository.java
  1. @SuppressWarnings("unused")  @Repository  public interface DrinkRepository extends JpaRepository<Drink, Long> {  
  2.     List<Drink> findByNameNotIn(Collection<String> names);  
  3. }
复制代码
现在创建一个CoffeeBotResource.java文件,其中包含 CoffeeBot 应用程序的业务逻辑和 REST 端点。
src/main/java/com/split/coffeebot/web/rest/CoffeeBotResource.java
  1. package com.split.coffeebot.web.rest;
  2. @RestController
  3. @RequestMapping("/api/coffee-bot")public class CoffeeBotResource {
  4.     private final Logger log = LoggerFactory.getLogger(CoffeeBotResource.class);
  5.     SplitClient splitClient;
  6.     DrinkRepository drinkRepository;
  7.     public CoffeeBotResource(SplitClient splitClient, DrinkRepository drinkRepository) {
  8.         this.splitClient = splitClient;
  9.         this.drinkRepository = drinkRepository;
  10.     }
  11.     private Drink makeDrink(String name, DrinkSize size, Integer caffeineMg, Integer price) {
  12.         Drink drink = new Drink();
  13.         drink.setCaffeineMilligrams(caffeineMg);
  14.         drink.setName(name);
  15.         drink.setSize(size);
  16.         drink.setPriceDollars(price);
  17.         return drink;
  18.     }
  19.     @EventListener
  20.     public void onApplicationEvent(ContextRefreshedEvent event) {
  21.         drinkRepository.save(makeDrink("Water", DrinkSize.Small, 0, 1));
  22.         drinkRepository.save(makeDrink("Soda", DrinkSize.Medium, 30, 3));
  23.         drinkRepository.save(makeDrink("Coffee", DrinkSize.XLarge, 50, 5));
  24.         drinkRepository.save(makeDrink("Coffee", DrinkSize.Small, 30, 3));
  25.         drinkRepository.save(makeDrink("Coffee", DrinkSize.Medium, 40, 3));
  26.         drinkRepository.save(makeDrink("Latte", DrinkSize.Large, 100, 8));
  27.         drinkRepository.save(makeDrink("Latte", DrinkSize.Small, 80, 6));
  28.         drinkRepository.save(makeDrink("Latte", DrinkSize.Medium, 60, 5));
  29.     }
  30.     @GetMapping("/list-drinks")
  31.     public List<Drink> listDrinks() {
  32.         Optional<String> userName = SecurityUtils.getCurrentUserLogin();
  33.         String treatment = splitClient.getTreatment(userName.get(),"drink-types");
  34.         if (treatment.equals("on")) {
  35.             return drinkRepository.findAll();
  36.         }
  37.         else {
  38.             return drinkRepository.findByNameNotIn(Arrays.asList("Latte", "Soda"));
  39.         }
  40.     }
  41. }
复制代码
和方法作为辅助方法,用于在应用程序启动时创建一些示例makeDrink()数据onApplicationEvent()(请记住,它使用的是内存数据库,不会在会话之间保留任何数据)。
该类使用 Spring 的依赖注入来使两个对象可用:DrinkRepository,这是自动创建的接口,定义应用程序如何操作实体(饮料);,SplitClient它是负责与 Split 通信并获取给定密钥和治疗名称的治疗的客户端。
你很快就会创建这种治疗方法。现在,请注意该getTreatment()方法至少需要两个参数。一种是文本键,它是任意字符串值,通常是用户名、帐户 ID 或用于区分用户的另一个唯一键。另一个是分割名称,它指定使用哪种处理来进行分割。
专业提示:可选的第三个getTreatment参数(我们在这里不会使用)是一个属性 映射对象,包含名称-值对中的用户属性。即使是敏感的用户数据也可以在此映射中传递,因为这些数据都不会发送到斯普利特的云。相反,属性映射会在本地内存中与你在拆分 UI 中输入的定位规则进行比较。更多内容请参见 Split SDK 文档:使用属性映射进行自定义定位。
如果治疗是on,它会返回所有可用的饮料。如果处理不是on(off或control或任何其他值),则返回除Latte和之外的所有饮料Soda。这演示了一种基于拆分来分叉代码的简单方法。更复杂的分割和治疗用例是可能的。
在你搬家之前,最后一项改变。打开SecurityConfiguration文件并允许api/coffee-bot资源路径上的所有流量。这将允许匿名用户获得饮料清单。
你要添加这一行:
  1. .antMatchers("/api/coffee-bot/**").permitAll()  代码语言: Bash  (bash )
复制代码
至configure(HttpSecurity http)方法。立场很重要。该行需要添加到该.antMatchers("/api/**").authenticated()行之前。
src/main/java/com/split/coffeebot/config/SecurityConfiguration.java
  1. @Overridepublic void configure(HttpSecurity http) throws Exception {
  2.     // @formatter:off
  3.     http
  4.     ...
  5.     .and()
  6.         .authorizeRequests()
  7.         .antMatchers("/api/authenticate").permitAll()
  8.         .antMatchers("/api/register").permitAll()
  9.         .antMatchers("/api/activate").permitAll()
  10.         .antMatchers("/api/account/reset-password/init").permitAll()
  11.         .antMatchers("/api/account/reset-password/finish").permitAll()
  12.         .antMatchers("/api/coffee-bot/**").permitAll()
  13.         .antMatchers("/api/**").authenticated()
  14.         .antMatchers("/management/health").permitAll()
  15.         .antMatchers("/management/info").permitAll()
  16.         .antMatchers("/management/prometheus").permitAll()
  17.         .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
  18.     ...
  19.     // @formatter:on
  20. }
复制代码
创建特征标志处理

如果你对治疗和 Split 不熟悉,你可能需要阅读Split 网站上的入门信息。简而言之,分割定义了一个决策点,一个标志,可以在代码中使用它来修改呈现给一组用户的功能。键(以及可选的属性映射)是根据拆分中定义的规则确定标志状态的值。这个决定是在运行时调用该方法时做出的。SplitClientgetTreatment()
在我们非常简单的示例中,你将创建一个名为Drink-types的拆分。这个分割将是一个简单的开/关分割,就像一个布尔标志(除了开和关之外,还可以有多个值)。分割将默认为off,但on如果admin用户在场,则分割将变为 。这是一个非常幼稚的例子。举个例子,在生产中,你可以根据用户群的一部分来定义这种划分,以在细分中推出新功能;或者,你可以先将功能仅提供给公共 Beta 测试人员,然后再将其发布给整个用户群。
打开拆分仪表板。你应该位于默认工作区中。
单击左侧的“拆分” 。
单击蓝色的“创建拆分”按钮。

为分割命名:drink-types。你可以将其余部分留空。
单击创建。

从环境下拉列表中选择暂存-默认。
单击添加规则按钮。
请注意,在定义处理部分下,定义了两个值:on和off。对于我们的用例来说,这非常棒。
在“创建单个目标”下,单击“添加目标”按钮。添加名为 的用户admin。这意味着用户admin将受到治疗on。
单击面板右上角的保存更改。
单击下一个面板上的“确认”以确认更改。
更新 Vue.js 客户端应用程序

客户端代码使用axios向资源服务器发出请求。你还需要安装 Split 模块依赖项。从项目根目录添加依赖项。
  1. npm install --save axios @splitsoftware/splitio@10.14.2
复制代码
更新home.component.ts文件以创建 CoffeeBot 应用程序。你需要为下面代码中的位置添加Javascript – staging-default键。const SPLIT_AUTH_KEY
src/main/webapp/app/core/home/home.component.ts
  1. import Component from 'vue-class-component';
  2. import { Inject, Vue, Watch } from 'vue-property-decorator';
  3. import LoginService from '@/account/login.service';
  4. import { SplitFactory } from '@splitsoftware/splitio';
  5. import { IClient } from '@splitsoftware/splitio/types/splitio';
  6. import axios from 'axios';const SPLIT_AUTH_KEY = <yourSplitAuthKey>;
  7. @Component
  8. export default class Home extends Vue {
  9.   @Inject('loginService')
  10.   private loginService: () => LoginService;
  11.   private splitClient: IClient = null;
  12.   // our list of drinks
  13.   private drinks = [];
  14.   // holds the drink that is the current order
  15.   private currentOrder = null;
  16.   // cream or no cream?
  17.   private withCream = false;
  18.   // the current Split.io treatment
  19.   private treatment = null;
  20.   public openLogin(): void {
  21.     this.loginService().openLogin((<any>this).$root);
  22.   }
  23.   public get authenticated(): boolean {
  24.     return this.$store.getters.authenticated;
  25.   }
  26.   public get username(): string {
  27.     return this.$store.getters.account ? this.$store.getters.account.login : '';
  28.   }
  29.   async getTreatment() {
  30.     // create a configured SplitFactory
  31.     const splitFactory = SplitFactory({
  32.       core: {
  33.         authorizationKey: SPLIT_AUTH_KEY,  // your Split.io auth key
  34.         key: this.username,  // identifier for this treatment (username in this case)
  35.         trafficType: 'user'
  36.       },
  37.       startup: {
  38.         readyTimeout: 1.5 // 1.5 sec
  39.       }
  40.     });
  41.     // create the split client (NOT READY TO USE YET)
  42.     this.splitClient = splitFactory.client();
  43.     // block untli the client is ready
  44.     this.splitClient.on(this.splitClient.Event.SDK_READY, function() {
  45.       // client is ready, get the treatment
  46.       this.treatment = this.splitClient.getTreatment('drink-types');
  47.     }.bind(this));
  48.   }
  49.   // triggered when username changes to update list
  50.   // of drinks and Split.io treatment
  51.   @Watch('username')
  52.   async usernameChanged(newVal: string, oldVal: String) {
  53.     // get treatment from split.io
  54.     await this.getTreatment();
  55.     // call the REST service to load drinks
  56.     await this.loadDrinks();
  57.         // clear the current order
  58.         this.currentOrder = null;
  59.   }
  60.   async loadDrinks() {
  61.     const response = await axios.get('http://localhost:8080/api/coffee-bot/list-drinks');
  62.     console.log(response);
  63.     if (response && response.status === 200) {
  64.       this.drinks = response.data;
  65.     }
  66.     else {
  67.       this.drinks = [];
  68.     }
  69.   }
  70.   async mounted() {
  71.     await this.getTreatment();
  72.     await this.loadDrinks();
  73.   }
  74.   beforeDestroy() {
  75.     this.splitClient.destroy();
  76.   }
  77. }
复制代码
该组件的身份验证部分是通过 JHipster 引导程序免费提供的。通过该方法从 Spring Boot 资源服务器加载数据loadDrinks(),该方法只是将饮料存储在本地数组中,巧妙地称为drinks. 当安装组件和用户更改时(因为可用的饮料取决于治疗,而治疗由用户决定),则会调用此方法。你可能会注意到此方法没有传递用户名。这是因为用户名会自动通过 JWT(JSON Web 令牌)传递到服务器,由 Spring Security 处理,身份验证代码由 JHipster 引导。
另一个重要的函数是usernameChanged()方法,当属性更改时调用该方法username。每次有新用户时,都需要创建新的 Split 客户端并重新加载处理。你还需要从服务器重新加载饮料。这个方法处理所有这些。
请注意此处的一般流程。首先,SplitFactory使用分割身份验证密钥和新用户名配置 a。该SplitFactory实例用于创建SplitClient实例。然而,客户此时不一定准备好。该代码会阻塞,直到SDK_READY事件被触发(参见下面的代码),然后才尝试从 获取处理SplitClient,否则它将仅返回control处理。
  1. // block until SDK is readythis.splitClient.on(this.splitClient.Event.SDK_READY, function () {
  2.   // ready now, so get treatment
  3.   this.treatment = this.splitClient.getTreatment('drink-types');
  4. }.bind(this))
复制代码
home.vue现在更新与该组件对应的模板文件。
src/main/webapp/app/core/home/home.vue
  1. <template>
  2.    
  3.         
  4.             
  5.                
  6.                     <h1 >CoffeeBot!</h1>
  7.                     <p >Drink coffee!</p>
  8.                     <p>{{username ? username : "anonymous"}}, treatment: {{treatment}}</p>
  9.                
  10.                
  11.                     <b-button variant="outline-primary"  @click="currentOrder=drink">{{drink.name}} {{drink.size}} - ${{drink.priceDollars}}</b-button>
  12.                
  13.                
  14.                     
  15.                         <b-button v-if="!withCream" variant="success"  @click="withCream=true">Add Cream - FREE</b-button>
  16.                         <b-button v-if="withCream" variant="danger"  @click="withCream=false">Remove Cream</b-button>
  17.                     
  18.                     
  19.                         <h4>Current order:</h4>
  20.                         
  21.                             {{currentOrder.name}} {{currentOrder.size}} {{withCream ? "(w/ cream)" : ""}} - ${{currentOrder.priceDollars}}
  22.                         
  23.                     
  24.                
  25.             
  26.         
  27.     </template>
  28.         ```
  29. 请注意,该文件使用 Vue 的条件语法根据处理状态有条件地渲染添加和删除奶油按钮。在这种情况下,即使组件中有一些与添加和删除奶油功能相关的代码未切换,这就是我们管理功能状态所需要做的全部工作。
复制代码
   Add Cream - FREE    Remove Cream```尝试完成的 Spring Boot + Vue.js 教程应用程序

你现在可以尝试完成的应用程序。启动或重新启动服务器和客户端。你可能希望在启动客户端之前让服务器完成启动。
Spring Boot Java 服务器:
  1. ./gradlew
复制代码
Vue.js 客户端:
  1. npm start
复制代码
客户端应用程序应自动打开。如果没有,请打开 http://localhost:9000
当你第一次加载应用程序时,你会看到用户是anonymous并且治疗是对照治疗。

使用默认管理员凭据 ( ) 登录admin:admin,你将看到扩展的饮料列表。当你添加一个饮料时,你会看到一个名为"Add Cream"的按钮。该按钮的可见性或功能可能受到名为"split treatment"的处理方式的控制。换句话说,根据某种分割处理的规则或逻辑,决定了是否显示或启用这个"Add Cream"按钮。

注销并以默认用户 ( user:user) 身份登录,你将看到处理方式,并且off你将获得与该用户相同的饮料列表anonymous。此外,你无法选择添加奶油。
了解有关 Spring Boot、功能标志和生产中测试的更多信息

在本教程中,你创建了一个全栈应用程序,其中包括 Vue.js 客户端和 Spring Boot 资源服务器。Vue.js 客户端使用 TypeScript 进行更现代、无错误的开发(因为如果使用得当,类型检查可以大大减少运行时错误)。Spring Boot 服务器使用 Spring Security 和 Spring JPA 等技术来快速轻松地定义数据模型(或实体),将该实体的实例保存到数据库,并在 REST 接口中提供该数据。
客户端和服务器都使用 JWT 身份验证来保护安全。Split用于实现功能标志,在服务器端使用Java SDK实现拆分,在客户端使用Javascript SDK实现拆分。
所有这一切都是使用 JHipster 引导的,这使得使用现代最佳实践和技术启动新的全栈项目变得非常容易。
你可以在Split 的示例 GitHub上找到所有设置的 JHipster 的完整源代码。
本文由博客群发一文多发等运营工具平台 OpenWrite 发布

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4