vue尚品汇商城项目-day04【25.面包屑处理关键字】

在这里插入图片描述

25.面包屑处理关键字

25.1面包屑处理关键字

(1)动态开发面包屑中的分类名

  • 变成式导航路由跳转【自己跳自己】

(2)动态开发面包屑中的关键字

  • 当面包屑中的关键字清除以后, 需要让兄弟组件Header组件中的关键字清除
  • 设计组间通信
    • props:父子
    • 自定义事件:子父
    • vuex:完成
    • 插槽:父子
    • pubsub-js:万能
    • 全局事件总线 b u s 、 bus、 buson

在这里插入图片描述

修改代码,src/pages/Search/index.vue

<ul class="fl sui-tag">
	<!-- 分类的面包屑 -->
	<li class="with-x" v-if="searchParams.categoryName" @click="removeCategoryName">{
   
   {searchParams.categoryName}}</li>
	<!-- 关键字的面包屑 -->
	<li class="with-x" v-if="searchParams.keyword" @click="removeKeyword">{
   
   {searchParams.keyword}}</li>
</ul>

//删除分类的名字
removeCategoryName() {
        //把带给服务器的参数置空了,还需要向服务器发请求
        //带给服务器参数说明可有可无的:如果属性值为空的字符串还是会把相应的字段带给服务器
        //但是你把相应的字段变为undefined,当前这个字段不会带给服务器
        this.searchParams.categoryName = undefined;
        this.searchParams.category1Id = undefined;
        this.searchParams.category2Id = undefined;
        this.searchParams.category3Id = undefined;
        this.getData();
        /**
         * 地址栏也需要需改:进行路由跳转(现在的路由跳转只是跳转到自己这里)
         * 严谨:本意是删除query,如果路径当中出现params不应该删除,路由跳转的时候应该带着
         * this.$route.params有值就跳转/search并传参params,否则就只跳转/search
         */
        if (this.$route.params) {
          this.$router.push({name: "search", params:this.$route.params})
        }
},
//删除搜索框关键字的名字
removeKeyword() {
        //给服务器带的参数searchParams的keyword置空
        this.searchParams.keyword = undefined;
        this.getData();
        //通知兄弟组件Header清除搜索框里的关键字
        this.$bus.$emit("clearHeaderComponentKeyword");
        //进行路由的跳转
        if (this.$route.query) {
          this.$router.push({name: "search", query:this.$route.query})
        }
}

src/main.js

beforeCreate() {
    Vue.prototype.$bus = this
},

src/components/Header/index.vue

mounted() {
    //通过全局事件总线清除关键字
    this.$bus.$on("clearHeaderComponentKeyword", ()=>{
      this.keyword = "";
    })
}

注意点1:

问题:面包屑是根据什么产生的?

答案:根据searchParams.categoryName字段值(也就是搜索分类的名字)。

注意点2:面包屑出了v-for循环遍历产生的外,每一个都得能够点击删除,删除的话就得清空searchParams.categoryName值,比如this.searchParams.categoryName = ‘’,这样写没毛病,但是接口文档中说该字段可不传,所以推荐使用this.searchParams.categoryName = undefined;推荐传值undefined,这样的好处是当前这个字段不会带给服务器。

注意点3:

问题:点击“面包屑”会跳转路由,如何组件内跳转路由呢?

答案:组件内使用this.$router.push(),可以实现自己跳转自己

注意点4:除了要清空categoryName、category1Id、category2Id、category3Id的值外,还要注意关键字搜索params的值,比如进入Search组件内点击三级菜单后在搜索框关键字进行搜索,但是当点击面包屑的删除时params参数不能清空,且必须保留,所以才会出现如下代码:

if (this.$route.params) {
    this.$router.push({name: "search", params:this.$route.params})
}

注意点5:

问题:注意点4中的写法啥意思?

答案:判断this.$route.params有值就跳转/search并传参params,否则就只跳转/search。哪怕this.$route.params没值了会是个空对象{},但是if里面的跳转语句还是会进入的,即哪怕this.$route.params={},也会执行this.$router.push({name: “search”, params:this.$route.params}),只不过params:this参数是个空对象而已。

注意点6:点击“删除搜索框关键字的名字”的方法要清除3个地方:第一个li隐藏掉,第二个给服务器带的参数searchParams的keyword置空,第三个通知兄弟组件Header清除搜索框里的关键字。

25.2面包屑处理品牌信息

代码修改:

src/pages/Search/index.vue

<!-- 品牌的面包屑 -->
            <li class="with-x" v-if="searchParams.trademark" @click="removeTrademark">{
   
   {searchParams.trademark.split(":")[1]}}</li>
<SearchSelector @clickTrademarkHandler="clickTrademarkHandler"/>

 //删除品牌的信息
      removeTrademark() {
        this.searchParams.trademark = undefined;
        this.getData();
      },
      
//自定义事件回调
      clickTrademarkHandler(brands) {
        console.log("接收到自定义事件传过来的品牌参数!")
        //1:整理品牌字段的参数  "ID:品牌名称"
        this.searchParams.trademark = `${brands.tmId}:${brands.tmName}`
        //再次发请求获取search模块列表数据进行展示
        this.getData();
      }    
      
 beforeDestroy() {
      this.$off("clickTrademarkHandler");
    }     

src/pages/Search/SearchSelector/SearchSelector.vue

<li v-for="brands in trademarkList" :key="brands.tmId" @click="clickTrademarkInfo(brands)">{
   
   {brands.tmName}}</li>

methods: {
      //品牌的事件处理函数
      clickTrademarkInfo(brands) {
        //点击了品牌(苹果),还是需要整理参数,向服务器发请求获取相应的数据进行展示
        //老师问题:在哪个组件中发请求,父组件?
        //为什么那,因为父组件中searchParams参数是带给服务器参数,子组件组件把你点击的品牌的信息,需要给父组件传递过去---自定义事件
        this.$emit("clickTrademarkHandler", brands)
      }
    }     

注意点:1

问题:假设点击了品牌(苹果),在哪个组件中发请求,父组件?还是子组件?

答案:在父组件中,因为父组件中searchParams参数是带给服务器参数,子组件组件把你点击的品牌的信息,需要给父组件传递过去—自定义事件

注意点2:

问题:Search组件自定义方法为啥要写成<SearchSelector @clickTrademarkHandler=“clickTrademarkHandler”/>而不是<SearchSelector @clickTrademarkHandler=“clickTrademarkHandler(brands)”?/>

答案:自定义函数这里不用写形参brands,如果写上会报错如图,实际这里不用写函数参数名称,在methods定义函数clickTrademarkHandler的时候写brands进行接收就可以的

在这里插入图片描述

注意点3:

问题:为啥自定义事件回调函数clickTrademarkHandler()最后不用判断this.$route.params和this.$route.query进行路由自己跳转自己?而删除分类的名字函数removeCategoryName()和删除搜索框关键字的名字函数removeKeyword()中却要判断this.$route.params和this.$route.query?

答案:因为自定义事件回调函数clickTrademarkHandler()不涉及到query路径url展示的参数改变或者params的展示参数keyword改变,所以不用加判断,就是如图,无论怎么点击品牌信息,都不会让图中红框内展示的参数改变。

在这里插入图片描述

注意点4:

问题:为啥品牌的事件处理函数clickTrademarkInfo()使用的是this.$emit,而不是this.$bus.$emit?而且如果使用this.$bus.$emit会发现不生效?

答案:该处使用了“自定义事件”,而不是“全局事件总线”,这两语法自己弄混了。

自定义事件语法长这样:

在这里插入图片描述

全局事件总线语法长这样:

在这里插入图片描述

注意点5:Search组件中自定义事件回调clickTrademarkHandler()内写成this.searchParams.trademark = \${brands.tmId}:\${brands.tmName},用的是模板字符串的解析写法。

注意点6:

问题:Search组件中品牌的面包屑写法是{ {searchParams.trademark.split(“:”)[1]}}?

答案:因为传递过来的品牌参数长这样 “1:苹果”,这样展示面包屑不优雅,所以需要截取字符串,只展示后面的名称即可。

25.3平台售卖属性的操作

修改代码:

src/pages/Search/SearchSelector/SearchSelector.vue

<li v-for="(attrValue, index) in attr.attrValueList" :key="index" @click="clickAttrInfo(attr, attrValue)">

//平台售卖属性值的点击事件
clickAttrInfo(attr, attrValue) {
        //["属性ID:属性值:属性名"]
        let props = `${attr.attrId}:${attrValue}:${attr.attrName}`;
        this.$emit("clickAttrInfo", props)
      }

src/pages/Search/index.vue

<!-- 平台售卖属性的面包屑 -->
<li class="with-x" v-for="(attr, index) in searchParams.props" :key="index" @click="removeAttrInfo(index)">{
   
   {attr.split(":")[1]}}</li>

<SearchSelector @clickAttrInfo="clickAttrInfo"/>

//收集平台属性地方回调函数(自定义事件)
clickAttrInfo(props) {
        console.log("接收到自定义事件传过来的平台售卖属性参数!");
        //数组去重
        if (this.searchParams.props.indexOf(props) == -1) this.searchParams.props.push(props)
        //再次发请求
        this.getData();
      },
//removeAttr删除售卖的属性
removeAttrInfo(index) {
        //再次整理参数
        this.searchParams.props.splice(index, 1);
        //再次发请求
        this.getData();
      }
      
beforeDestroy() {
      this.$off("clickAttrInfo");
}      

注意点1:“品牌”面包屑可以只有一个,但是“平台售卖属性”面包屑却是可以多个的,所以不能用v-if,而是要用v-for了。

注意点2:点击“平台售卖属性”面包屑数组需要去重处理,否则就会出现如图错误现象

在这里插入图片描述

解决方案:

//数组去重
if (this.searchParams.props.indexOf(props) == -1) this.searchParams.props.push(props)

注意点3:点击清除按钮你得找到内容对应的数组索引值,否则无法匹配删除

this.searchParams.props.splice(index, 1);

注意点4:平台售卖属性的面包屑展示也要对attar进行分割展示,原attr长如图1,实际分割截取后展示如图2

在这里插入图片描述

如图1

在这里插入图片描述

如图2

注意点5:请求参数最终要的传递过来的属性格式是:[“属性ID:属性值:属性名”],所以我们需要拼接传递参数

let props = `${attr.attrId}:${attrValue}:${attr.attrName}`;

本人其他相关文章链接

1.vue尚品汇商城项目-day04【24.点击搜索按钮跳转后的页面商品列表、平台售卖属性动态展示(开发Search组件)】
2.vue尚品汇商城项目-day04【25.面包屑处理关键字】
3.vue尚品汇商城项目-day04【26.排序操作(难点)】
4.vue尚品汇商城项目-day04【27.分页器静态组件(难点)】
5.vue尚品汇商城项目-day04【28.详情页面Detail】
6.vue尚品汇商城项目-day04【29.加入购物车操作(难点)】

猜你喜欢

转载自blog.csdn.net/a924382407/article/details/129907133