中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

注冊一個(gè)網(wǎng)站營銷團(tuán)隊(duì)找產(chǎn)品合作

注冊一個(gè)網(wǎng)站,營銷團(tuán)隊(duì)找產(chǎn)品合作,網(wǎng)站建設(shè)寫程序用什么軟件,網(wǎng)站建設(shè) 項(xiàng)目背景從 0 開始實(shí)現(xiàn)一個(gè) SpringBoot Vue 項(xiàng)目 從 0 開始實(shí)現(xiàn)一個(gè) SpringBoot Vue 項(xiàng)目 軟件和工具創(chuàng)建 SpringBoot 后端項(xiàng)目創(chuàng)建 MySQL 數(shù)據(jù)庫配置文件實(shí)現(xiàn)增刪改查接口 Model 層mapper 層service 層controller 層測試 實(shí)現(xiàn)項(xiàng)目功能接口 代碼測試 創(chuàng)建 Vue 前端 安裝 Node.js配置…
從 0 開始實(shí)現(xiàn)一個(gè) SpringBoot + Vue 項(xiàng)目
  • 從 0 開始實(shí)現(xiàn)一個(gè) SpringBoot + Vue 項(xiàng)目
    • 軟件和工具
    • 創(chuàng)建 SpringBoot 后端項(xiàng)目
    • 創(chuàng)建 MySQL 數(shù)據(jù)庫
    • 配置文件
    • 實(shí)現(xiàn)增刪改查接口
      • Model 層
      • mapper 層
      • service 層
      • controller 層
      • 測試
    • 實(shí)現(xiàn)項(xiàng)目功能接口
      • 代碼
      • 測試
    • 創(chuàng)建 Vue 前端
      • 安裝 Node.js
      • 配置 npm 鏡像
      • 安裝腳手架
      • 創(chuàng)建并配置項(xiàng)目
      • 項(xiàng)目結(jié)構(gòu)
      • Vue 組件結(jié)構(gòu)
      • Vue 組件調(diào)用與傳值
      • Vue 組件的生命周期
      • 測試 Vue 程序
      • 需求分析
    • 實(shí)現(xiàn)項(xiàng)目頁面
      • 框架搭建
      • 項(xiàng)目配置
      • 主界面設(shè)計(jì)
      • 設(shè)置路由
      • 內(nèi)容組件設(shè)計(jì)
      • 發(fā)送組件設(shè)計(jì)
      • 分頁面設(shè)計(jì)
        • 排行頁面 LikesSortedView.vue
        • 最新頁面 NewestView.vue
        • 隨機(jī)頁面 RandomView.vue
      • 項(xiàng)目啟動(dòng)
    • 源碼下載

從 0 開始實(shí)現(xiàn)一個(gè) SpringBoot + Vue 項(xiàng)目

參考:夢想屋A

軟件和工具

  • 后端開發(fā)軟件:IntelliJ IDEA
  • 前端開發(fā)軟件:Visual Studio Code
  • 后端框架:SpringBoot
  • 后端語言:Java
  • 前端框架:Vue

這是后面要用的妙妙小工具:

  • 服務(wù)器連接工具:Termius
  • 數(shù)據(jù)庫:MySQL
  • 數(shù)據(jù)庫管理工具:Navicat Premium
  • 數(shù)據(jù)庫連接工具:MyBatis
  • API 文檔生成工具:Swagger
  • API 文檔美化工具:Knife4j
  • UI 組件庫:Element
  • 網(wǎng)絡(luò)請求庫:Axios
  • 字體處理庫:Sfntly
  • JSON 處理工具:Fastjson
  • Java 工具庫:Lombok

可以不必全部用這些來做,有很多類似的產(chǎn)品可以替代。

創(chuàng)建 SpringBoot 后端項(xiàng)目

首先我們打開 IDEA,點(diǎn)擊新建項(xiàng)目,選擇 Spring Initializr,然后在右側(cè)填寫項(xiàng)目名稱,類型選擇 Maven,JDK 版本選擇1.8,如下圖所示,然后點(diǎn)擊下一步。

在這里插入圖片描述

在新的頁面中選擇 SpringBoot 版本 3.0.2,引入一些依賴,點(diǎn)擊創(chuàng)建。

在這里插入圖片描述

后面在 pom.xml 中把 Java 版本改回 1.8,SpringBoot 版本改回 2.7.6。

項(xiàng)目結(jié)構(gòu):

在這里插入圖片描述

可以看到 SpringBoot 的基礎(chǔ)結(jié)構(gòu)有三個(gè)文件:

  • src/main/java 下的程序入口:DreamHouseApplication
  • src/main/resources 下的配置文件:application.properties
  • src/test 下的測試入口:DreamHouseApplicationTests

在運(yùn)行類 DreamHouseApplication 同級目錄下創(chuàng)建 controller、service、mapper、model 四個(gè)目錄:

在這里插入圖片描述

controller 層:控制層

  • 作用是請求和響應(yīng)控制。
  • 負(fù)責(zé)前后端交互,接受前端請求,調(diào)用 service 層,接收 service 層返回的數(shù)據(jù),最后返回具體的頁面和數(shù)據(jù)到客戶端。

service 層:業(yè)務(wù)邏輯層

  • 作用是完成功能設(shè)計(jì)。
  • 調(diào)用 mapper 層接口,接收 mapper 層返回的數(shù)據(jù),完成項(xiàng)目的基本功能設(shè)計(jì)。

mapper 層:數(shù)據(jù)持久層,也被稱為 dao 層

  • 作用是訪問數(shù)據(jù)庫,向數(shù)據(jù)庫發(fā)送 sql 語句,完成數(shù)據(jù)的增刪改查任務(wù)。

model 層:數(shù)據(jù)庫實(shí)體層,也被稱為 entity 層、pojo 層

  • 用于存儲數(shù)據(jù)庫中的數(shù)據(jù),類屬性與數(shù)據(jù)庫表字段對應(yīng)。
  • 通常情況下,Model 層使用 ORM(對象關(guān)系映射)技術(shù),如 JPA,MyBatis 等與數(shù)據(jù)庫進(jìn)行交互。

在項(xiàng)目目錄中的 pom.xml 配置文件中引入本次項(xiàng)目中需要用到的相關(guān)依賴:

        <!--MyBatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.0</version></dependency><!--Swagger3--><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><!--knife4j--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-ui</artifactId><version>3.0.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><!--JSON--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.15</version></dependency><!--MySQL--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.31</version><scope>runtime</scope></dependency><!--Lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>

將這些依賴放到標(biāo)簽內(nèi),就接著 SpringBoot 自帶的一些依賴下面就行了。

稍微解釋一下這些依賴:

  • Lombok:可以通過注解的方式為 Java 類生成許多常用的方法,例如 getter、setter、toString、equals 等,省去了手寫這些方法的代碼。

  • Swagger:開源的 API 文檔生成工具,可以根據(jù)代碼中的注釋自動(dòng)生成 API 文檔。

  • Knife4j:用來美化 Swagger 生成的 API 文檔。

  • MyBatis:持久層框架,主要用于簡化數(shù)據(jù)庫操作,提高代碼可讀性,降低數(shù)據(jù)訪問代碼的維護(hù)難度,提高效率。

  • MySQL:MySQL 官方提供的 Java 用的 JDBC 驅(qū)動(dòng),它允許 Java 程序通過 JDBC API 連接到 MySQL 數(shù)據(jù)庫。

  • JSON:用來將 json 數(shù)據(jù)序列化和反序列化的,主要是覺得 SpringBoot 自帶的 json 工具不好用。

創(chuàng)建 MySQL 數(shù)據(jù)庫

安裝 MySQL 這里就不講了,這里用 Navicat Premium 連接數(shù)據(jù)庫。

填寫連接名、主機(jī)IP、端口、用戶名和密碼等,然后點(diǎn)擊連接。

在這里插入圖片描述

可以先點(diǎn)測試連接,顯示連接成功,在點(diǎn)確定。

連接上數(shù)據(jù)庫之后,新建數(shù)據(jù)庫–>新建表–>添加 id、ip、province、time、str、likes 六個(gè)字段。

表名為 dream,具體內(nèi)容如下所示:

在這里插入圖片描述

這里有兩個(gè)細(xì)節(jié):

  1. id 要設(shè)置自動(dòng)遞增
  2. likes 設(shè)置為無符號

友情鏈接:mysql自增navicat_navicat怎么設(shè)置主鍵自增

配置文件

讓我們回到 SpringBoot,打開剛剛介紹到的配置文件 application.properties 進(jìn)行項(xiàng)目配置:

server.port = 8087spring.mvc.pathmatch.matching-strategy = ant_path_matcher# Swagger
swagger.enabled = true# MySQL
spring.datasource.url = jdbc:mysql:(服務(wù)器IP地址):3306/(數(shù)據(jù)庫名)
spring.datasource.username = (用戶名)
spring.datasource.password = (密碼)
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver

稍微解釋一下:

  • server.port:指定項(xiàng)目使用 8087 端口,默認(rèn) 8080 端口。

  • spring.mvc.pathmatch.matching-strategy:指定 Spring MVC 框架中 URL 路徑匹配策略的實(shí)現(xiàn)類的類名,ant_path_matcher 是一種路徑匹配策略,使用 Ant 風(fēng)格的通配符來匹配 URL 路徑。

  • swagger.enabled:啟用 Swagger 工具。

  • spring.datasource.url:指定 MySQL 數(shù)據(jù)庫的 URL。這里的服務(wù)器 IP 地址就是主機(jī)名,我的是 localhost(前面要帶//),數(shù)據(jù)庫名是 dreamhouse,完整格式:jdbc:mysql://localhost:3306/dreamhouse。

  • spring.datasource.username:指定連接 MySQL 數(shù)據(jù)庫使用的用戶名。我的是 root。

  • spring.datasource.password:指定連接 MySQL 數(shù)據(jù)庫使用的密碼。

  • spring.datasource.driver-class-name:指定連接 MySQL 數(shù)據(jù)庫使用的 JDBC 驅(qū)動(dòng)程序的類名。

這里可能會有注釋中文亂碼問題,在設(shè)置中可以解決,全部換成 UTF-8:

在這里插入圖片描述

友情鏈接:【SpringBoot2】讀取配置application.properties文件亂碼問題解決

第一次用要安裝點(diǎn)驅(qū)動(dòng)啥的,點(diǎn)一下就安裝好了,沒截到圖。

配置好以后,可以測試連接:

在這里插入圖片描述

也可以在 IDEA 看到數(shù)據(jù)庫:

在這里插入圖片描述

實(shí)現(xiàn)增刪改查接口

Model 層

回顧一下 model 層:數(shù)據(jù)庫實(shí)體層,也被稱為 entity 層、pojo 層

  • 用于存儲數(shù)據(jù)庫中的數(shù)據(jù),類屬性與數(shù)據(jù)庫表字段對應(yīng)。
  • 通常情況下,Model 層使用 ORM(對象關(guān)系映射)技術(shù),如 JPA,MyBatis 等與數(shù)據(jù)庫進(jìn)行交互。

在 model 目錄下新建 Data 類:

package com.example.dream_house.model;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.model* @Author:Uestc_Xiye* @CreateTime:2023-12-17 16:29:49*/@lombok.Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("數(shù)據(jù)庫字段")
public class Data {@ApiModelProperty(value = "信息所屬ID", required = true, example = "1")private int id;@ApiModelProperty(value = "信息來源IP地址", required = true, example = "127.0.0.1")private String ip;@ApiModelProperty(value = "信息來源所屬省份", required = true, example = "廣東")private String province;@ApiModelProperty(value = "內(nèi)容發(fā)布時(shí)間", required = true, example = "2023-12-17 16:58:00")private String time;@ApiModelProperty(value = "夢想內(nèi)容", required = true, example = "環(huán)游世界!")private String str;@ApiModelProperty(value = "點(diǎn)贊數(shù)", required = true, example = "52")private int likes;
}

接下來說一下這段代碼中的各個(gè)注解的作用:

  • @lombok.Data:這是 Lombok 框架提供的注解,它會自動(dòng)生成 getter、setter、toString、equals、hashCode 等方法。使用該注解可以簡化代碼,并提高開發(fā)效率。

  • @NoArgsConstructor:這也是 Lombok 提供的注解,它會生成一個(gè)無參構(gòu)造器,可以避免手動(dòng)編寫無參構(gòu)造器。這個(gè)注解常用于一些框架或工具的實(shí)例化。

  • @AllArgsConstructor:同樣是 Lombok 提供的注解,它會生成一個(gè)全參構(gòu)造器,可以避免手動(dòng)編寫全參構(gòu)造器。這個(gè)注解也常用于一些框架或工具的實(shí)例化。

  • @ApiModel:這是 Swagger 框架提供的注解,用于描述一個(gè)模型類。這個(gè)注解的作用是將模型類描述為一個(gè) API 文檔的模型,可以通過該注解指定模型類的名稱和描述信息。

  • @ApiModelProperty:也是 Swagger 框架提供的注解,用于描述模型類中的屬性信息。該注解可以設(shè)置屬性的名稱、描述、是否必需等信息,以便在 Swagger 生成的 API 文檔中顯示。

    • value:屬性的描述信息,用于在 API 文檔中顯示該屬性的作用。

    • required:屬性是否必需。當(dāng)該值為 true 時(shí),表示該屬性必須包含在請求中;當(dāng)該值為 false 時(shí),表示該屬性可以為空或者不包含在請求中。

    • example:屬性的示例值。用于在 API 文檔中顯示該屬性的樣例值,方便開發(fā)者理解該屬性的類型和取值范圍。

mapper 層

回顧一下 mapper 層:數(shù)據(jù)持久層,也被稱為 dao 層

  • 作用是訪問數(shù)據(jù)庫,向數(shù)據(jù)庫發(fā)送 sql 語句,完成數(shù)據(jù)的增刪改查任務(wù)。

在 mapper 目錄下新建 DataMapper 接口:

package com.example.dream_house.mapper;import com.example.dream_house.model.Data;
import org.apache.ibatis.annotations.*;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.mapper* @Author:Uestc_Xiye* @CreateTime:2023-12-17 16:36:57*/@Mapper
public interface DataMapper {/*** 信息來源IP地址* @param ip* 信息來源省份* @param province* 信息發(fā)出時(shí)間* @param time* 信息內(nèi)容* @param str* 點(diǎn)贊數(shù)* @param likes** @return*/@Insert("insert into dream (ip, province, time, str, likes) values(#{ip}, #{province}, #{time}, #{str}, #{likes})")int insert(@Param("ip") String ip,@Param("province") String province,@Param("time") String time,@Param("str") String str,@Param("likes") int likes);/*** 信息id* @param id** @return** property屬性對應(yīng)Data對象中的成員名,column對應(yīng)select出的字段名。*/@Results({@Result(property = "id", column = "id"),@Result(property = "ip", column = "ip"),@Result(property = "province", column = "province"),@Result(property = "time", column = "time"),@Result(property = "str", column = "str"),@Result(property = "likes", column = "likes")})@Select("select * from dream where id = #{id}")Data findById(@Param("id") int id);/*** 用Data對象來作為傳參,這樣語句中的#{id}、#{ip}等數(shù)據(jù)就分別對應(yīng)Data對象中的id和ip等屬性。** @param data*/@Update("update dream set ip=#{ip}, province=#{province}, time=#{time}, str=#{str}, likes=#{likes} where id=#{id}")void update(Data data);/*** 刪除該id對應(yīng)的信息** @param id*/@Delete("delete from dream where id =#{id}")void delete(int id);}

相關(guān)注解的作用:

  • @Mapper:是 MyBatis 框架提供的注解,用于標(biāo)記一個(gè) Java 接口,該接口用于定義數(shù)據(jù)訪問方法。在使用 @Mapper 注解后,MyBatis 會自動(dòng)掃描該接口,為其創(chuàng)建一個(gè)代理對象。該代理對象可以將接口方法與 MyBatis 的 SQL 映射文件中的 SQL 語句進(jìn)行綁定,并完成數(shù)據(jù)訪問的操作。

  • @Insert:也是 MyBatis 框架提供的注解,該注解的值為 SQL 語句,用于指定插入操作的具體邏輯。該 SQL 語句使用了預(yù)處理語句,從而避免了 SQL 注入的問題。

  • @Param:

    • /** */中的內(nèi)容是 JavaDoc(Java文檔注釋),它用于對方法進(jìn)行說明、描述和文檔化。

    • 在方法中的 @Param 注解用于指定參數(shù)的名稱,以便在 SQL 語句中使用相應(yīng)的占位符。

  • @Results:用于定義從查詢結(jié)果集中將查詢結(jié)果映射為 Java 對象的過程。

  • @Select:同樣是 MyBatis 框架提供的注解,該注解的值為 SQL 語句,用于指定查詢操作的具體邏輯。

  • @Update:MyBatis 框架提供的注解,用于指定更新操作的 SQL 語句。

  • @Delete:MyBatis 框架提供的注解,用于指定刪除操作的 SQL 語句。

service 層

簡單回顧一下 service 層:業(yè)務(wù)邏輯層

  • 作用是完成功能設(shè)計(jì)。
  • 調(diào)用 mapper 層接口,接收 mapper 層返回的數(shù)據(jù),完成項(xiàng)目的基本功能設(shè)計(jì)。

在 service 目錄下新建 DataService 類:

package com.example.dream_house.service;import com.example.dream_house.mapper.DataMapper;
import com.example.dream_house.model.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.service* @Author:Uestc_Xiye* @CreateTime:2023-12-17 17:04:45*/@Service
public class DataService {@Autowiredprivate DataMapper dataMapper;/*** 新增信息** @param ip* @param province* @param time* @param str* @param likes* @return*/public String insert(String ip, String province, String time, String str, int likes) {dataMapper.insert(ip, province, time, str, likes);return "succeed";}/*** 查詢id對應(yīng)的信息** @param id* @return*/public Data findById(int id) {return dataMapper.findById(id);}/*** 更新信息** @param data*/public void update(Data data) {dataMapper.update(data);}/*** 刪除id對應(yīng)的信息** @param id*/public void delete(int id) {dataMapper.delete(id);}
}

相關(guān)注解的作用:

  • @Service:用于標(biāo)注一個(gè)類為 Spring 框架中的一個(gè)服務(wù)類,該類中通常包含了業(yè)務(wù)邏輯的實(shí)現(xiàn)。使用該注解可以使 Spring 框架自動(dòng)掃描并將該類實(shí)例化,并將其作為服務(wù)類注冊到容器中,以供其他組件使用。當(dāng)我們需要在其他類中使用該服務(wù)類時(shí),只需要通過依賴注入的方式獲取該類的實(shí)例即可。

  • @Autowired:用于實(shí)現(xiàn) Spring 框架中的自動(dòng)裝配功能,將需要使用的 Bean 對象注入到指定的屬性中。通過使用該注解,可以避免手動(dòng)創(chuàng)建 Bean 實(shí)例和手動(dòng)注入對象的麻煩。

controller 層

簡單回顧一下 controller 層:控制層

  • 作用是請求和響應(yīng)控制。
  • 負(fù)責(zé)前后端交互,接受前端請求,調(diào)用 service 層,接收 service 層返回的數(shù)據(jù),最后返回具體的頁面和數(shù)據(jù)到客戶端。

在 controller 目錄下新建 DataController 類:

package com.example.dream_house.controller;import com.example.dream_house.model.Data;
import com.example.dream_house.service.DataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.controller* @Author:Uestc_Xiye* @CreateTime:2023-12-17 17:17:36*/@Api(tags = "API接口")
@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
public class DataController {@Autowiredprivate DataService dataService;@ApiOperation("添加完整信息")@PostMapping("/insert")public String insert(@RequestBody Data data) {// @RequestBody注解用來綁定通過http請求中application/json類型上傳的數(shù)據(jù)return dataService.insert(data.getIp(), data.getProvince(), data.getTime(), data.getStr(), data.getLikes());}@ApiOperation("查詢id對應(yīng)的信息")@GetMapping("/findById/{id}")public Data findById(@PathVariable int id) {return dataService.findById(id);}@ApiOperation("更新信息")@PutMapping("/update")public void update(@RequestBody Data data) {dataService.update(data);}@ApiOperation("刪除指定id的信息")@DeleteMapping("/delete/{id}")public void deleteUser(@PathVariable int id) {dataService.delete(id);}}

相關(guān)注解的作用:

  • @Api:Swagger 的注解之一,用于對 API 接口進(jìn)行注釋和說明。tags 屬性是 Swagger 文檔中的一個(gè)重要屬性,可以用來將 API 接口進(jìn)行分類,方便管理和查找。

  • @RestController:Spring MVC 中的注解之一,用于標(biāo)識該類是一個(gè)基于 RESTful 風(fēng)格的 Web 服務(wù)類。

  • @CrossOrigin:Spring 中的一個(gè)注解,用于支持跨域請求。跨域請求通常指在一個(gè)域名下的頁面中使用 AJAX 技術(shù)向不同的域名或端口號的 Web 服務(wù)發(fā)送請求。

  • @ApiOperation:Swagger 的注解之一,用于對 API 接口中的具體操作進(jìn)行注釋和說明。

  • @PostMapping:Spring MVC 中的注解之一,表示該方法接收 POST 請求。

  • @RequestBody:Spring MVC 中的注解之一,表示該方法接收的請求參數(shù)為請求體中的數(shù)據(jù)。

  • @GetMapping:Spring MVC 中的注解之一,表示該方法接收 GET 請求。

  • @PathVariable:Spring MVC 中的注解之一,表示該方法接收的請求參數(shù)為路徑參數(shù)。

  • @PutMapping:Spring MVC 中的注解之一,表示該方法接收 PUT 請求。

  • @DeleteMapping:Spring MVC 中的注解之一,表示該方法接收 DELETE 請求。

這里要引入 Spring Web,不然在使用這些注解的時(shí)候報(bào)錯(cuò)無法解析。

在這里插入圖片描述

測試

預(yù)先設(shè)置一些數(shù)據(jù)庫內(nèi)容:

在這里插入圖片描述

在把上面的四層架構(gòu)都處理完之后,我們直接啟動(dòng)項(xiàng)目。

運(yùn)行 DreamHouseApplication,或者運(yùn)行它的 main 方法。

踩坑 1:Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstre

切換“跳過測試”模式:

在這里插入圖片描述

友情鏈接:解決:Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstre

踩坑點(diǎn)2:Consider defining a bean of type ‘com.example.dream_house.mapper.DataMapper’ in your configuration.

18:10:27.233 [Thread-1] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@6d1a5149.   ____          _            __ _ _/\ / ___'_ __ _ _(_)_ __  __ _    

( ( )___ | '_ | '| | ’ / ` |
/ )| |)| | | | | || (| | ) ) ) )
’ |
| .__|| ||| |, | / / / /
=========|
|==============|
/=///_/
:: Spring Boot :: (v2.7.6)

2023-12-17 18:10:27.843  INFO 11824 --- [  restartedMain] c.e.dream_house.DreamHouseApplication    : Starting DreamHouseApplication using Java 1.8.0_192 on LAPTOP-P25TKBR2 with PID 11824 (C:Users81228DocumentsProgramJava ProjectDreamHousedream_house	argetclasses started by 81228 in C:Users81228DocumentsProgramJava ProjectDreamHousedream_house)
2023-12-17 18:10:27.844  INFO 11824 --- [  restartedMain] c.e.dream_house.DreamHouseApplication    : No active profile set, falling back to 1 default profile: "default"
2023-12-17 18:10:27.975  INFO 11824 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2023-12-17 18:10:27.975  INFO 11824 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2023-12-17 18:10:29.551  WARN 11824 --- [  restartedMain] o.m.s.mapper.ClassPathMapperScanner      : No MyBatis mapper was found in '[com.example.dream_house]' package. Please check your configuration.
2023-12-17 18:10:30.264  INFO 11824 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8087 (http)
2023-12-17 18:10:30.265  INFO 11824 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : An older version [1.2.24] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum version of [1.2.30]
2023-12-17 18:10:30.265  INFO 11824 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : Loaded Apache Tomcat Native library [1.2.24] using APR version [1.7.0].
2023-12-17 18:10:30.265  INFO 11824 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [false].
2023-12-17 18:10:30.265  INFO 11824 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2023-12-17 18:10:30.283  INFO 11824 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 1.1.1g  21 Apr 2020]
2023-12-17 18:10:30.295  INFO 11824 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-12-17 18:10:30.295  INFO 11824 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.69]
2023-12-17 18:10:30.507  INFO 11824 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-12-17 18:10:30.507  INFO 11824 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2531 ms
2023-12-17 18:10:30.645  WARN 11824 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataController': Unsatisfied dependency expressed through field 'dataService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataService': Unsatisfied dependency expressed through field 'dataMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.dream_house.mapper.DataMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2023-12-17 18:10:30.651  INFO 11824 --- [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-12-17 18:10:30.679  INFO 11824 --- [  restartedMain] ConditionEvaluationReportLoggingListener : Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-12-17 18:10:30.751 ERROR 11824 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : ***************************
APPLICATION FAILED TO START
***************************Description:Field dataMapper in com.example.dream_house.service.DataService required a bean of type 'com.example.dream_house.mapper.DataMapper' that could not be found.The injection point has the following annotations:- @org.springframework.beans.factory.annotation.Autowired(required=true)Action:Consider defining a bean of type 'com.example.dream_house.mapper.DataMapper' in your configuration.

解決方法:在 dataService.java 的 private DataMapper dataMapper; 的上面的@Autowired 改成 @Autowired(required = false)。

在這里插入圖片描述

友情鏈接:Consider defining a bean of type問題解決

運(yùn)行成功后,在瀏覽器中訪問 http://127.0.0.1:8087/doc.html 頁面,該頁面是 Swagger 生成的 API 文檔經(jīng)過 knife4j 美化過后的 API 文檔頁面。

在這里插入圖片描述

點(diǎn)擊左側(cè)的 “API接口” 可以看到出現(xiàn)了四個(gè)熟悉的接口,就是我們剛剛寫的 “增刪改查” 對應(yīng)的接口,該 API 文檔的好處就是可以在線對接口進(jìn)行測試。

首先測試添加接口,依次點(diǎn)擊并填寫數(shù)據(jù)信息:

在這里插入圖片描述

然后點(diǎn)擊發(fā)送,看到響應(yīng)內(nèi)容 succeed 說明添加成功了:

在這里插入圖片描述

我們前往 Navicat Premium 查看數(shù)據(jù)庫內(nèi)容有沒有變化,刷新一下頁面,可以看到在最下面的數(shù)據(jù)出現(xiàn)了我們剛剛添加進(jìn)去的內(nèi)容:

在這里插入圖片描述

其次測試查詢接口,依次點(diǎn)擊并填寫 id 信息,然后點(diǎn)擊發(fā)送。

可以看到響應(yīng)內(nèi)容成功拿到數(shù)據(jù):

在這里插入圖片描述

然后測試更新接口,依次點(diǎn)擊并填寫信息,然后點(diǎn)擊發(fā)送:

在這里插入圖片描述

由于沒有設(shè)置返回值,所以響應(yīng)內(nèi)容為空。

我們直接去看數(shù)據(jù)庫的內(nèi)容變化,刷新一下數(shù)據(jù)庫,可以看到該條數(shù)據(jù)已經(jīng)發(fā)生了變化:

在這里插入圖片描述

最后測試刪除接口,點(diǎn)擊并填寫 id 信息,然后點(diǎn)擊發(fā)送:

在這里插入圖片描述

由于沒有設(shè)置返回值,所以還是直接前往數(shù)據(jù)庫查看,刷新數(shù)據(jù)庫,發(fā)現(xiàn) id 為 4 的這條數(shù)據(jù)不見了,說明接口沒問題:

在這里插入圖片描述

經(jīng)過測試,“增刪改查”四個(gè)接口全部都能夠正常使用。

實(shí)現(xiàn)項(xiàng)目功能接口

上面詳細(xì)介紹了編寫 “增刪改查” 四個(gè)接口,下面給出其他項(xiàng)目功能接口。

代碼

model 層之前寫的一個(gè) Data 的實(shí)體類就繼續(xù)保留,我們再增加一個(gè) getUser 類,用來作為前端從接口獲取到的信息的類。

原理與 Data 類相同,這里就不再進(jìn)行講解了,直接上代碼:

package com.example.dream_house.model;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.model* @Author:Uestc_Xiye* @CreateTime:2023-12-17 22:25:14*/@lombok.Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("獲取信息內(nèi)容")
public class getUser {@ApiModelProperty(value = "信息所屬ID", required = true, example = "1")private int id;@ApiModelProperty(value = "信息來源所屬省份", required = true, example = "湖北")private String province;@ApiModelProperty(value = "夢想內(nèi)容", required = true, example = "環(huán)游世界")private String str;@ApiModelProperty(value = "點(diǎn)贊數(shù)", required = true, example = "52")private int likes;}

其實(shí)就是 Data 類去掉了 ip 和 time。

mapper 層我們需要在 DataMapper 接口中添加新的內(nèi)容,新增的方法有:

  • 查詢點(diǎn)贊數(shù)前 50 名的信息。
  • 查詢最新的 50 條信息。
  • 查詢隨機(jī)的 50 條信息。
  • 更新指定 id 的點(diǎn)贊數(shù) + 1。
  • 更新指定 id 的點(diǎn)贊數(shù) - 1。

方法的原理還是與之前相同,只是改變了 SQL 語句。

    /*** 查詢點(diǎn)贊數(shù)前50名的信息*/@Results({@Result(property = "id", column = "id"),@Result(property = "province", column = "province"),@Result(property = "str", column = "str"),@Result(property = "likes", column = "likes")})@Select("SELECT * FROM dream ORDER BY likes DESC LIMIT 50")List<getUser> findByLikes();/*** 查詢最新的50條信息*/@Results({@Result(property = "id", column = "id"),@Result(property = "province", column = "province"),@Result(property = "str", column = "str"),@Result(property = "likes", column = "likes")})@Select("SELECT * FROM dream ORDER BY time DESC LIMIT 50")List<getUser> findByTime();/*** 查詢隨機(jī)的50條信息*/@Results({@Result(property = "id", column = "id"),@Result(property = "province", column = "province"),@Result(property = "str", column = "str"),@Result(property = "likes", column = "likes")})@Select("SELECT * FROM dream ORDER BY rand() DESC LIMIT 50")List<getUser> findByRand();/*** 更新指定id的點(diǎn)贊數(shù)+1*/@Update("UPDATE dream SET likes = likes + 1 WHERE id = #{id}")void increaseLikesById(int id);/*** 更新指定id的點(diǎn)贊數(shù)-1*/@Update("UPDATE dream SET likes = likes - 1 WHERE id = #{id}")void decreaseLikesById(int id);

service 層在這里增加的內(nèi)容比較多,因?yàn)槭菢I(yè)務(wù)邏輯層,需要完成功能設(shè)計(jì)。

首先在 service 目錄下新建 getIP、getProvince、getTime 三個(gè)類,分別用來獲取用戶 IP 地址、用戶所在省份、內(nèi)容發(fā)送時(shí)間。

getIP 類代碼如下,可以從用戶的請求頭中篩選出用戶真實(shí)的IP地址:

package com.example.dream_house.service;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.service* @Author:Uestc_Xiye* @CreateTime:2023-12-18 09:12:22*/
public class getIP {public String getIp(HttpServletRequest request, HttpServletResponse response) {response.setContentType("text/html;charset=utf-8");// 設(shè)置響應(yīng)頭允許ajax跨域訪問,星號表示所有的異域請求都可以接受response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "GET,POST");return getIpAddr(request);}public String getIpAddr(HttpServletRequest request) {// 獲取請求頭"x-forwarded-for"對應(yīng)的valueString ip = request.getHeader("x-forwarded-for");// 如果獲取的ip值為空if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {// 則獲取請求頭"Proxy-Client-IP"對應(yīng)的valueip = request.getHeader("Proxy-Client-IP");}// 如果獲取的ip值仍為空if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {//則獲取請求頭"WL-Proxy-Client-IP"對應(yīng)的valueip = request.getHeader("WL-Proxy-Client-IP");}// 如果以上方式獲取的ip值都為空if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {//則直接獲取ip地址ip = request.getRemoteAddr();}// 返回ip地址return ip;}
}

getProvince 類代碼如下,可以調(diào)用外部 API 來檢測出用戶 ip 地址所屬的省份:

package com.example.dream_house.service;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.service* @Author:Uestc_Xiye* @CreateTime:2023-12-18 09:23:34*/
public class getProvince {/*** @param ip* @return*/public String get_Province(String ip) {// 設(shè)置api的urlString url = "https://ip.useragentinfo.com/json?ip=" + ip;RestTemplate template = new RestTemplate();// 發(fā)起一個(gè)HTTP GET請求,獲取指定URL的響應(yīng)實(shí)體,String.class表示要獲取的響應(yīng)實(shí)體的類型是字符串類型ResponseEntity<String> response = template.getForEntity(url, String.class);// 將Spring類型轉(zhuǎn)換為JSON類型JSONObject json = JSON.parseObject(response.getBody());// 取出json中的數(shù)據(jù)String province = json.getString("province");return province;}
}

getTime 類代碼如下,直接調(diào)用 Java 自帶的包就行:

package com.example.dream_house.service;import java.text.SimpleDateFormat;
import java.util.Date;/*** @BelongsProject:dream_house* @BelongsPackage:com.example.dream_house.service* @Author:Uestc_Xiye* @CreateTime:2023-12-18 09:29:50*/
public class getTime {public String get_Time() {// 設(shè)置日期格式SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 獲取當(dāng)前系統(tǒng)時(shí)間String date = simpleDateFormat.format(new Date());return date;}
}

接下來修改 DataService 類的內(nèi)容,需要新增以下方法:

    /*** 獲取用戶數(shù)據(jù)并調(diào)用mapper層上傳數(shù)據(jù)庫** @param request* @param response* @param str* @return*/public String Add(HttpServletRequest request, HttpServletResponse response, String str) {getIP getIP = new getIP();getProvince getProvince = new getProvince();getTime getTime = new getTime();// 獲取信息的IP地址String ip = getIP.getIp(request, response);// 獲取信息所屬省份String province = getProvince.get_Province(ip);// 獲取當(dāng)前時(shí)間String time = getTime.get_Time();// 設(shè)置當(dāng)前點(diǎn)贊數(shù)為0int currentLikes = 0;// 上傳數(shù)據(jù)dataMapper.insert(ip, province, time, str, currentLikes);return "succeed";}/*** 查詢點(diǎn)贊數(shù)排名前50的信息** @return*/public List<getUser> findByLikes() {return dataMapper.findByLikes();}/*** 查詢最新的50條信息** @return*/public List<getUser> findByTime() {return dataMapper.findByTime();}/*** 查詢隨機(jī)的50條信息** @return*/public List<getUser> findByRand() {return dataMapper.findByRand();}/*** 更新指定id對應(yīng)的點(diǎn)贊數(shù)+1** @param id* @return*/public String increaseLikesById(int id) {dataMapper.increaseLikesById(id);return "succeed";}/*** 更新指定id對應(yīng)的點(diǎn)贊數(shù)-1** @param id* @return*/public String decreaseLikesById(int id) {dataMapper.decreaseLikesById(id);return "succeed";}

controller 層需要新增以下接口:

    @ApiOperation("上傳信息接口")@PostMapping("/Add/{str}")public String Add(HttpServletRequest request, HttpServletResponse response, @PathVariable String str) {return dataService.Add(request, response, str);}@ApiOperation("查詢點(diǎn)贊數(shù)前50名的信息")@GetMapping("/findByLikes")public List<getUser> findByLikes() {return dataService.findByLikes();}@ApiOperation("查詢最新的50條信息")@GetMapping("/findByTime")public List<getUser> findByTime() {return dataService.findByTime();}@ApiOperation("查詢隨機(jī)的50條信息")@GetMapping("/findByRand")public List<getUser> findByRand() {return dataService.findByRand();}@ApiOperation("更新指定id對應(yīng)的點(diǎn)贊數(shù)+1")@PutMapping("/increaseLikesById/{id}")public String increaseLikesById(@PathVariable int id) {return dataService.increaseLikesById(id);}@ApiOperation("更新指定id對應(yīng)的點(diǎn)贊數(shù)-1")@PutMapping("/decreaseLikesById/{id}")public String decreaseLikesById(@PathVariable int id) {return dataService.decreaseLikesById(id);}
測試

啟動(dòng)項(xiàng)目,訪問 API 文檔頁面 http://127.0.0.1:8087/doc.html,可以看到我們編寫的接口都在這里:

在這里插入圖片描述

發(fā)現(xiàn)問題:上傳信息接口無效。

原因是 service 層的 get_Province 函數(shù)中的:

String url = "https://ip.useragentinfo.com/json?ip=" + ip;

我們?nèi)?https://ip.useragentinfo.com 這個(gè)網(wǎng)址看看:

在這里插入圖片描述

查詢一下,確實(shí)能用,但是和代碼里的不同,注意這里的網(wǎng)址:

在這里插入圖片描述

我們把代碼改一下:

String url = "https://ip.useragentinfo.com/?ip=" + ip;

還是不行,原因是這個(gè)網(wǎng)站已經(jīng)不支持帶參數(shù)查詢了(悲)。

我們只能按下面的方法修改 get_IP、getIpAddr 和 getProvince 函數(shù)。

友情鏈接:java實(shí)現(xiàn)獲取IP及歸屬地

其他測試了都沒什么大問題。

有個(gè)小問題就是,測試上傳信息接口的時(shí)候,是能上傳,但是 IP 地址是 0:0:0:0:0:0:0:0:1。

在這里插入圖片描述

友情鏈接:手把手教你用Java獲取IP歸屬地

這里面說,在本地環(huán)境調(diào)用獲取 IP,要么是 0:0:0:0:0:0:0:1,或者是局域網(wǎng)IP。

局域網(wǎng)IP是以192.168.x.x開頭,或者是127.0.0.1的IP。

所以需要部署到外網(wǎng)服務(wù)器才能獲取到公網(wǎng)地址,部署到外網(wǎng)服務(wù)器才能成功獲取 IP 地址。

再查了一下,在本地測試時(shí),這個(gè)是無解的。

要是在局域網(wǎng)中運(yùn)行,訪問時(shí)使用本身的 IP 訪問。這時(shí)候請求會通過路由器轉(zhuǎn)發(fā),因此服務(wù)器獲取的就是本機(jī)的局域網(wǎng)內(nèi) IP,在 Java 中獲取的 IP 就是局域網(wǎng) IP,不是 localhost 或者 127.0.0.1 這種東西。

友情鏈接:java獲取IP為0:0:0:0:0:0:0:1的情況

詳細(xì)解釋:

0:0:0:0:0:0:0:1是屬于 ipv6,后來我又進(jìn)行另一臺電腦做測試,發(fā)現(xiàn)這種情況只有在服務(wù)器和客戶端都在同一臺電腦上才會出現(xiàn)(例如用 localhost 訪問的時(shí)候才會出現(xiàn)),這是hosts配置文件的問題。

友情鏈接:

  1. request.getRemoteAddr()獲取ip地址時(shí)得到的值是[0:0:0:0:0:0:0:1]原因和解決方法
  2. 查詢本地ip地址為0:0:0:0:0:0:0:1

總結(jié):

因?yàn)殡娔X優(yōu)先把 localhost 解析成了 IPv6,用 localhost 測試,返回 IPv6 地址,get_Province 能解析到省份。

用 127.0.0.1 測試,返回本機(jī) IPv4 地址,get_Province 不能解析到省份,是“本機(jī)地址”。

在這里插入圖片描述

創(chuàng)建 Vue 前端

安裝 Node.js

Node.js 簡介:Node.js 入門 | 青訓(xùn)營筆記

官網(wǎng)下載安裝:https://nodejs.org/zh-cn/

調(diào)出終端,輸入指令 node -v,顯示版本號說明 node 安裝好了。

輸入指令 npm -v,顯示版本號,說明 npm 可以正常使用。

在這里插入圖片描述

配置 npm 鏡像

npm 默認(rèn)的倉庫地址在國外,訪問速度較慢,我們切換成國內(nèi)的淘寶鏡像。

輸入指令安裝:npm install -g cnpm --registry=https://registry.npm.taobao.org

在這里插入圖片描述

輸入指令 cnpm -v,顯示版本號說明 cnpm 安裝好了。

在這里插入圖片描述

前端代碼在 Visual Studio Code 上寫,在它上面再測一下:

在這里插入圖片描述

安裝腳手架

終端輸入指令 cnpm i -g @vue/clinpm i -g @vue/cli 全局安裝。

安裝細(xì)節(jié)很長,這樣就算成功了:

在這里插入圖片描述

創(chuàng)建并配置項(xiàng)目

在任意位置新建一個(gè)文件夾用來放置項(xiàng)目。

終端中通過 cd 指令跳轉(zhuǎn)到這個(gè)文件夾(我這里已經(jīng)到項(xiàng)目文件夾了)。

輸入指令 vue create dream_house 創(chuàng)建項(xiàng)目。

  • 上下鍵:表示選擇
  • 回車鍵:表示確認(rèn)

選擇 Manually select features 手動(dòng)配置。

在這里插入圖片描述

選擇需要安裝的插件,勾選如下插件,按空格鍵選擇:

在這里插入圖片描述

  • Babel:解析 es6 轉(zhuǎn) es5 的插件
  • TypeScript:TypeScript 插件
  • Progressive Web App (PWA) Support:漸進(jìn)式 Web 應(yīng)用程序(PWA)支持
  • Router:vue 路由插件
  • Vuex:Vuex 插件
  • CSS Pre-processors:css 預(yù)處理插件
  • Linter/Formatter:格式化程序
  • Unit Testing:單元測試
  • E2E Testing:端到端(end-to-end)

回車(Enter)確認(rèn)。

版本選擇:選 2.x。

在這里插入圖片描述

路由模式:選擇是否為 history 模式,y 表示是,n 表示使用 hash 模式,這里選擇的是 n。

  • history:利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法(需要特定瀏覽器支持)
    *hash: 瀏覽器 url 址欄中的 # 符號(如這個(gè) URL:http://love.byzy.love/#/SuiJi ,hash 的值為“ #/SuiJi ”),hash 不被包括在 HTTP 請求中,所以對后端完全沒有影響。因此改變 hash 不會重新加載頁面,更容易進(jìn)行打包上傳服務(wù)器。

在這里插入圖片描述

選擇 CSS 預(yù)處理器:選第一個(gè)

在這里插入圖片描述

選擇編碼規(guī)則:

  • ESLint with error prevention only:只配置使用 ESLint 官網(wǎng)的推薦規(guī)則

  • ESLint + Airbnb config:官網(wǎng)推薦的規(guī)則 + Airbnb 第三方的配置

  • ESLint + Standard config:使用 ESLint 官網(wǎng)推薦的規(guī)則 + Standard 第三方的配置

  • ESLint + Prettier:使用 ESLint 官網(wǎng)推薦的規(guī)則 + Prettier 第三方的配置

在這里插入圖片描述

建議初學(xué)者(就是我)選擇第一項(xiàng),表示只有報(bào)錯(cuò)時(shí)才會驗(yàn)證。

檢測條件:

  • Lint on save:保存就檢測

  • Lint and fix on commit:fix 和 commit 時(shí)候檢查

在這里插入圖片描述

選 Lint on save。

存放配置:

  • In dedicated config files:獨(dú)立文件放置
  • In package.json:放 package.json 里

選 In package.json。

最后輸入 y:

在這里插入圖片描述

保存配置并命名:

在這里插入圖片描述

包管理器就選 npm:

在這里插入圖片描述

等下載完成,顯示出如下界面說明配置完成:

在這里插入圖片描述

輸入指令 cd dream_house 進(jìn)入項(xiàng)目。

項(xiàng)目結(jié)構(gòu)

Visual Studio Code 打開項(xiàng)目文件夾,觀察左側(cè)項(xiàng)目目錄。

項(xiàng)目結(jié)構(gòu)說明如下:

  • node_modules: 包含所有安裝的 npm 包。
  • public:包含所有不需要經(jīng)過 Webpack 處理的靜態(tài)文件,如:index.html、favicon.ico等。
    • favicon.ico
    • index.html
  • src:包含所有源代碼
    • assets:存放靜態(tài)資源文件,如圖片、樣式表等
      • logo.png
    • components:存放 Vue 組件
      • HelloWorld.vue
    • router:存放 Vue 路由
      • index.js
    • store:存放 Vuex 狀態(tài)管理相關(guān)的代碼
      • index.js
    • views:存放頁面級別的 Vue 組件
      • AboutView.vue
      • HomeView.vue
    • App.vue:Vue應(yīng)用程序的根組件
    • main.js:Vue應(yīng)用程序的入口文件
  • .gitignore:Git 忽略文件列表,告訴 Git 哪些文件和目錄應(yīng)該被忽略,不被納入版本控制中。
  • babel.config.js:Babel 配置文件,用于轉(zhuǎn)換 ES6+ 代碼到 ES5,以便它們能夠在更舊的瀏覽器中運(yùn)行。
  • jsconfig.json:用于配置 Vusial Studio Code 的 JavaScript 語言服務(wù)的 JSON 配置文件。它可以用來設(shè)置JS項(xiàng)目的編譯選項(xiàng)、路徑別名、自動(dòng)引入模塊等選項(xiàng)。
  • package-lock.json:記錄當(dāng)前項(xiàng)目的依賴項(xiàng)及其版本信息,確保不同計(jì)算機(jī)或者環(huán)境下的依賴項(xiàng)保持一致。
  • package.json:Vue.js 項(xiàng)目的元數(shù)據(jù)文件,包含項(xiàng)目的名稱、版本、作者、依賴項(xiàng)等信息。其中,dependencies 字段記錄的是項(xiàng)目的運(yùn)行時(shí)依賴項(xiàng),而 devDependencies 字段記錄的是項(xiàng)目的開發(fā)時(shí)依賴項(xiàng)。
  • README.md:項(xiàng)目的說明文檔,描述項(xiàng)目的目的、功能、使用方法等等。
  • vue.config.js:Vue.js 項(xiàng)目的配置文件,包含了一些 Vue CLI 的默認(rèn)配置,可以用于自定義 Webpack 配置、開發(fā)環(huán)境的代理設(shè)置等等。使用 vue-cli-service 命令時(shí),它將自動(dòng)被加載并應(yīng)用于項(xiàng)目配置。
Vue 組件結(jié)構(gòu)

一個(gè) Vue 組件分為三個(gè)部分,分別是:template 部分、script 部分、style 部分。

  • template:組件的模板部分,用來定義組件的 html 結(jié)構(gòu)。
    必須在里面放置一個(gè) html 標(biāo)簽來包裹所有的代碼,例如
    標(biāo)簽。
  • script:組件的 JavaScript 代碼部分,用來定義組件的邏輯和屬性。
  • style:組件的樣式部分,它用來定義組件的樣式。
Vue 組件調(diào)用與傳值

我們就從官方的例子中來理解 Vue 組件間的傳值與調(diào)用。由于 HelloWorld.vue 中的內(nèi)容過多,所以我進(jìn)行了刪減。

觀察下面的兩段 Vue 代碼。

HomeView.vue:

<template><div class="home"><img alt="Vue logo" src="../assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js App"/></div>
</template><script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'export default {name: 'HomeView',components: {HelloWorld}
}
</script>

HelloWorld.vue:

<template><div class="hello"><h1>{{ msg }}</h1></div>
</template><script>
export default {name: 'HelloWorld',props: {msg: String}
}
</script>

可以看到 HomeView.vue 組件中 template 部分有一個(gè) HelloWorld 標(biāo)簽,這個(gè)就是我們自定義的 HelloWorld 組件,在這個(gè)標(biāo)簽中,我們將一串字符串賦值給 msg 傳遞了過去。

在 script 部分中,使用 ES6 的 import 語法引入了 “@/components/HelloWorld.vue” 文件,并將其賦值給 HelloWorld 變量。

  • export default:使用 ES6 的 export 語法導(dǎo)出一個(gè)默認(rèn)的對象,該對象包含了組件的各種屬性和方法。

  • name:定義了組件的名稱,可以在代碼中用來引用這個(gè)組件。

  • components:定義了組件所包含的子組件。在這里,我們將 HelloWorld 子組件注冊為了 HomeView 組件的一個(gè)子組件,以便在 HomeView 組件的模板中使用 HelloWorld 組件。

接下來看 HelloWorld.vue 組件中的 script 部分,我們可以看到 props 屬性,這個(gè)屬性定義了該組件的數(shù)據(jù)屬性,也就是它的輸入。在這里,我們定義了一個(gè)名為 msg 的屬性,它是一個(gè)字符串類型。該屬性可以從組件外部傳遞進(jìn)來,在組件內(nèi)部使用。

然后在 template 部分,

{{ msg }}

調(diào)用了該值。

Vue 組件的生命周期

Vue組件的生命周期是指在組件實(shí)例化時(shí),從開始到結(jié)束,不同階段會自動(dòng)執(zhí)行的一些函數(shù)。Vue提供了一些鉤子函數(shù),讓我們在這些生命周期階段執(zhí)行我們的自定義邏輯。Vue組件的生命周期可以分為以下三個(gè)階段:

  1. 創(chuàng)建階段:包括組件實(shí)例化、數(shù)據(jù)觀測、模板編譯和掛載等過程。
    具體的生命周期函數(shù)有:

    • beforeCreate:在實(shí)例初始化之后,數(shù)據(jù)觀測和事件配置之前被調(diào)用,此時(shí)data和methods 等組件屬性還未初始化。

    • created:在實(shí)例創(chuàng)建完成后被立即調(diào)用,此時(shí) data 和 methods 等組件屬性已經(jīng)初始化,但是 DOM 節(jié)點(diǎn)還未掛載。

    • beforeMount:在掛載開始之前被調(diào)用,此時(shí)模板已經(jīng)編譯完成,但是還未渲染成 DOM。

    • mounted:在掛載完成后被調(diào)用,此時(shí)組件已經(jīng)掛載到 DOM 上,可以進(jìn)行 DOM 操作和異步數(shù)據(jù)請求等操作。

  2. 更新階段:更新階段包括數(shù)據(jù)更新和重新渲染等過程。
    具體的生命周期函數(shù)有:

    • beforeUpdate:在數(shù)據(jù)更新之前被調(diào)用,此時(shí)組件還未重新渲染。

    • updated:在數(shù)據(jù)更新之后被調(diào)用,此時(shí)組件已經(jīng)重新渲染。

  3. 銷毀階段:銷毀階段包括組件銷毀和清理等過程。
    具體的生命周期函數(shù)有:

    • beforeDestroy:在實(shí)例銷毀之前被調(diào)用,此時(shí)組件還未銷毀,可以進(jìn)行一些清理工作。

    • destroyed:在實(shí)例銷毀之后被調(diào)用,此時(shí)組件已經(jīng)完全銷毀,不再可用。

在組件的生命周期中,我們可以使用這些生命周期函數(shù)來執(zhí)行一些初始化、清理和動(dòng)態(tài)更新等操作。例如,在 created 生命周期函數(shù)中可以發(fā)起異步請求獲取數(shù)據(jù),在 beforeDestroy 生命周期函數(shù)中可以清理定時(shí)器或取消訂閱等操作。

測試 Vue 程序

我們先看看默認(rèn)的 Vue 程序如何運(yùn)行。

第一步:npm install

在這里插入圖片描述

第二步:npm run serve

在這里插入圖片描述

第三步:打開瀏覽器,進(jìn)入 http://localhost:8080/

在這里插入圖片描述

友情鏈接:如何運(yùn)行vue項(xiàng)目(超詳細(xì)圖解)

需求分析

整理需求:

  1. 一個(gè)導(dǎo)航欄
  2. 三個(gè)頁面
  3. 頁面中顯示每個(gè)用戶發(fā)出的內(nèi)容
  4. 可以給內(nèi)容點(diǎn)贊
  5. 可以發(fā)送內(nèi)容
  6. 先把整體頁面的框架模型搭建起來,然后再進(jìn)行修飾

在了解了需求之后,就可以開始動(dòng)手操作了。

實(shí)現(xiàn)項(xiàng)目頁面

框架搭建

在 views 目錄下新建 LikesSortedView.vue、NewestView.vue、RandomView.vue。

在 components 目錄下新建 UserList.vue、InputText.vue。

在這里插入圖片描述

LikesSortedView.vue、NewestView.vue、RandomView.vue 三個(gè)組件作為三個(gè)頁面,內(nèi)容包括所有的 UserList.vue 組件排列起來。

UserList.vue 組件作為單個(gè)用戶發(fā)送的內(nèi)容,上面顯示省份與點(diǎn)贊等內(nèi)容。

InputText.vue 組件作為發(fā)送內(nèi)容的組件,包括一個(gè)輸入框和一個(gè)發(fā)送按鈕。

項(xiàng)目配置

我們需要把項(xiàng)目運(yùn)行端口更改一下,不然默認(rèn)是 8080 端口。在 vue.config.js 文件中更改:

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer: {port: 8086, // 此處修改你想要的端口號},})

然后在項(xiàng)目中我們會用到 Axios 以及 Element ,所以需要下載相關(guān)依賴并在 main.js 中引入。

  • 安裝 Axios 指令:npm install axios

  • 安裝 Element 指令:npm install element-ui。

安裝好以后,修改 main.js:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'import ElementUI from 'element-ui';                      // 引入element-ui
import 'element-ui/lib/theme-chalk/index.css';           // element-ui的css樣式要單獨(dú)引入import axios from 'axios'Vue.prototype.$axios = axiosVue.use(ElementUI);Vue.config.productionTip = falsenew Vue({router,store,render: h => h(App)
}).$mount('#app')
主界面設(shè)計(jì)

主頁面的設(shè)計(jì)在根組件 App.vue 中進(jìn)行,主要負(fù)責(zé)一些全局內(nèi)容的顯示。

在 template 部分為一個(gè)標(biāo)題,一個(gè)導(dǎo)航欄,一個(gè) InputText 組件,一條每頁都需要顯示的提示文字。

<template><div id="app"><h1 class="MyName">Dream House</h1><nav><router-link to="/">排行</router-link> |<router-link to="/Newest">最新</router-link> |<router-link to="/Random">隨機(jī)</router-link></nav><router-view /><InputText /><div class="newText">該列表僅顯示50條內(nèi)容!</div></div>
</template>

在 script 部分引入 InputText.vue 組件。

<script>
import InputText from '@/components/InputText.vue'export default {name: 'App',components: {InputText},
}
</script>

在 style 部分設(shè)置該組件的樣式,以及一些全局效果。

<style lang="scss">
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}nav {padding: 20px;font-size: 30px;font-family: pyt;text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2);a {text-decoration: none;font-weight: bold;color: #2c3e50;&.router-link-exact-active {-webkit-tap-highlight-color: transparent; //清除藍(lán)框text-decoration: none;color: #42b983;}}
}.MyName {font-family: pyt;font-size: 60px;background-clip: text;-webkit-background-clip: text;-webkit-text-fill-color: transparent;background-image: linear-gradient(to right, #41ffa9, rgba(79, 168, 252, 0.6));margin: 20px 10px 0px 10px;text-shadow: 3px 3px 3px rgba(0, 0, 0, 0.2); //文本陰影
}
body {background: rgb(244, 189, 255);background: linear-gradient(90deg,rgb(183, 180, 255) 0%,rgb(255, 255, 255) 50%,rgb(165, 240, 255) 100%);
}// 設(shè)置全局滾動(dòng)條
body::-webkit-scrollbar {width: 5px;background-color: #f5f5f5;
}body::-webkit-scrollbar-thumb {border-radius: 10px;-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);background-color: #c4ffe4;
}.newText {height: 80px;margin: 10px auto;font-size: 13px;
}
</style>
設(shè)置路由

在 router 目錄下的 index.js 中設(shè)置路由:

import Vue from 'vue'
import VueRouter from 'vue-router'Vue.use(VueRouter)const routes = [{path: '/',name: '排行',component: () => import('../views/LikesSortedView.vue')},{path: '/Newest',name: '最新',// route level code-splitting// this generates a separate chunk (Newest.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/NewestView.vue')},{path: '/Random',name: '隨機(jī)',component: () => import('../views/RandomView.vue')}
]const router = new VueRouter({routes
})export default router
內(nèi)容組件設(shè)計(jì)

UserList.vue 的 template 部分如下,顯示一個(gè)主要內(nèi)容,在左下角顯示省份,右下角顯示點(diǎn)贊數(shù)和一個(gè)圖片按鈕。

<template><div class="UserList"><div class="box"><div class="box1"><div class="str">{{str}}</div></div><div class="box2"><div class="province">{{province}}</div><div class="likes">{{likes}}</div><img:src="imagePath"@click="toggleImage"class="img-btn"/></div></div></div>
</template>

style 部分如下,設(shè)置對應(yīng)的標(biāo)簽顯示的位置,以及樣式等。

<!-- 添加“scoped作用域”屬性以將 CSS 限制為此組件 -->
<style scoped lang="scss">
.UserList {display: flex;justify-content: center;align-items: center;
}.box {border: 1px solid #ddd;border-radius: 10px;box-shadow: 2px 2px 4px #ddd;padding: 10px;display: flex;flex-direction: column; //將 flex 子元素沿豎直方向排列align-items: center; //將 flex 子元素在縱軸上居中對齊margin: 5px;width: 500px;transition: all 0.3s ease; //面板放大
}.box:hover {transform: scale(1.04); //面板放大
}.box1 {width: 100%;float: left;margin: 5px;
}.str {flex: 1;text-align: center;font-size: 20px;//font-family:wpyt;width: 100%;height: 25px;display: flex;justify-content: center;align-items: center;text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2);
}.box2 {width: 100%;display: flex;
}.province {text-align: center;font-size: 14px;width: 120px;height: 20px;display: flex;
}.likes {text-align: center;font-size: 14px;width: 100px;height: 20px;margin: auto 5px auto auto;display: flex;justify-content: flex-end;align-items: center;
}.img-btn {width: 16px;height: 16px;transition: all 0.3s ease; // 設(shè)置按鈕元素的過渡效果
}
</style>

script 部分如下,獲取從上級頁面?zhèn)鱽淼臄?shù)據(jù),在 created() 鉤子函數(shù)中判斷是否給這個(gè)內(nèi)容點(diǎn)過贊,并將圖片按鈕初始化。

<script>
import axios from 'axios'export default {name: 'UserList',props: {Obj: Object},data() {return {imagePath: require("@/assets/點(diǎn)贊-no.png"),str: this.Obj.str,province: this.Obj.province,likes: this.Obj.likes};},created() {if (localStorage.getItem(`isLiked${this.Obj.id}`)) {this.imagePath = require("@/assets/點(diǎn)贊-yes.png");}},methods: {toggleImage() {// 判斷是否點(diǎn)贊過if (this.imagePath === require("@/assets/點(diǎn)贊-no.png")) {// 獲取按鈕元素const imgBtn = this.$el.querySelector('.img-btn');// 給按鈕元素應(yīng)用縮放和旋轉(zhuǎn)的樣式imgBtn.style.transform = 'scale(1.2) rotate(-10deg)';// 設(shè)置計(jì)時(shí)器,在 300 毫秒之后給按鈕元素應(yīng)用新的樣式setTimeout(() => {imgBtn.style.transform = 'scale(1) rotate(10deg)';setTimeout(() => {imgBtn.style.transform = 'scale(1) rotate(0deg)';}, 300);}, 300);this.likes++;// 將圖片替換為已點(diǎn)贊的圖片this.imagePath = require("@/assets/點(diǎn)贊-yes.png");// 將已點(diǎn)贊的狀態(tài)存入 localStoragelocalStorage.setItem(`isLiked${this.Obj.id}`, true);//向服務(wù)器發(fā)送發(fā)送put請求axios.put(`http://localhost:8087/increaseLikesById/${this.Obj.id}`).then(res => {console.log(res.data);}).catch(error => {console.log("點(diǎn)贊出錯(cuò)!")console.error(error);});} else {this.likes--;// 否則將圖片替換為未點(diǎn)贊的圖片this.imagePath = require("@/assets/點(diǎn)贊-no.png");// 并且刪除已點(diǎn)贊的狀態(tài)localStorage.removeItem(`isLiked${this.Obj.id}`);// 向服務(wù)器發(fā)送發(fā)送put請求axios.put(`http://localhost:8087/decreaseLikesById/${this.Obj.id}`).then(res => {console.log(res.data);}).catch(error => {console.log("取消點(diǎn)贊出錯(cuò)!")console.error(error);});}}}}
</script>

按鈕綁定 toggleImage() 函數(shù),通過點(diǎn)擊按鈕觸發(fā)此函數(shù),觸發(fā)圖片按鈕的動(dòng)作,以及更換圖片,并且向服務(wù)器發(fā)出 put 請求,更新數(shù)據(jù)庫中的數(shù)據(jù),更新頁面中顯示的數(shù)據(jù)。

assets 文件夾下要放圖片:

在這里插入圖片描述

友情鏈接:阿里巴巴矢量圖標(biāo)庫

發(fā)送組件設(shè)計(jì)

InputText.vue 的 template 部分如下,只有一個(gè)輸入框以及一個(gè)圖片按鈕。

<template><div class="InputText"><inputtype="text"maxlength="15"v-model="inputValue"placeholder="發(fā)送你的夢想!"/><imgsrc="../assets/send.png"class="submit-btn"/></div>
</template>

style 部分如下,依然是設(shè)置整個(gè)發(fā)送組件的樣式。

<style scoped lang="scss">
.InputText {position: fixed;bottom: 10px;left: 0;right: 0;display: flex;justify-content: space-between;padding: 10px;background-color: transparent;width: 300px;margin: 0 auto;//設(shè)置 z-index 值為 999,顯示為最頂部z-index: 999;
}input[type="text"] {flex: 1;height: 40px;padding: 0 10px;background-color: rgba(255, 255, 255, 0.7);border: 1px solid transparent;border-radius: 20px;box-shadow: 0 0 10px #42b983;transition: all 0.3s ease-in-out;
}input[type="text"]:hover {transform: scale(1.05);box-shadow: 0 0 15px rgba(24, 144, 255, 0.8);
}.submit-btn {height: 40px;padding: 2px 0px 0px 10px;background-color: transparent;border: none;cursor: pointer;transform: scale(1);transition: all 0.3s ease-in-out;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}.submit-btn:hover {transform: scale(1.2);
}
</style>

script 部分如下,通過點(diǎn)擊按鈕觸發(fā) submit() 函數(shù),播放按鈕的動(dòng)畫,以及獲取輸入框的內(nèi)容,發(fā)送到服務(wù)器上。

<script>
import axios from 'axios'export default {name: 'InputText',// 定義數(shù)據(jù)data() {return {isAnimating: false, // 用于標(biāo)識動(dòng)畫是否正在播放inputValue: ''};},methods: {// 定義提交方法submit() {// 如果動(dòng)畫正在播放,直接返回if (this.isAnimating) return;//向服務(wù)器發(fā)送發(fā)送post請求axios.post(`http://localhost:8087/Add/${this.inputValue}`).then(res => {console.log(res.data);this.inputValue = '';this.$message({message: '發(fā)送成功!',type: 'success',duration: 2000 // 自動(dòng)關(guān)閉延遲時(shí)間,單位毫秒});}).catch(error => {this.$message({message: '發(fā)送失敗!',type: 'error',duration: 2000 // 自動(dòng)關(guān)閉延遲時(shí)間,單位毫秒});console.log("發(fā)送信息出錯(cuò)!")console.error(error);});this.isAnimating = true; // 標(biāo)記動(dòng)畫正在播放// 獲取提交按鈕元素const btn = this.$el.querySelector(".submit-btn");// 記錄提交按鈕的原始 transform 值const originalTransform = btn.style.transform;// 設(shè)置提交按鈕的 transform 值,使其向右上方移動(dòng)btn.style.transform = "translate(100%, -100%)";// 設(shè)置動(dòng)畫播放完成后的回調(diào)函數(shù)setTimeout(() => {// 將提交按鈕的 transform 值設(shè)置為原始值btn.style.transform = originalTransform;// 標(biāo)記動(dòng)畫已經(jīng)播放完畢this.isAnimating = false;}, 500);}},mounted() {// 在組件掛載完成后,給提交按鈕元素綁定 click 事件this.$el.querySelector(".submit-btn").addEventListener("click", this.submit);}
};
</script>

assets 文件夾下要放圖片:

在這里插入圖片描述

分頁面設(shè)計(jì)

三個(gè)分頁面的作用是向數(shù)據(jù)庫發(fā)出請求,獲取到內(nèi)容數(shù)據(jù),再調(diào)用內(nèi)容組件將各個(gè)內(nèi)容排列顯示在頁面上。

排行頁面 LikesSortedView.vue

template 部分如下,在該部分中只使用了一個(gè)自定義組件 UserList ,使用 Vue 的模板語法動(dòng)態(tài)的生成一個(gè)組件列表。

<template><div class="PaiHang"><UserListv-for="(item, index) in Obj":key="index":Obj="item"/></div>
</template>

解釋:

  • v-for="(item, index) in Obj"指令表示對 Obj 對象進(jìn)行遍歷,生成對應(yīng)數(shù)量的 組件。

  • :key="index"屬性用于標(biāo)識每個(gè)組件的唯一性,使 Vue 能夠更高效地管理組件的狀態(tài)。

  • :Obj="item"屬性將當(dāng)前元素的值 item 傳遞給 組件,作為組件的參數(shù)之一。

script 部分如下,在該頁面被初始化的的時(shí)候會調(diào)用 getList() 方法從服務(wù)器拿到數(shù)據(jù),然后將 json 數(shù)據(jù)傳入對應(yīng)的 UserList 組件中。

<script>
// @ 是 /src 的別名
import UserList from '@/components/UserList.vue'
import axios from 'axios'export default {name: 'LikesSortedView',components: {UserList},data() {return {Obj: []}},// computed會緩存結(jié)果,methods每次都會重新計(jì)算methods: {getList() {let list = [];let newObjects = {};axios.get('http://localhost:8087/findByLikes').then(res => {list = res.data;for (let i = 0; i < list.length; i++) {newObjects[i] = list[i];}console.log(newObjects);this.Obj = newObjects;}).catch(error => {this.$message({message: '獲取頁面內(nèi)容失敗!',type: 'error',duration: 2000});console.log("獲取排行出錯(cuò)!")console.error(error);});}},created() {this.getList();}}
</script>
最新頁面 NewestView.vue

最新頁面基本上與排行頁面相同,唯一不同的地方就是請求的參數(shù)不同,所以只需要把請求的 url 改一下就行了,改成 API 定義的對應(yīng)的接口。

url:http://(接口IP地址):8087/findByTime

然后就是本組件的名字需要改一下。

<template><div class="Newest"><UserListv-for="(item, index) in Obj":key="index":Obj="item"/></div></template><script>// @ 是 /src 的別名import UserList from '@/components/UserList.vue'import axios from 'axios'export default {name: 'NewestView',components: {UserList},data() {return {Obj: []}},// computed會緩存結(jié)果,methods每次都會重新計(jì)算methods: {getList() {let list = [];let newObjects = {};axios.get('http://localhost:8087/findByTime').then(res => {list = res.data;for (let i = 0; i < list.length; i++) {newObjects[i] = list[i];}console.log(newObjects);this.Obj = newObjects;}).catch(error => {this.$message({message: '獲取頁面內(nèi)容失敗!',type: 'error',duration: 2000});console.log("獲取排行出錯(cuò)!")console.error(error);});}},created() {this.getList();}}</script>  
隨機(jī)頁面 RandomView.vue

同理,改一下請求的 url 就行。

url:http://(接口IP地址):8087/findByRand

<template><div class="Random"><UserListv-for="(item, index) in Obj":key="index":Obj="item"/></div></template><script>// @ 是 /src 的別名import UserList from '@/components/UserList.vue'import axios from 'axios'export default {name: 'RandomView',components: {UserList},data() {return {Obj: []}},// computed會緩存結(jié)果,methods每次都會重新計(jì)算methods: {getList() {let list = [];let newObjects = {};axios.get('http://localhost:8087/findByRand').then(res => {list = res.data;for (let i = 0; i < list.length; i++) {newObjects[i] = list[i];}console.log(newObjects);this.Obj = newObjects;}).catch(error => {this.$message({message: '獲取頁面內(nèi)容失敗!',type: 'error',duration: 2000});console.log("獲取排行出錯(cuò)!")console.error(error);});}},created() {this.getList();}}</script>
項(xiàng)目啟動(dòng)

在終端中輸入指令:npm run serve。

可以看到如下界面,說明項(xiàng)目成功運(yùn)行:

在這里插入圖片描述

根據(jù)提示訪問本地地址 http://localhost:8086/。

在這里插入圖片描述

發(fā)現(xiàn)所有功能都正常使用,頁面正常排布。

經(jīng)測試,點(diǎn)贊按鈕和發(fā)送按鈕動(dòng)畫正常播放,頁面數(shù)據(jù)正常更新,夢想內(nèi)容正常發(fā)布,各功能使用正常。

至此,“夢想屋” 小項(xiàng)目成功完成。

源碼下載

GitHub:https://github.com//DreamHouse

CSDN:DreamHouse.zip

http://www.risenshineclean.com/news/44212.html

相關(guān)文章:

  • wordpress獲取指定目錄的文章百度網(wǎng)站排名優(yōu)化
  • 裝飾公司網(wǎng)站seo公司排名教程
  • 公司網(wǎng)站建設(shè)行業(yè)怎么樣老鬼seo
  • 網(wǎng)站維護(hù)需要多少錢全網(wǎng)引流推廣
  • 中國電商建站程序seo運(yùn)營是做什么的
  • 個(gè)人做網(wǎng)站需要備案嗎bt兔子磁力天堂
  • 用什么軟件做網(wǎng)站最快搜索量排行
  • 桂林做網(wǎng)站公司seo網(wǎng)絡(luò)優(yōu)化
  • 日照網(wǎng)站制作seo診斷站長
  • 博客網(wǎng)站如何建設(shè)互聯(lián)網(wǎng)推廣渠道
  • 做飛機(jī)票預(yù)訂網(wǎng)站如何做網(wǎng)站推廣的策略
  • 做彩票生意要登陸哪個(gè)網(wǎng)站百度最怕哪個(gè)投訴電話
  • 上海 網(wǎng)站制作公司網(wǎng)絡(luò)建站工作室
  • 有什么做服裝的網(wǎng)站蘭州seo網(wǎng)站建設(shè)
  • div css網(wǎng)站邊框模板疫情防控最新政策
  • 網(wǎng)站建設(shè)公司的公眾號百度官網(wǎng)平臺
  • 網(wǎng)站制作需要哪些軟件有哪些網(wǎng)站宣傳推廣策劃
  • 上海做網(wǎng)站 公司關(guān)鍵詞排名優(yōu)化怎么做
  • 舟山建設(shè)信息港門戶網(wǎng)站seo網(wǎng)絡(luò)推廣技術(shù)員招聘
  • 成都疫情實(shí)時(shí)狀況seo搜索優(yōu)化 指數(shù)
  • 外管局網(wǎng)站上做預(yù)收登記廊坊seo
  • 網(wǎng)站安全如何做百度 營銷推廣多少錢
  • tomcat做網(wǎng)站站長之家查詢的網(wǎng)址
  • 十堰微網(wǎng)站建設(shè)淘寶自動(dòng)推廣軟件
  • 淘寶客做的比較好的網(wǎng)站友情鏈接有哪些作用
  • 網(wǎng)站中的圖片必須用 做嗎網(wǎng)站建設(shè)純免費(fèi)官網(wǎng)
  • 個(gè)人網(wǎng)站怎么建設(shè)關(guān)鍵詞分為哪幾類
  • 網(wǎng)站策劃怎么做內(nèi)容環(huán)球軍事網(wǎng)
  • 網(wǎng)站制作怎樣做背景常用的網(wǎng)絡(luò)推廣方法有
  • 旅游網(wǎng)站建設(shè)系統(tǒng)百度一下官網(wǎng)頁