日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

仿今日头条项目——首页(文章搜索)

發(fā)布時(shí)間:2024/3/13 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 仿今日头条项目——首页(文章搜索) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

1.創(chuàng)建組件并配置路由

1、創(chuàng)建 src/views/search/index.vue

<template><div class="search-container">搜索頁面</div> </template><script>export default {name: "SearchPage",components: {},props: {},data() {return {};},computed: {},watch: {},created() {},methods: {}}; </script><style scoped></style>

2、把搜索頁面的路由配置到根組件路由(一級路由)

{path: '/search',name: 'search',component: () =>import ('@/views/search')}

3.為首頁的搜索按鈕添加to屬性,實(shí)現(xiàn)路徑跳轉(zhuǎn)

<van-buttonclass="search-btn"slot="title"type="info"size="small"roundicon="search"to="/search">搜索</van-button>

2.頁面布局

1.創(chuàng)建 src/views/search/components/search-history.vue(使用cell組件)

<template><div class="search-history"><van-cell title="搜索歷史"><span>全部刪除</span><span>完成</span><van-icon name="delete" /></van-cell><van-cell title="hello"><van-icon name="close" /></van-cell><van-cell title="hello"><van-icon name="close" /></van-cell><van-cell title="hello"><van-icon name="close" /></van-cell><van-cell title="hello"><van-icon name="close" /></van-cell></div> </template><script> export default {name: 'SearchHistory',components: {},props: {},data () {return {}},computed: {},watch: {},created () {},mounted () {},methods: {} } </script><style scoped lang="less"></style>

2.創(chuàng)建 src/views/search/components/search-suggestion.vue(使用cell組件)

<template><div class="search-suggestion"><van-cell title="黑馬程序員..." icon="search"></van-cell><van-cell title="黑馬程序員..." icon="search"></van-cell><van-cell title="黑馬程序員..." icon="search"></van-cell><van-cell title="黑馬程序員..." icon="search"></van-cell><van-cell title="黑馬程序員..." icon="search"></van-cell></div> </template><script> export default {name: 'SearchSuggestion',components: {},props: {},data () {return {}},computed: {},watch: {},created () {},mounted () {},methods: {} } </script><style scoped lang="less"></style>

3.創(chuàng)建 src/views/search/components/search-result.vue(使用list組件)

<template><div class="search-result"><van-listv-model="loading":finished="finished"finished-text="沒有更多了"@load="onLoad"><van-cell v-for="item in list" :key="item" :title="item" /></van-list></div> </template><script> export default {name: 'SearchResult',components: {},props: {},data () {return {list: [],loading: false,finished: false}},computed: {},watch: {},created () {},mounted () {},methods: {onLoad () {// 異步更新數(shù)據(jù)// setTimeout 僅做示例,真實(shí)場景中一般為 ajax 請求setTimeout(() => {for (let i = 0; i < 10; i++) {this.list.push(this.list.length + 1)}// 加載狀態(tài)結(jié)束this.loading = false// 數(shù)據(jù)全部加載完成if (this.list.length >= 40) {this.finished = true}}, 1000)}} } </script><style scoped lang="less"></style>

4.搜索組件(search組件):

取消按鈕注冊onCancel事件,調(diào)用this.$router.back()方法返回頁面上一級

<template><div class="search-container"><!-- 搜索欄 --><!--Tips: 在 van-search 外層增加 form 標(biāo)簽,且 action 不為空,即可在 iOS 輸入法中顯示搜索按鈕--><form action="/"><van-searchv-model="searchText"show-actionplaceholder="請輸入搜索關(guān)鍵詞"background="#3296fa"@search="onSearch"@cancel="onCancel"/></form><!-- /搜索欄 --><!-- 搜索歷史記錄 --><search-history /><!-- /搜索歷史記錄 --><!-- 聯(lián)想建議 --><search-suggestion /><!-- /聯(lián)想建議 --><!-- 歷史記錄 --><search-result /><!-- /歷史記錄 --></div> </template><script> import SearchHistory from './components/search-history' import SearchSuggestion from './components/search-suggestion' import SearchResult from './components/search-result'export default {name: 'SearchIndex',components: {SearchHistory,SearchSuggestion,SearchResult},props: {},data () {return {searchText: ''}},computed: {},watch: {},created () {},mounted () {},methods: {onSearch (val) {console.log(val)},onCancel () {this.$router.back()}} } </script><style scoped lang="less"> .search-container {.van-search__action {color: #fff;} } </style>

3.處理頁面顯示狀態(tài)?

1、在 data?中添加數(shù)據(jù)用來控制搜索結(jié)果的顯示狀態(tài)?

data () {...isResultShow: false }

2.在模板中綁定條件渲染

<!-- 搜索結(jié)果 --> <search-result v-if="isResultShow" /> <!-- /搜索結(jié)果 --><!-- 聯(lián)想建議 --> <search-suggestion v-else-if="searchText" /> <!-- /聯(lián)想建議 --><!-- 搜索歷史記錄 --> <search-history v-else /> <!-- /搜索歷史記錄 -->

4.搜索聯(lián)想建議?

當(dāng)搜索框輸入內(nèi)容的時(shí)候,請求加載聯(lián)想建議的數(shù)據(jù),并將請求得到的結(jié)果綁定到模板中

一、將父組件中搜索框輸入的內(nèi)容傳給聯(lián)想建議子組件

二、在子組件中監(jiān)視搜索框輸入內(nèi)容的變化,如果變化則請求獲取聯(lián)想建議數(shù)據(jù)

2.1封裝聯(lián)想建議的請求方法(search.js):

/*** 用戶相關(guān)請求模塊*/ import request from '@/utils/request'export const getSearchSuggestions = q => {return request({method: 'GET',url: '/v1_0/suggestion',params: {q}}) } <script> import { getSearchSuggestions } from '@/api/search'export default {name: 'SearchSuggestion',components: {},props: {searchText: {type: String,required: true}},data () {return {suggestions: [], // 聯(lián)想建議數(shù)據(jù)列表}},computed: {},watch: {searchText: {// 當(dāng) searchText 發(fā)生改變的時(shí)候就會(huì)調(diào)用 handler 函數(shù)// 注意:handler 函數(shù)名稱是固定的handler (value) {this.loadSearchSuggestions(value)},immediate: true // 該回調(diào)將會(huì)在偵聽開始之后被立即調(diào)用}},created () {},mounted () {},methods: {async loadSearchSuggestions (q) {try {const { data } = await getSearchSuggestions(q)this.suggestions = data.data.options} catch (err) {this.$toast('數(shù)據(jù)獲取失敗,請稍后重試')}},} } </script>

?三、將獲取到的聯(lián)想建議數(shù)據(jù)展示到列表中

<van-cellicon="search"v-for="(text, index) in suggestions":key="index"></van-cell>

?5.聯(lián)想建議優(yōu)化——防抖

第三方包:lodash

?

1、安裝 lodash

2、防抖處理

// lodash 支持按需加載,有利于打包結(jié)果優(yōu)化 import { debounce } from "lodash" // debounce 函數(shù) // 參數(shù)1:函數(shù) // 參數(shù)2:防抖時(shí)間 // 返回值:防抖之后的函數(shù),和參數(shù)1功能是一樣的 handler: debounce(function (value) {this.loadSearchSuggestions(value)}, 200),// handler (value) {// this.loadSearchSuggestions(value)// },immediate: true // 該回調(diào)將會(huì)在偵聽開始之后被立即調(diào)用}

??6.聯(lián)想建議優(yōu)化——搜索關(guān)鍵字高亮

?保證不修改原始數(shù)據(jù)!!

data () {return {htmlStr: 'Hello <span style="color: red">World</span>'} } <div>{{ htmlStr }}</div> <div v-html="htmlStr"></div>

雙花括號綁定會(huì)直接輸出純文本內(nèi)容 :?<div>{{ htmlStr }}</div>?

使用 v-html 指令可以綁定渲染帶有 HTML 標(biāo)簽的字符串 :<div v-html="htmlStr"></div>?

使用插槽:

<van-cellicon="search"v-for="(text, index) in suggestions":key="index"><div slot="title" v-html="highlight(text)"></div></van-cell> highlight (text) {const highlightStr = `<span class="active">${this.searchText}</span>`// 正則表達(dá)式 // 中間的內(nèi)容都會(huì)當(dāng)作匹配字符來使用,而不是數(shù)據(jù)變量// 如果需要根據(jù)數(shù)據(jù)變量動(dòng)態(tài)的創(chuàng)建正則表達(dá)式,則手動(dòng) new RegExp// RegExp 正則表達(dá)式構(gòu)造函數(shù)// 參數(shù)1:匹配模式字符串,它會(huì)根據(jù)這個(gè)字符串創(chuàng)建正則對象// 參數(shù)2:匹配模式,要寫到字符串中const reg = new RegExp(this.searchText, 'gi')return text.replace(reg, highlightStr)}

bug:// 正則表達(dá)式 // 中間的內(nèi)容都會(huì)當(dāng)作匹配字符來使用,而不是數(shù)據(jù)變量
? ? ? // 如果需要根據(jù)數(shù)據(jù)變量動(dòng)態(tài)的創(chuàng)建正則表達(dá)式,則手動(dòng)
new RegExp


7.搜索結(jié)果

一、獲取搜索關(guān)鍵字

1、為搜索建議添加點(diǎn)擊按鈕,將選中的建議傳入父組件的搜索框(子傳父)

@click="$emit('search', text)"

父組件:

<van-searchv-model="searchText"show-actionplaceholder="請輸入搜索關(guān)鍵詞"background="#3296fa"@search="onSearch"@cancel="onCancel"@focus="isResultShow = false"/> onSearch(val) {// 更新文本框內(nèi)容this.searchText = val// 渲染搜索結(jié)果this.isResultShow = true},

2、父組件給子組件(搜索結(jié)果)傳遞數(shù)據(jù)(父傳子)

<!-- 搜索結(jié)果 --> <search-result v-if="isResultShow" :q="searchText" /> <!-- /搜索結(jié)果 --> props: {q: {type: String,require: true} },

二、請求獲取數(shù)據(jù)

1、在 api/serach.js添加封裝獲取搜索結(jié)果的請求方法

?

/*** 獲取搜索結(jié)果*/ export function getSearch(params) {return request({method: "GET",url: "/app/v1_0/search",params}) }

2、請求獲取

+ import { getSearch } from '@/api/search'export default {name: 'SearchResult',components: {},props: {q: {type: String,require: true}},data () {return {list: [],loading: false,finished: false, + page: 1, + perPage: 20}},computed: {},watch: {},created () {},mounted () {},methods: { +++ async onLoad () {// 1. 請求獲取數(shù)據(jù)const { data } = await getSearch({page: this.page, // 頁碼per_page: this.perPage, // 每頁大小q: this.q // 搜索關(guān)鍵字})// 2. 將數(shù)據(jù)添加到列表中const { results } = data.datathis.list.push(...results)// 3. 設(shè)置加載狀態(tài)結(jié)束this.loading = false// 4. 判斷數(shù)據(jù)是否加載完畢if (results.length) {this.page++ // 更新獲取下一頁數(shù)據(jù)的頁碼} else {this.finished = true // 沒有數(shù)據(jù)了,將加載狀態(tài)設(shè)置結(jié)束,不再 onLoad}}} }

三、最后,模板綁定

<van-listv-model="loading":finished="finished"finished-text="沒有更多了"@load="onLoad" ><van-cell + v-for="(article, index) in list" + :key="index" + :title="article.title"/> </van-list>

8.歷史記錄?——添加歷史記錄

要求:不要有重復(fù)歷史記錄,最新的排在最前面

1、在 data 中添加一個(gè)數(shù)據(jù)用來存儲(chǔ)歷史記錄

data () {return {...searchHistories: []} }

2、在觸發(fā)搜索的時(shí)候,記錄歷史記錄

onSearch (val) {// 更新文本框內(nèi)容this.searchText = val// 存儲(chǔ)搜索歷史記錄// 要求:不要有重復(fù)歷史記錄、最新的排在最前面const index = this.searchHistories.indexOf(val)if (index !== -1) {this.searchHistories.splice(index, 1)}this.searchHistories.unshift(val)// 渲染搜索結(jié)果this.isResultShow = true },

9.歷史記錄?——添加歷史記錄

父傳子:

父:

<search-historyv-else:search-histories="searchHistories"/>

子:

<!-- 歷史記錄 --> <van-cell-group v-else><van-cell title="歷史記錄"><van-icon name="delete" /><span>全部刪除</span>&nbsp;&nbsp;<span>完成</span></van-cell><van-cell:title="item"v-for="(item, index) in searchHistories":key="index"><van-icon name="close"></van-icon></van-cell> </van-cell-group> <!-- /歷史記錄 --> props: {searchHistories: {type: Array,required: true}},

10.歷史記錄?——?jiǎng)h除

- 給歷史記錄中的每一項(xiàng)注冊點(diǎn)擊事件
- 在處理函數(shù)中判斷
? - 如果是刪除狀態(tài),則執(zhí)行刪除操作
? - 如果是非刪除狀態(tài),則執(zhí)行搜索操作

一、處理刪除相關(guān)元素的展示狀態(tài)

1、在 data 中添加一個(gè)數(shù)據(jù)用來控制刪除相關(guān)元素的顯示狀態(tài)

data () {return {...isDeleteShow: false} }

2、綁定使用(v-if及v-else)

<!-- 歷史記錄 --> <van-cell-group v-else><van-cell title="歷史記錄"><template v-if="isDeleteShow"><span @click="searchHistories = []">全部刪除</span>&nbsp;&nbsp;<span @click="isDeleteShow = false">完成</span></template><van-icon v-else name="delete" @click="isDeleteShow = true"></van-icon></van-cell><van-cell:title="item"v-for="(item, index) in searchHistories":key="index"@click="onSearch(item)"><van-iconv-show="isDeleteShow"name="close"@click="searchHistories.splice(index, 1)"></van-icon></van-cell> </van-cell-group> <!-- /歷史記錄 -->

二、處理刪除操作

Prop 數(shù)據(jù):Prop 是受父組件數(shù)據(jù)影響的。

如果是普通數(shù)據(jù)(數(shù)字、字符串、布爾值)絕對不能修改,即便改了也不會(huì)傳導(dǎo)給父組件

如果是引用類型數(shù)據(jù)(數(shù)組、對象)可以修改,例如 [].push(xxx),對象.xxx = xxx,不能重新賦值, xxx = []

解決bug:讓父組件刪除!!!

子:<span @click="$emit('clear-search-histories')">全部刪除</span>

父:

<search-historyv-else:search-histories="searchHistories"@clear-search-histories="searchHistories = []"/>
<!-- 歷史記錄 --> <van-cell-group v-else><van-cell title="歷史記錄"><template v-if="isDeleteShow"> + <span @click="searchHistories = []">全部刪除</span>&nbsp;&nbsp;<span @click="isDeleteShow = false">完成</span></template><van-icon v-else name="delete" @click="isDeleteShow = true" /></van-cell><van-cell:title="item"v-for="(item, index) in searchHistories":key="index" + @click="onHistoryClick(item, index)"><van-icon v-show="isDeleteShow" name="close"></van-icon></van-cell> </van-cell-group> <!-- /歷史記錄 --> onHistoryClick (item, index) {// 如果是刪除狀態(tài),則執(zhí)行刪除操作if (this.isDeleteShow) {this.searchHistories.splice(index, 1)} else {// 否則執(zhí)行搜索操作this.onSearch(item)} }

11.歷史記錄?——數(shù)據(jù)持久化

1、利用 watch 監(jiān)視統(tǒng)一存儲(chǔ)數(shù)據(jù)

watch: {searchHistories (val) {// 同步到本地存儲(chǔ)setItem('serach-histories', val)} },

2、初始化的時(shí)候從本地存儲(chǔ)獲取數(shù)據(jù)

data () {return {...searchHistories: getItem('serach-histories') || [],} }

總結(jié)

以上是生活随笔為你收集整理的仿今日头条项目——首页(文章搜索)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。