如果说vue组件化开发中第一步应该了解的是什么的话,那无疑是父子组件之间是如何实现通讯的(说白了就是父子组件中数据是如何传递的),只有理解了这一步,才能更好的开发组件
这里先提出两个关键词: props 与 emit :
写这个组件之前,先看看效果图:
组件开发分析:
既然是组件:
- 首先组件内部数据内容肯定是可变的(如上图中的"按时间排序"之类的),这必须由父组件传入(即父组件如何将数据传个父组件);
- 在选择了内容之后,如何将数据传出来(即子组件如何将数据传给父组件)
先写结构:
父组件
<!--下拉框父组件-->
<template>
<div id="app">
<oSelect @changeOption="onChangeOption" :selectData="selectData"></oSelect>
<!--
selectData: 传入父组件需要传入的数据;格式:childDataName="parentDataName";
onChangeOption: 子组件触发的事件名,通过触发一个事件从而来接收子组件的传过来的数据
格式:@childEventName="parentEventName"
注:可写多个
-->
</div>
</template>
<script>
import oSelect from "@/components/select.vue"; //引入组件
export default{
name: 'App',
data(){
return {
selectData: {
defaultIndex: 0, //默认选中的是第几个
selectStatus: false, // 通过selectStatus来控制下拉框的显示/隐藏
selectOptions: [ // 下拉框中的数据 name这样的参数,看项目是否有需求,可自行修改
{
name: 'time',
context: '按时间排序'
},
{
name: 'view',
context: '按浏览量排序'
},
{
name: 'like',
context: '按点赞数排序'
},
{
name: 'reply',
context: '按回复数排序'
},
{
name: 'reward',
context: '按打赏数排序'
}
]
}
}
},
methods:{
onChangeOption(index){
//子组件通过一个事件来触发onChangeOption方法,从而传递一系列参数,这里的index就是传过来的
this.selectData.defaultIndex = index;
//触发过后,动态改变了需要值
}
},
components: {
oSelect,
//注册组件
}
}
</script>
子组件
<template>
<!-- 下拉框组件html结构(子组件) -->
<div class="select-box" @click="changeStatus">
<!-- changeStatus事件: 点击实现下拉框的显示和隐藏 -->
<h3 class="select-title"
:name="selectData.selectOptions[selectData.defaultIndex].name"
:class="{'select-title-active': selectData.selectStatus}">
<!--属性name class的动态绑定-->
{{ selectData.selectOptions[selectData.defaultIndex].context }}
<!--这里主要绑定选择的数据-->
</h3>
<transition name="slide-down">
<!--transition 实现下拉列表显示隐藏时的动画-->
<ul class="select-options" v-show="selectData.selectStatus">
<li class="select-option-item"
v-for="(item,index) in selectData.selectOptions"
@click="EmitchangeOption(index)"
:class="{'select-option-active':selectData.defaultIndex===index}">
<!--
v-for:循环数据渲染下拉列表
EmitchangeOption:点击下拉列表事件
class:动态绑定被选中的数据
-->
{{ selectData.selectOptions[index].context }}
</li>
<div class="arrow-top"></div>
</ul>
</transition>
</div>
</template>
<script>
export default{
name: 'oSelect', //建议大家都写上这个,有利于我们知道这个组件叫什么名字
//通过props来接收父组件传过来的数据
props:{
selectData: {
type: Object //规定传过来的数据为对象,否则就会报错(其实这样写就是规避错误和良好的习惯)
}
},
methods:{
EmitchangeOption(index){
this.$emit('changeOption',index);
// 通过点击事件触发EmitchangeOption函数,传入当前点击下拉列表中的索引值index
// 下拉框通过emit方法触发父组件中changeOption函数,动态传给父组件需要的数据,这里为索引值
},
changeStatus(){
// 通过changeStatus事件动态改变selectStatus的值,从而控制下拉框的显示隐藏
this.selectData.selectStatus = !this.selectData.selectStatus
}
}
}
</script>
内容版权声明:除非注明,否则皆为本站原创文章。
