一、首页-频道编辑——数据持久化
// 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 组件提供了 search 和 cancel 事件,search 事件在点击键盘上的搜索/回车按钮后触发,cancel 事件在点击搜索框右侧取消按钮时触发。
.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
}
},
推荐阅读
- 项目分析一
- 项目分析六
- 项目分析七
- vue.js|vue-cli3.0 使用postcss-plugin-px2rem(推荐)和 postcss-pxtorem(postcss-px2rem)自动转换px为rem 的配置方法;
- 大数据项目总结|基于Java+springmvc+vue 健康管理系统
- Java毕业设计|基于Java+SpringMvc+vue+element实现博物馆平台系统
- vue|Vue基础知识点(一)
- vuejs|vue-router原理与源码分析
- 前端面试总结|vue核心面试题(vue中模板编译原理)