學習筆記-DAY01-VUE
文章目錄
前言
第一次嘗試在網路上寫筆記,不夠成熟,暫時只為了以後能及時翻查而寫
一、Vue中的鉤子函式&監聽&方法的呼叫時機?
- 鉤子(create):頁面載入時發請求(重新整理)
- 監聽(watch):是被監聽的欄位又發生改變的時候傳送請求
- 方法(method): 不發請求,而是等待被呼叫
二、點選上一頁、下一頁後重新整理,頁面依舊可以跳回當前頁,而非首頁
大致思路:在監聽函式watch中記錄當前的頁數:page,把page放到位址列,保證位址列的值與searchParam(data中的引數,儲存位址列"?"後面的資料)是一致的:
searchParams: {
key: "",
page: 1,
filterParams: {}
},
鉤子函式
created(){
//獲取位址列的key的值
const key = ly.getUrlParam("key")
//判斷是否有搜尋條件
if(!key){
alert("請求提供搜尋條件!")
return
}
//把key值賦值給searchParams中的key
//this.searchParams.key = key
//獲取位址列location的search
const searchStr = location.search.substring(1)
//將searchStr轉成json物件
const searchObj = ly.parse(searchStr)
//判斷searchObj中是否有page屬性
searchObj.page = searchObj.page || 1
//判斷searchObj中是否有filterParams屬性
searchObj.filterParams = searchObj.filterParams || {}
//把searchObj物件值覆蓋給searchParams
this.searchParams = searchObj
//向伺服器發起請求
this.loadSearchPage()
},
監聽器
watch: {
"searchParams.page": {
handler() {
//把page值放到位址列,保證位址列的值與searchParams是一致的
//將searchParams轉成字串
const searchStr = ly.stringify(this.searchParams)
//替換location的search,注意:只要location的search發生了變化,頁面就會自動重新整理
//location.search = searchStr
//指定新的位址列url
const newUrl = location.origin+location.pathname+"?"+searchStr
//使用history修改位址列,可以不重新整理頁面
window.history.replaceState(null, null, newUrl)
//向伺服器發起請求
this.pageChange()
}
},
上面的程式碼中特別注意一下的是:
- window.history 代替了 location.search,因為使用後者頁面會自動重新整理一次,使用者體驗不好
- const newUrl = location.origin+location.pathname+"?"+searchStr
三、點選篩選條件後,被點選的引數能夠新增到位址列中
在method中新增一個方法:
clickFilterParams(key, value){
//先把filterParams物件賦值給另外一個地址的物件
const {...newFilterParams} = this.searchParams.filterParams
newFilterParams[key] = value
this.searchParams.filterParams = newFilterParams
//將searchParams轉成字串
const searchStr = ly.stringify(this.searchParams)
//指定新的位址列url
const newUrl = location.origin+location.pathname+"?"+searchStr
//使用history修改位址列,可以不重新整理頁面
window.history.replaceState(null, null, newUrl)
}
這裡需要注意我們用的是:
- this.searchParams.filterParams[key] =
value而不是this.searchParams.filterParams.key =
value,用後面的寫法將得不到我們想要的結果,因為key是一個變數,後面的寫法相當於把key當做一個常量了。 - List item
const {…newFilterParams} 表示我們有可能需要多個引數,代表一個另外的一個地址, 如果直接寫
const {...newFilterParams} = this.searchParams.filterParams
表示的還是原來的地址。新的地址變化,即可觸發監聽事件
四、點選事件
@click="clickFilterParams(k, o.id || o)
<div class="fl value">
<ul class="type-list">
<li v-for="o in v" :key="o.id || o" @click="clickFilterParams(k, o.id || o)">
<a>{{o.name || o}}</a>
</li>
</ul>
</div>
注意之後鉤子函式中需要判斷一下filterParams屬性是否為空
//判斷searchObj中是否有filterParams屬性
searchObj.filterParams = searchObj.filterParams || {}
新增監聽事件
"searchParams.filterParams": {
handler() {
//向伺服器發起請求
this.loadSearchPage()
}
}
五、過濾條件查詢
在條件過濾時我們要變換寫法
根據以上圖示改寫JAVA程式碼中的service:
/**
- 查詢條件封裝
*/
private QueryBuilder createQueryBuilder(SearchRequest request) {
//建立一個過濾條件查詢物件
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//新增搜尋查詢
boolQuery.must(QueryBuilders.multiMatchQuery(request.getKey(), "all", "spuName").operator(Operator.AND));
//得到過濾條件
Map<String, Object> filterParams = request.getFilterParams();
//判斷是否有過濾條件
if(CollectionUtils.isNotEmpty(filterParams)){
//遍歷過濾條件
filterParams.entrySet().forEach(entry->{
//得到key
String key = entry.getKey();
//對key進行處理
if(StringUtils.equals(key, "分類")){
key = "categoryId";
}else if(!StringUtils.equals(key, "brandId")){
key = "specs."+key+".keyword";
}
//得到value
Object value = entry.getValue();
//新增過濾查詢
boolQuery.filter(QueryBuilders.termQuery(key, value));
});
}
return boolQuery;
}
結果展示:特有屬性會有多個,共同屬性只會展示一個
類比下京東,好像效果不太一樣,哈哈,這是後面的麵包屑功能,以後再說吧
新增一個選項所有唯一的資料隱藏
computed: {
remainFilterConditions(){
//定義一個計算屬性返回值物件
const obj = {}
//遍歷filterConditions
for (let key in this.filterConditions) {
//判斷如果當前map的value的長度是否大於1
if(this.filterConditions[key].length > 1){
//將長度大於1的過濾條件賦值給新定義的計算屬性
obj[key] = this.filterConditions[key]
}
}
return obj
}
},
六、頁面靜態化
不再進入資料庫查詢,從頭到尾只查詢一次,後面都不需要重複載入,減輕伺服器壓力,京東為每一個spu都做了一個靜態頁
修改我們的a標籤屬性,讓它跳轉到我們希望它跳轉的位置,後面可以切換到nginx實現真正的跳轉
<a :href="'/item/'+item.id+'.html'" target="_blank"><img :src="item.selectedSku.image" height="200"/></a>
七、Thymeleaf
特點:將一個靜態頁面做成動態之餘,還可以將一個動態頁面做成靜態化(兩個功能並沒有關聯)
spring官方推薦到的文件並不包括jsp,springBoot特別推薦Thymeleaf
第一步:匯入相關的依賴包
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
第二步:Thymeleaf的配置
- 檢視器配置
檢視解析器是作用是什麼:返回到頁面拼接的前字尾,你要返回哪個頁面你只要寫頁面的名稱即可。
預設字首:classpath:/templates/
預設字尾:.html
所以如果我們返回檢視:hello
,會指向到classpath:/templates/hello.html
- 修改快取配置:
凡是要經過編譯器編譯的快取就會比較小,html頁面不需要編譯,所需快取比較大,因此一定要將快取改為false
# 關閉Thymeleaf的快取
spring.thymeleaf.cache=false
第三步:搭建靜態資源伺服器
-
搭建一個新的服務(Moudle):ly-page
注意:1. 這裡不需要經過閘道器 2. 不需要連線資料庫,通過feign獲取資料 -
匯入依賴
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.leyou</groupId>
<artifactId>ly-client-item</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.leyou</groupId>
<artifactId>ly-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
第四步:配置檔案:application.yml
server:
port: 8084
spring:
application:
name: page-service
thymeleaf:
cache: false
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
第五步:啟動類
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class LyPageApplication {
public static void main(String[] args) {
SpringApplication.run(LyPageApplication.class, args);
}
}
這裡不需要閘道器,閘道器更多的起到的是一個安全的作用,在服務來獲取資料的時候起到保障作用。
第六步 : 分析渲染商品詳情頁面
找不到頁面,我們需要提供這樣一個路徑:
這樣的話只能返回一個頁面,改寫一下
@Controller
public class PageController {
@GetMapping("/item/{spuId}.html")
public String toItemPage(@PathVariable("spuId") Long spuId){
return "item";
}
}
修改nginx的配置檔案:
分析靜態頁
根據item.html頁面渲染所需要的佔位符得知,需要如下這些資料:
categories:三個分類物件的集合
brand:品牌物件
spuName:spu的名稱
subTitle:spu的副標題
detail:商品詳情物件
skus:spu下對應的sku的物件集合
specs:規格組物件列表
其中每個規格組物件中有個params屬性,params屬性型別為List
接下來怎麼提供這些資料:?
第七步 : 分析feign介面
現在唯一的條件就是spuId。
第一:根據spuId獲取SpuDTO物件,裡面要包含SpuDeail物件和sku物件的集合兩個屬性。
第二:根據品牌id查詢品牌物件。
第三:根據三個分類id的集合查詢分類物件的集合。
第四:根據第三級分類id查詢出當前分類下所有的規格引數物件集合,而且要包含規格引數集合屬性。
最後貼一下完整的VUE程式碼:
var vm = new Vue({
el: "#searchApp",
data: {
ly,
//搜尋條件和過濾條件
searchParams: {
key: "",
page: 1,
filterParams: {}
},
//過濾條件結果
filterConditions: {},
//商品資料列表
itemsList: [],
//總記錄數
totalCount: 0,
//總頁數
totalPages: 0,
//定義一個控制更多和收起按鈕的布林值
showMore: false
},
computed: {
remainFilterConditions(){
//定義一個計算屬性返回值物件
const obj = {}
//遍歷filterConditions
for (let key in this.filterConditions) {
//判斷如果當前map的value的長度是否大於1
if(this.filterConditions[key].length > 1){
//將長度大於1的過濾條件賦值給新定義的計算屬性
obj[key] = this.filterConditions[key]
}
}
return obj
}
},
created(){
//獲取位址列的key的值
const key = ly.getUrlParam("key")
//判斷是否有搜尋條件
if(!key){
alert("請求提供搜尋條件!")
return
}
//把key值賦值給searchParams中的key
//this.searchParams.key = key
//獲取位址列location的search
const searchStr = location.search.substring(1)
//將searchStr轉成json物件
const searchObj = ly.parse(searchStr)
//判斷searchObj中是否有page屬性
searchObj.page = searchObj.page || 1
//判斷searchObj中是否有filterParams屬性
searchObj.filterParams = searchObj.filterParams || {}
//把searchObj物件值覆蓋給searchParams
this.searchParams = searchObj
//向伺服器發起請求
this.loadSearchPage()
},
watch: {
"searchParams.page": {
handler() {
//把page值放到位址列,保證位址列的值與searchParams是一致的
//將searchParams轉成字串
const searchStr = ly.stringify(this.searchParams)
//替換location的search,注意:只要location的search發生了變化,頁面就會自動重新整理
//location.search = searchStr
//指定新的位址列url
const newUrl = location.origin+location.pathname+"?"+searchStr
//使用history修改位址列,可以不重新整理頁面
window.history.replaceState(null, null, newUrl)
//向伺服器發起請求
this.pageChange()
}
},
"searchParams.filterParams": {
handler() {
//向伺服器發起請求
this.loadSearchPage()
}
}
},
methods: {
//向伺服器發起請求獲取渲染搜尋頁面的資料
loadSearchPage(){
ly.http.post("/search/load/search/page", this.searchParams)
.then((resp)=>{
this.filterConditions = resp.data.filterConditions
//對商品列表資料中的skus進行轉換
resp.data.itemsList.forEach(spu=>{
spu.skus = JSON.parse(spu.skus)
//給每個spu物件中新增一個預設選中的sku物件
spu.selectedSku = spu.skus[0]
})
//vue中事件,只能對原始屬性起作用
this.itemsList = resp.data.itemsList
this.totalCount = resp.data.totalCount
this.totalPages = resp.data.totalPages
})
},
pageChange(){
ly.http.post("/search/page/change", this.searchParams)
.then((resp)=>{
//對商品列表資料中的skus進行轉換
resp.data.forEach(spu=>{
spu.skus = JSON.parse(spu.skus)
//給每個spu物件中新增一個預設選中的sku物件
spu.selectedSku = spu.skus[0]
})
//vue中事件,只能對原始屬性起作用
this.itemsList = resp.data
})
},
prePage(){
if(this.searchParams.page>1){
this.searchParams.page--
}
},
nextPage(){
if(this.searchParams.page<this.totalPages){
this.searchParams.page++
}
},
clickFilterParams(key, value){
//先把filterParams物件賦值給另外一個地址的物件
const {...newFilterParams} = this.searchParams.filterParams
newFilterParams[key] = value
this.searchParams.filterParams = newFilterParams
//將searchParams轉成字串
const searchStr = ly.stringify(this.searchParams)
//指定新的位址列url
const newUrl = location.origin+location.pathname+"?"+searchStr
//使用history修改位址列,可以不重新整理頁面
window.history.replaceState(null, null, newUrl)
}
},
components: {
lyTop: () => import("./js/pages/top.js")
}
});
相關文章
- numpy的學習筆記\pandas學習筆記筆記
- 學習筆記筆記
- 【學習筆記】數學筆記
- 《JAVA學習指南》學習筆記Java筆記
- 機器學習學習筆記機器學習筆記
- 學習筆記-粉筆980筆記
- 學習筆記(3.29)筆記
- 學習筆記(4.1)筆記
- 學習筆記(3.25)筆記
- 學習筆記(3.26)筆記
- JavaWeb 學習筆記JavaWeb筆記
- golang 學習筆記Golang筆記
- Nginx 學習筆記Nginx筆記
- spring學習筆記Spring筆記
- gPRC學習筆記筆記
- GDB學習筆記筆記
- 學習筆記(4.2)筆記
- 學習筆記(4.3)筆記
- 學習筆記(4.4)筆記
- Servlet學習筆記Servlet筆記
- 學習筆記(3.27)筆記
- jest 學習筆記筆記
- NodeJS學習筆記NodeJS筆記
- WebSocket 學習筆記Web筆記
- mount 學習筆記筆記
- mapGetters學習筆記筆記
- jQuery學習筆記jQuery筆記
- 學習筆記:DDPG筆記
- flex學習筆記Flex筆記
- react 學習筆記React筆記
- Promise學習筆記Promise筆記
- vim學習筆記筆記
- Ansible 學習筆記筆記
- Taro 學習筆記筆記
- MongoDB學習筆記MongoDB筆記
- hbase學習筆記筆記
- git學習筆記Git筆記
- ComfyUi學習筆記UI筆記