本章内容:
1、组件封装完成后,非需求性变更,组件不需要更改。
2、组件内容的变化,都有父组件控制,这种组件被称为可控组件
3、组件封装过程中,第一步先考虑入参。这题中,swiper一定有个数组
4、然后考虑数据控制型入参,如题中入参是数组,且是swiper,那么就可以有入参数组下标
设计稿:
开始进入代码:
1、slot定义左侧上方的文字,先把基础写出来:
首先,我们来理解,什么是slot,slot是vue中的插槽
<slot></slot>就是插槽的写法,他又匿名插槽和具名插槽两种,匿名插槽写法:
<slot></slot>
<child-example> <!--这个是你在父级给这个插槽起的名字-->
<span>这是匿名插槽的内容</span>
</child-example>
具名插槽写法:
// 这里是子级的写法
<slot name="left"></slot>
<slot name="right"></slot>
// 这是父级的写法
<child-example>
<span slot="left">这是具名插槽left的内容</span>
<template v-slot:right>
<span>这是具名插槽right的内容</span>
</template>
</child-example>
因为我们这里需要用到插槽,所以我们的子级页面中就应该写一个插槽,然后向父级索要我们需要的代码:
<slot :name=""></slot>
这里,我们需要一个数组,数组中需要有个对象,对象中应该有两个元素,分别是左侧的具名函数的name和右侧的swiper的图片,那么我们把这个数组,写在父级,然后在子级调用它:
list: [
{
id: 1,
switchImg: bannerImg1, // swiper图片
names: "page1", // 插槽名
},
{
id: 2,
switchImg: bannerImg2,
names: "page2",
},
{
id: 3,
switchImg: bannerImg3,
names: "page3",
},
],
然后在子级中定义向父级索要一个数组:
props:{
list:Array
}
然后在父级中定义他:
<swichNft :list="list">
import swichNft from "@/components/NFTPage/swichNft.vue";
components: {
swichNft,
},
我们在父级中的数组,我们需要把他赋值给子级,这里怎么做呢,在子级的data中建立一个空数组,swich:
export default{
data:()=>{
return{
swich[];
}
}
}
然后用vue2生命周期中的mounted函数,将父级的list数组中的值赋值给自己的swich数组:
mounted: function () {
this.swich = this.list;
},
这样,我们的swich数组里面的内容就和父级中的list数组里面的内容一模一样了,我们需要更改数据的时候就可以直接更改父级就可以了,接下来,我们给子级的具名插槽的name赋值:
<slot :name="swich[0]?.names"></slot>
这里加问号的意思就是,如果这个数组里面没有这个值,不会报错。
其实这里我们是没写完的,因为我们把具名函数的值写死了,不过,我们先写到这里,我们接下来去写swiper,这里我们的swiper和平时的不一样,因为我们这里是自定义按钮去控制右侧swiper的滑动,属于一个交互,所以,这里很重要,我写了整整一天半,才实现了他的功能
2、自定义按钮控制swiper的切换:
a、首先,我们先在element-ui里面,找到走马灯(就是swiper),然后找到一个形态写在页面上:
<el-carousel :interval="5000" arrow="always">
<el-carousel-item v-for="item in 4" :key="item">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
这样,我们就得到了一个引入的走马灯,然后按照ui设计稿给他定义宽高,样式:
.swichNft {
.switchOne {
.el-carousel {
margin-left: 100px;
width: 665px;
height: 758px;
margin-top: 32px;
.el-carousel__container {
width: 100%;
height: 758px;
}
.el-carousel__indicators {
display: none;
}
}
}
}
老规矩啊,因为element-ui的特殊原因,我们必须把他的样式写在外部的less全局文件中,不然不生效。
定义好样式以后,我们需要把他的内部定义好,我们不需要左右两侧的点击滑动按钮,不需要底部的切换横条,并且图片也需要去改变,所以,我们就利用element-ui走马灯的变量,将他们定义好:
<div class="switchOne">
<el-carousel
:interval="5000"
arrow="never" // 这个是删除两边按钮
:autoplay="false"
>
// 这里是在切换内容,将我们的数组中的图片切换过来
<el-carousel-item v-for="(item, index) in swich" :key="index">
<img :src="item.switchImg" alt="" />
</el-carousel-item>
</el-carousel>
</div>
这样,swiper就被我们定义好了,里面的元素也换成了我们的元素。
b、然后我们开始定义我们的按钮:
<div
class="switchButtonStyle"
v-for="(_item, index) in swich":key="index" @click="imgShowChange(index)"
></div>
这里我们没用button而是用了div代替了button,这里如果想用button。把div换成button就可以了,因为我们的按钮数量必须和swiper的数量一样,所以我们这里直接循环了数组,让数组的元素数量,去定义我们的按钮数量。这里我们会发现,他的按钮是不同样式的,比如,我当前在第二张图片中,那么我们的按钮应该也是在第二张图片中,并且颜色和其他的按钮颜色是不一样的,并且,这里应该会有一个需求,就是当按钮对应当前图片的时候,这个按钮点击应该是没有效果的,那么,我们这里就需要改变他的class样式,怎么去定义他所在的位置和样式与旁边的swiper相呼应呢,这边我们用到了一个变量,这个变量应该和当前swiper的数组下标相同,所以,我们需要给swiper定义一个变量,这个变量就是当前显示的图片的数组下标:
export default {
name: "SwichNft",
data: () => {
return {
activeIndex: 1,
};
},
}
<el-carousel
:initial-index="activeIndex" // 这个值就是他的数组下标
:interval="5000"
arrow="never"
:autoplay="false"
ref="changeImg"
>
<el-carousel-item v-for="(item, index) in swich" :key="index">
<img :src="item.switchImg" alt="" />
</el-carousel-item>
</el-carousel>
然后我们就用这个activeIndex变量,去定义样式的不同:
<div
:class="
index === activeIndex ? 'switchButton' : 'switchButtonStyle'"
v-for="(_item, index) in swich":key="index"
@click="imgShowChange(index)">
</div>
这段代码的意思就是,如果数组的index和activeIndex的值一样,那么我们就给与他不同的样式,这里,我们给了activeIndex === 1,那么swiper就会从第二张图片作为默认图片(开局显示第二张图片),因为数组下标是从0开始的。
c、书写按钮的函数:
我们这里给按钮一个点击事件,点击事件给个参数,这个参数就是数组的index(索引)
@click="imgShowChange(index)"
然后我们开始书写函数:
methods: {
imgShowChange: function (val) {
this.$refs.changeImg.setActiveItem(val);
this.activeIndex = val;
},
},
这里我们里面的两句代码是什么意思呢:
首先第一句,我们给element-ui走马灯一个ref函数,他的名字叫做changeImg,然后走马灯有一个参数,叫做setActiveItem,这个参数的意思是:
也就是说,我们点击按钮的时候,手动切换他的幻灯片索引,然后他的参数就是val,val === swich的index,也就等于list的index。也就是说,当我们点击按钮的时候,假如,我们点击的是第一个按钮,那么他的索引值就是0,val === 0 ,那么这个图片索引就是0,显示的就是第一张图。
然后将val的值赋值给activeIndex。这里的意义是当点击的时候,他的图片默认显示就为val。
3、书写插槽内容:
上边我们已经把插槽的使用写完了,记下来来我们写插槽的内容就可以了:
<div slot="page1">
<div class="switchInt">
<div class="bigThing">大事件1</div>
<div class="bigThing">ConFi即将推出</div>
</div>
<div class="swichNftTextInt">
艺术家发行认证的唯一版数字艺术品,在以太坊区块链上进行认证以防止伪造,并提供历史来源。
</div>
<div class="findButton">
<baseButton :buttonStyle="{ color: '#fff' }">发现</baseButton>
</div>
</div>
因为,我们数组中有三个元素,但是只有一个插槽,那么我们就需要再写两个插槽,不然他的css就会出现问题,如果后面我们的插槽中有其他的活动,我们直接改数据就可以了
<div slot="page2">
<div class="switchInt">
<div class="bigThing">大事件1</div>
<div class="bigThing">ConFi即将推出</div>
</div>
<div class="swichNftTextInt">
艺术家发行认证的唯一版数字艺术品,在以太坊区块链上进行认证以防止伪造,并提供历史来源。
</div>
<div class="findButton">
<baseButton :buttonStyle="{ color: '#fff' }">发现</baseButton>
</div>
</div>
<div slot="page3">
<div class="switchInt">
<div class="bigThing">大事件1</div>
<div class="bigThing">ConFi即将推出</div>
</div>
<div class="swichNftTextInt">
艺术家发行认证的唯一版数字艺术品,在以太坊区块链上进行认证以防止伪造,并提供历史来源。
</div>
<div class="findButton">
<baseButton :buttonStyle="{ color: '#fff' }">发现</baseButton>
</div>
</div>
这样就实现了整个组件的封装,实现了:
1、组件封装完成后,非需求性变更,组件不需要更改。// 我们现在可以直接更改父级中的数据
2、组件内容的变化,都有父组件控制,这种组件被称为可控组件。// 这里我们更改父级的数据,组件中的数据就会自动改变,无需更改组件。
3、组件封装过程中,第一步先考虑入参。这题中,swiper一定有个数组 // 这里我们定义了数组list,然后给子级组件定义了数组,复制了父级数组,入参就是数组的数组下标。
4、然后考虑数据控制型入参,如题中入参是数组,且是swiper,那么就可以有入参数组下标 // 搞定!!