需求示例:电商平台中搜索栏的相应分类,点击需要添加相应面包屑,并且向父组件传递点击的数据,并重新发送请求。 子组件为SearchSelector.vue 父组件为SearchIndex.vue
首先我们给子组件中相应的li绑定点击事件 attrInfo,这里传入了相应参数
-
- <li
- v-for="(attrValue, index) in attr.attrValueList"
- :key="index"
- @click="attrInfo(attr, attrValue)"
- >
Vue3中新增了emits属性,可以在里面声明我们在组件中要发送的自定义事件。它是一个数组,可以在里面输入多个值(如果需要绑定多个自定义事件的话)
- export default {
- name: "SearchSelector",
- emits: ["attrInfo"], //申明
- setup(props, context) {
- // 平台售卖属性值
- function attrInfo(attr, attrValue) {
- // [”属性ID:属性值:属性名“]
- // console.log(attr, attrValue);
- context.emit("attrInfo", attr, attrValue);
- }
- return {
- attrInfo,
- };
- }
- }
其实这会已经申明好了自定义事件,可以直接在父组件中监听这个事件,但是由于我们需要传参,所以还需要在子组件中写一下方法的。
在Vue2中可以直接this.$emit,但是Vue3中我这是用的context.emit
如果这里报错,首先看一下是不是context.emit,不是$emit。其次看一下setup()中是不是props,context。不要只写一个context
子组件已经绑定好了自定义事件,接下来可以在父组件中进行监听。
在父组件中给使用到的子组件绑定事件(@自定义事件=“回调函数”)。
- <SearchSelector @attrInfo="attrInfo" />
接着就可以在父组件中定义它的回调函数,也是命名为attrInfo
- // 收集售卖平台属性回调函数(自定义事件)
- function attrInfo(attr, attrValue) {
- // console.log(attr,attrValue);
- let props = `${attr.attrId}:${attrValue}:${attr.attrName}"`;
- // 数组去重
- if (searchParams.props.indexOf(props) == -1) {
- searchParams.props.push(props);
- }
- //重新发送请求
- getData();
- }
这里说明一下,getData是封装的一个发送请求的函数,searchParams是reactive的搜索时的请求参数对象(用了Object.assign,ES6新增语法,合并对象,里面一共有10条数据)
因为props是定义的数组格式,因为我们要通过一系列属性才能精确到具体我们想买的商品。
所以还需要对要添加的属性进行数组去重(否则会展示多个相同的面包屑)
属性面包屑
-
- <li
- class="with-x"
- v-for="(attrValue, index) in searchParams.props"
- :key="index"
- >
- {{ attrValue.split(":")[1] }}<i @click="removeAttr(index)">×i>
- li>
就是因为props是数组,所以没再用v-if,而是用的v-for。并且我们的面包屑应该只是展示具体的属性名字,所以用了切片进行提取。
然后就是点击 x 按钮,关闭相应面包屑,并重新发送请求
- // 删除售卖属性
- function removeAttr(index) {
- searchParams.props.splice(index, 1);
- getData();
- }
splice函数 向/从数组中添加/删除项目,然后返回被删除的项目。
ps:该方法会改变原始数组。
参数:
- index —— 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
- howmany —— 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
- item1, …, itemX —— 可选。向数组添加的新项目。