黑马头条项目-day08前台最后一天

2.递归组件的回复评论

在这里插入图片描述

实现方式:内部无限循环

让递归组件无限回复评论

<div class="commentItem" title="我是评论列表的子组件">
     <!-- 组件递归,判断是否有parent.parent -->
     <!-- 递归:内部循环,这一条为了实现无限的评论回复 -->
 <item v-if='parent.parent' :parent='parent.parent' @replyItem='sendComment'></item>

21.栏目管理

添加栏目管理的入口:index添加样式

/deep/.van-sticky{
  padding-right: 50px;
  &::after{
    content: '+';
    position: absolute;
    width: 51px;
    height: 44px;
    background-color: #fff;
    top: 0;
    right: 0;
    text-align: center;
    line-height: 42px;
    font-size: 35px;
  }
}
---------------------------------
document.querySelector('.van-sticky').οnclick=e=>{
               console.log(e.target.className);
               if(e.target.className==='van-sticky'){
                 this.$router.push('/cateManager')
               }
             }

需要处理的业务

1.获取所有栏目,加载到“点击删除频道”结构中

2.这里注意一个细节:不要考虑“关注”和“头条”

3.栏目管理的相关数据存储在本地

4.在本地存储 未添加的频道 和 已添加的频道

5.我们所操作的数据都是来自于本地

6.首页栏目数据应该来自于本地存储,当然为了首页的业务依然顺利,意味着本地存储的数组数据不能仅仅是栏目名称,还应该包含着id等类似的数据

回顾json数据(数组字符串)的操作流程

获取json格式的字符串

将字符串转换为js数组或对象

操作数组或对象

将数组或对象重新转换为字符串

存储字符串

添加组件并配置路由

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

调用api方法,获取数据实现动态渲染:之前在页面栏目中有存接口

cateManager读取本地存储的栏目数据,动态渲染
async mounted () {
    
    
        // 数据渲染,如果我有之前存过的栏目数据,那么我渲染之前的数据在页面,没有则发请求渲染默认的栏目数据
        // 判断是否有已删除的栏目
        if(localStorage.getItem('tokens_addColumnList')){
    
    
            this.addColumnList=JSON.parse(
                localStorage.getItem('tokens_addColumnList')
            )
        }
        // 判断是否有已添加的栏目
        if(localStorage.getItem('tokens_delColumnList')){
    
    
            this.delColumnList=JSON.parse(
                localStorage.getItem('tokens_delColumnList')
            )
        }else{
    
    
            let res= await getCategory()
            this.delColumnList=res.data.data
            console.log(this.delColumnList);
            // if(localStorage.getItem('tokens')){
    
    
            //     this.delColumnList=this.delColumnList.splice(2) // 干掉关注和头条
            // }else{
    
    
            //     this.delColumnList=this.delColumnList.splice(1) // 干掉头条
            // }
        }
    }
实现栏目的移除
removeCate(i){
    
    
            console.log(this.delColumnList[i]);
             // 先添加再移除
             // 将当前栏目添加到“未添加栏目数组”中
             this.addColumnList.push(this.delColumnList[i])
             // 从已添加的栏目数组中移除当前栏目
             this.delColumnList.splice(i,1)
             // 将当前数据存储到本地
             localStorage.setItem('tokens_delColumnList',JSON.stringify(this.delColumnList))
              localStorage.setItem('tokens_addColumnList',JSON.stringify(this.addColumnList))

        },
实现栏目的添加
 addCate(i){
    
    
            this.delColumnList.push(this.addColumnList[i])
            this.addColumnList.splice(i,1)
            // 将当前数据存储到本地
             localStorage.setItem('tokens_delColumnList',JSON.stringify(this.delColumnList))
              localStorage.setItem('tokens_addColumnList',JSON.stringify(this.addColumnList))

        }

页面结构

<template>
  <div class="cateManager">
      <myheader title='我的栏目'>
          <span slot="left" class="iconfont iconjiantou2" @click="$router.back()"></span>
      </myheader>
      <div class="column">
          <div class="del">
              <h2>点击删除以下频道</h2>
              <ul>
                  <li v-for="(v,i) in delColumnList" :key="i" @click="removeCate(i)">{
   
   {v.name}}</li>
              </ul>
          </div>
          <div class="add">
              <h2>点击添加以下频道</h2>
              <ul>
                  <li v-for="(v,i) in addColumnList" :key="i" @click="addCate(i)">{
   
   {v.name}}</li>
              </ul>
          </div> 
      </div>
  </div>
</template>

<script>
import myheader from '@/components/myheader.vue'
import {getCategory} from '@/apis/category'
export default {
    data () {
     return {
         delColumnList:[],  //可以删除的栏目
         addColumnList:[]    //可以添加的栏目      
     }
    },
    components:{
        myheader
    },
}
<style lang="less" scoped>
h2{
   margin: 10px 0 0 10px;
}
ul{
    display: flex;
    flex-wrap: wrap;
    padding: 10px;
    // justify-content: space-between;
}
li{
    display: flex;
    justify-content: center;
    width: 50px;
    padding: 10px;
    margin: 10px 0;
    margin-right: 20px;
    border: 1px solid #000;
    &:nth-child(4n){
    margin-right: 0px;
    }
}
</style>

22.搜索

实现搜索数据的本地存储

添加组件和配置路由

{
    
    
    name:'Search',
	path:'/search',
	component:Search
}

制作组件的结构

<template>
  <div class="search">
    <div class="header">
      <span class="iconfont iconjiantou2" @click="$router.back()"></span>
      <van-search
        v-model="userKey"
        placeholder="请输入搜索关键词"
        shape="round"
      >
      </van-search>
      <div @click="onSearch">搜索</div>
    </div>
    <div class="historyList">
      <h2>历史记录</h2>
      <router-link to="">美女</router-link>
      <router-link to="">美女</router-link>
    </div>
    <div class="historyList">
      <h2>搜索结果</h2>
      <router-link to="">美女</router-link>
      <router-link to="">美女</router-link>
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return {
      userKey:''
    }
  },
  methods:{
    onSearch(){

    }
  }
}
</script>

<style lang='less' scoped>
  .header{
    display: flex;
    height: 50px;
    justify-content: space-between;
    align-items: center;
    padding: 0 10px;
    border-bottom: 1px solid #ccc;
    .van-search{
      flex: 1;
      padding: 5px 12px;
    }
  }
  .historyList{
    padding:10px;
    border-bottom: 1px solid #ccc;
    h2{
      line-height: 40px;
      font-weight: bold;
    }
    > a {
      display: block;
      text-decoration: underline;
      line-height: 30px;
      color:#666;
    }
  }
</style>

添加api方法

// 7.搜索文章
export const searchArticle = (params)=>{
    
    
    return axios({
    
    
        url:`/post_search`,
        params
    })
}
---------------------------------------
<div class="historyList">
	<h2>搜索结果</h2>
	<router-link :to="{path:`/articleDetail/${item.id}`}" v-for='item in searchList' :key='item.id'>{
    
    {
    
    item.title}}</router-link>
</div>

调用方法实现搜索

async onSearch(key){
    
    
    this.searchList.length = 0
    let res = await searchArticle({
    
    keyword:key})     
    if(res.data.data.length > 0){
    
    
        this.searchList = res.data.data
    }
    // 将当前的搜索关键字存储到本地
    let arr = this.getdata()
    // 判断当前关键字是否已经存在
    let index = arr.indexOf(key)
    if(index !== -1){
    
    
        arr.splice(index,1)
    }
    // unshift:在数组的最前面插入数据
    arr.unshift(key)
    localStorage.setItem('toutiao_search_history_52',JSON.stringify(arr))
},
// 获取之前存储的历史关键字
getdata(){
    
    
        return JSON.parse(localStorage.getItem('toutiao_search_history_52')|| '[]') 
    }

页面打开时,加载历史记录

mounted(){
    
    
    this.historyList = this.getdata()
}
---------------------------------------
<div class="historyList">
      <h2>历史记录</h2>
      <a href='javascript:;' v-for='(item,index) in historyList' :key='index' @click="onSearch(item)">{
    
    {
    
    item}}</a>
</div>    

猜你喜欢

转载自blog.csdn.net/weixin_48371382/article/details/109388110
今日推荐