Vue(自定义事件+组件)实现简易表单

Vue组件实现简易表单

描述:封装Vue组件,组件可以复用,只需改变组件内容,通过遍历vue实例对象内的数据内容,将数据放进组件,并在组件内部通过$emit()将需要操作的事件以及参数传递出去,由父组件接收后再利用vue实例里的函数进行相应操作,注意这里不要直接在组件内部调用vue实例的函数,必须要通过父组件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/light.css">
    <style>
      .child{
         width: 700px;
         height: 50px;
         display: flex;
         line-height: 50px;
         justify-content: space-between;
      }
    </style>
</head>
<body>
    <div id="bigBox">
        <person :p="list" v-for="list in List" @change="del" @changecount="countall" @chec="ch" @addnum="addnum" @reducenum="reducenum"></person> //调用组件,遍历List数组,将遍历到的每一项用变量p传入组件内部   绑定一系列自定义事件
        <span><input type="checkbox" name="" id=""  @click="checked()" v-model="checkedall"></span><span>总价:{{count}}</span>//全选框
        
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
     var Btn={                         //加减按钮组件
       data(){
           return {
           }
       },
       props:["b"],                     //接收变量b带来的参数
       template:`<div class="chilBtn">
                <button @click="reduce(b.id)">-</button>
                    {{ b.num }}                  //提取b中的数据
                    <button @click="add(b.id)">+</button> 
                </div> 
           `,
        methods:{
              add(id){             
                this.$emit('addnum',id)     //点击过后,传值给父组件   父组件触发名称为addnum的自定义事件
                this.$emit('changesm')   //同上
              },
              reduce(id){
                  this.$emit('reducenum',id)   //点击过后,传值给父组件   父组件触发名称为reducenum的自定义事件
                  this.$emit('changesm')  //同上
              }
           }
    }

    var Person={            //每一条list数据的组件
        data(){
            return {  
            }
        },
        props:["p"],        //接收父组件传进来的p变量的参数
        template:`<div class="child">
               <span><input type="checkbox" name="" id=""  @click="ch(p.id)" v-model="p.check"></span> 
                 <span>
                    {{ p.name }}
                 </span> 
                 <span>
                    {{ p.price }}
                 </span> 
                 <btn :b=p @changesm="countall" @addnum="addnum" @reducenum="reducenum"></btn>     //调用上面的Btn组件,并将p的值用变量b传进去
                 <span>{{p.price*p.num}}</span>
                 <button @click="del(p.id)">删除</button>
                </div> 
           `,
           methods:{
                del(id){
                    this.$emit('change',id)       
                    this.$emit('changecount')
                },
                ch(id){
                    this.$emit('chec',id)
                    this.$emit('changecount')
                },
                countall(){
                    this.$emit('changecount')
                },
                addnum(id){
                    this.$emit('addnum',id)
                },
                reducenum(id){
                    this.$emit('reducenum',id)
                }
           },
        components:{           //要在一个组件内部用别的组件一定要先注册要用的组件
           Btn
        }
    }
   
    var vm=new Vue({
       el:"#bigBox",
       data:{
           checkedall:false,
           count:0,
           List:[{id:"pikaqiu" ,name:"皮卡丘",price:300,num:1,check:false},
                 {id:"huluwa" ,name:"葫芦娃",price:250,num:1,check:false},
                 {id:"xiaowanzi" ,name:"小丸子",price:200,num:1,check:false},
                 {id:"xiaopzhu" ,name:"小P猪",price:120,num:1,check:false}]
       },
       methods:{
            addnum(id){
                let obj = this.List.find((item)=>item.id == id);
                obj.num++
            },
            reducenum(id){
                let obj = this.List.find((item)=>item.id == id);
                let n=obj.num-1
                obj.num = Math.max(n,1)
            },
            countall(){
                this.count=0 
                for(var i=0;i<this.List.length;i++){
                    if(this.List[i].check==true){
                        this.count+=this.List[i].num*this.List
                        [i].price
                    }
                }
            },
            del(id){
                    this.List = this.List.filter((item)=>{  
                    return item.id != id
                })
            },
            checked(){          //勾选全选框时,将所有复选框选中
                if(this.checkedall==false){
                    for(var i=0;i<this.List.length;i++){
                        this.List[i].check=true
                    }
                }else{
                    for(var i=0;i<this.List.length;i++){
                        this.List[i].check=false
                    }
                }
                this.countall()
            },
            ch(id){         //实现多选框勾选时遍历判断是否是全选,是的话就自动勾选全选框
                var n=0;
                let obj = this.List.find((item)=>item.id == id);
                obj.check=!obj.check
                for(var i=0;i<this.List.length;i++){
                        if(this.List[i].check==true){
                             n++
                        }
                    }
                    if(n==this.List.length){
                        this.checkedall=true
                    }else{
                        this.checkedall=false
                    }
            }
       },
       components:{ 
           Person,Btn
        }
    })
    
</script>
</html>

注:初学vue,此代码很多地方还需优化

效果图:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大兵的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值