您的当前位置:首页正文

Vue2.0 组件传值通讯的示例代码

2020-11-27 来源:易榕旅网

在Vue项目中,我们经常把某个功能模块封装起来,形成组件,下次调用时非常方便,同时也是在一些循环中进行dom操作的一种较好方式。

本次我想以一个评价组件来说一下组件的事件和参数是怎样传递的,如何完成的组件通讯。

示例如下:


这里先说一下组件设计思路:

明确整个功能场景,找出存在的事件操作,此例是一个简单的评价功能,即点击某一个星星时左边以及当前为选中的黄色星,右边为未选中的白色星。

确定可复用的组件,即具有重复操作的模块,这里明显的每一个星星为一个可复用组件, 其实还有个星星变成白色和黄色也是一个小组件,这种在具体写的时候觉得可以再分即可。

至此一个划分了三个组件:JudgeOf、JudgeStar、StarImg

这里需要明确的是,在大多数的组件通讯中,父组件往子组件传递的都是数据,子组件往父组件传递的才是事件,
我们姑且称父到子走的是一个数据流,子到父走的是一个事件流,了解这一点基本可以很好的了解组件通讯的情况。

JudgeOf组件:

基本的外框,循环starList构成三个评分选项。向子组件传递选项名字,和当前选项的索引

<template>
 <div>
 <div class="judge-modal" @click="cancel"></div>
 <div class="judge">
 <br>
 <div class="text-center font16">评价</div>
 <judge-star v-for="item,index in starList" :key="index" @judge="judge" :name="item.name" :index="index" ></judge-star>
 <br>
 <div class="box container text-left">
 <span class="icon-i"></span> 评价内容
 </div>
 <div class="bgfff container font14">
 <textarea placeholder="请输入您的评价,方便我们改进,谢谢!" type="textarea" class="textarea" rows="6" v-model="judgeTxt"></textarea>
 </div>
 <div class="container">
 <br>
 <div class="btn btn_block text-center" @click="submit">提交</div>
 </div>
 </div>
 </div>
</template>

<script>
 import JudgeStar from './judgeStar.vue'
 export default{
 data(){
 return{
 starList:[
 {name:'服务态度',key:'evaluate.serviceStarLevel'},
 {name:'责任感',key:'evaluate.dutyStarLevel'},
 {name:'准时度',key:'evaluate.onTimeStarLevel'},
 ],
 evaluate:[],
 judgeTxt:''
 }
 },
 components:{
 JudgeStar
 },
 computed:{

 },
 methods:{
 cancel(){
 this.$emit('cancel')
 },
 submit(){
 let data = '';
 this.starList.forEach((val,index)=>{
 data =`${val.key}:${this.evaluate[index]}`
 console.log(data)
 });
 },
 judge(data){
 this.evaluate[data[0]]=data[1];
 }
 }
 }
</script>

JudgeStar组件:

在这里注册一个chooseIndex,当点击某一个星星时,StarImg组件emit当前星星的index,JudgeStar组件中接收此参数并赋值给chooseIndex,同时StarImg里面watch这个参数,大于index表明没有被选中,反之则为选中,

<template>
 <div class="flex_cont container">
 <div class="flex_item name">{{name}}</div>
 <div class="flex_item">
 <star-img @choose="choose" v-for="item,index in starArr" :key="index" :chooseIndex="chooseIndex" :index="index"></star-img>
 </div>
 </div>

</template>

<script>
 import StarImg from './starImg.vue'
 export default{
 props:{
 name:String,
 index:''
 },
 data(){
 return{
 chooseIndex:4,
 starArr:Array.from({ length: 5 })
 }
 },
 components:{
 StarImg
 },
 mounted(){
 this.$emit('judge',[this.index,this.chooseIndex+1]);
 },
 methods:{
 choose(data){
 this.chooseIndex = data;
 this.$emit('judge',[this.index,this.chooseIndex+1]);
 }
 }
 }
</script>

StarImg组件:

观察chooseIndex值的变化

<template>
 <i style="margin: 0 3px;" :class="icon" @click="choose"></i>
</template>

<script>
export default{
 props:{
 index:Number, //当前星星的索引
 chooseIndex:Number //选中星星的索引
 },
 data(){
 return{
 icon:'icon-star'
 }
 },
 watch:{
 //大于index表明没有被选中,反之则为选中,
 chooseIndex:function () {
 if(this.chooseIndex>=this.index){
 this.icon = 'icon-star'
 } else {
 this.icon = 'icon-star2'
 }
 },
 },
 methods:{
 choose(){
 /*所选星星最大索引*/
 this.$emit('choose',this.index)
 }
 },
 created(){

 }
}
</script>

总结一下:

  1. 父组件通过v-bind:绑定参数传给子组件,子组件通过props接受这个参数。
  2. 在组件的最底层开始写事件,由最底层组件逐步向上$emit事件流,并携带相应参数,最后在父组件内完成总的数据处理。
显示全文