项目分析五

一、首页-频道编辑——数据持久化

// 1.封装添加请求的方法,在src/api/channel.js中 export const addUserChannel = channels => { return request({ method: 'PATCH', url: '/v1_0/user/channels', data: { channels: [channels] } }) }// 2.在src/views/home/components/channel-edit.vue中导入请求方法 import {addUserChannel} from "@/api/channel"; import {mapState} from 'vuex' import {setItem} from '@/utils/storage'computed: { ...mapState(['user']), .... }// 3.修改添加频道的处理逻辑 async onAddChannels(channels) { // console.log(22); this.myChannel.push(channels); // 添加数据持久化处理 if (this.user) { try { // 已登录,就把数据请求接口放到线上 await addUserChannel({ id: channels.id, // 频道id seq: this.myChannel.length,// 序号 }); } catch (err) { this.$toast("请求失败,请稍后再试"); } } else { // 未登录,把数据存储到本地 setItem("TOUTIAO_CHANNELS", this.myChannel); } },

【项目分析五】
// 4.封装删除请求的方法在src/api/channel.js中 export const deleteUserChannel = (channelID) => { return request({ method: 'DELETE', url: `/v1_0/user/channels/${channelID}`, }) }// 5.在src/views/home/components/channel-edit.vue中导入请求方法 import {.... deleteUserChannel} from"@/api/channels"; // 6. 修改删除频道的处理逻辑 onMyChannels(channels, index) { if (this.idEdit) { .... this.myChannel.splice(index, 1); // 处理删除持久化 this.deleteChannel(channels); .... }, async deleteChannel(channels) { try { if (this.user) { // 已登录,就将数扰更新到线上 await deleteUserChannel(channels.id); } else { // 未登录,就将数据更新到本地 setItem("TOUTIAO_CHANNELS", this.myChannel); } } catch (err) { this.$toast("获取失败"); } },

// 7.在src/views/home/index.vue中导入 import { mapState } from "vuex"; import { getItem } from "@/utils/storage"; // 8.正确获取首页频道数据 methods:{ ..., async loadUserChannels() { try { // const { data } = await getUserChannels(); // console.log(data); // this.UserChannels = data.data.channels; let channels = []; // 定义一个空数组 if (this.user) { // 已登录,请求获取用户频道列表 const { data } = await getUserChannels(); // console.log(data); channels = data.data.channels; } else { // 未登录,判断是否有本地的频道列表数据 const localChannels = getItem("TOUTIAO_CHANNELS"); // 有的话,就拿来使用 if (localChannels) { channels = localChannels; } else { // 没有的话,请求获取默认频道列表 const { data } = await getUserChannels(); channels = data.data.channels; } } this.UserChannels = channels // 让之前就定义的频道列表UserChannels来接收channels } catch (err) { this.$toast("获取频道列表失败"); } }, ... }

二、首页-文章搜索——创建组件并配置路由
// 1.在src/views下创建search文件夹 // 2.在src/views/search创建文件index.vue,并搭建基本样式 // 3.在src/router/index.js中添加一级路由 // 路由映射数组 const routes = [ {....}, {....}, { path: "/search", name: "search", component: () => import("@/views/search"), }, ]; // 4.在src/views/home/index.vue中添加跳转 搜索

三、文章搜索——完成搜索栏布局
.search-container { padding-top: 108px; .van-search__action { color: #fff; } .search-form { position: fixed; top: 0; left: 0; right: 0; z-index: 1; } }

四、文章搜索——创建组件
// 1.在src/views/search中创建文件夹components,在此文件夹下创建三个文件:search-history.vuesearch-suggestion.vuesearch-result.vue并搭建基本样式 // 2. search-history.vue 搭建基本样式 // 3.search-suggestion.vue搭建基本样式 // 4.search-result.vue搭建基本样式

// 5、在search/index.vue 中导入 import SearchResult from './components/search-result' import SearchSuggestion from './components/search-suggestion' import SearchHistory from './components/search-history'// 6.注册 components: { SearchResult, SearchSuggestion, SearchHistory }, data() { return { searchText: "", // 绑定输入框变量 isResultShow:false, // 8.在data 中添加数据用来控制搜索结果的显示状态 }; },// 7.使用// 9.添加判断显示条件 // 9.添加判断显示条件// 9.添加判断显示条件

五、文章搜索——实现搜索联想功能
// 1.在父组件src/views/search/index.vue中自定义属性// 2.在子组件src/views/search/components/search-suggestion.vue中接收数据 props: { // 接收输入框数据 searchText: { type: String, required: true } }, // 3.侦听数据变化 watch: { searchText:{ handler(value){ console.log(value); // 8.监听调用获取数据 this.loadSearchSuggestions(value) }, immediate:true } },// 4.封装请求,在src/api下创建search.js文件 import request from '@/utils/request'export const getSearchSuggestions = (q) => { return request({ method: 'GET', url: '/v1_0/suggestion', params:{ q } }) }// 5.在子组件src/views/search/components/search-suggestion.vue中使用 import { getSearchSuggestions } from '@/api/search' // 6.定义变量用来储存数数据 data () { return { suggestions: [], // 联想建议数据列表 } }, // 7. 定义获取数据方法 methods: { async loadSearchSuggestions (q) { try { const { data } = await getSearchSuggestions(q) this.suggestions = data.data.options } catch (err) { this.$toast('数据获取失败,请稍后重试') } } } // 9.渲染

六、文章搜索——搜索结果
// 1.在src/views/search/components/search-suggestion.vue中给van-cell增加点击事件,触发自定义事件 // 2.父组件src/views/search/index.vue中的监听自定义事件 // 可以直接给监听事件onSearchmethods: { onSearch (val) { //console.log(val); // 更新文本框内容 this.searchText = val // 打开搜索结果 this.isResultShow = true },// 3.在父组件src/views/search/index.vue中将输入框的数据传递给搜索结果组件search-result.vue // 4.在子组件src/views/search/components/search-result.vue中接收数据 props: { // 接收传递进入的数据 searchText: { type: String, required: true } }// 5.在src/api/search.js中封装请求 export const getSearchResult = (params) => { return request({ method: 'GET', url: '/v1_0/search', params }) }// 6.在子组件src/views/search/components/search-result.vue中导入方法, import { getSearchResult } from '@/api/search' // 7.在子组件src/views/search/components/search-result.vue中请求获取数据 data () { return { list: [],// 定义存储变量 loading: false, finished: false, page: 1, perPage: 20, error: false } }, methods: { async onLoad () { try { // 1. 请求获取数据 const { data } = await getSearchResult({ page: this.page, // 页码 per_page: this.perPage, // 每页大小 q: this.searchText // 查询关键词 }) // 2. 将数据添加到数组列表中 const { results } = data.data this.list.push(...results) // 3. 将本次加载中的 loading 关闭 this.loading = false // 4. 判断是否还有数据 if (results.length) { // 如果有,则更新获取下一个数据的页码 this.page++ } else { // 如果没有,则将加载状态 finished 设置为结束 this.finished = true } } catch (err) { // 展示加载失败的提示状态 this.error = true // 加载失败了 loading 也要关闭 this.loading = false } } }, // 7.在子组件src/views/search/components/search-result.vue中渲染

七、文章搜索——实现搜索关键字高亮
// 在 methods 中添加一个方法处理高亮 highlight (text) { const highlightStr = `${this.searchText}`// 正则表达式 // 中间的内容都会当作匹配字符来使用,而不是数据变量 // 如果需要根据数据变量动态的创建正则表达式,则手动 new RegExp // RegExp 正则表达式构造函数 //参数1:匹配模式字符串,它会根据这个字符串创建正则对象 //参数2:匹配模式,要写到字符串中 const reg = new RegExp(this.searchText, 'gi') return text.replace(reg, highlightStr) } // 调用方法

八、文章搜索——实现防抖
// 1.安装查看中文文档地址https://www.lodashjs.com/ yarn add lodash // 2.导入 在src/views/search/components/search-result.vue中使用局部导入 import { debounce } from "lodash" // 3.使用 watch: { searchText: { // debounce 函数 // 参数1:一个函数 // 参数2:延迟时间,单位是毫秒 // 返回值:防抖之后的函数 //debounce(函数,时长)返回一个防抖函数 handler: debounce(function (value) { this.loadSearchSuggestions(value) }, 2000), immediate: true } },

    推荐阅读