vue组件

组件 (Component) 是 Vue.js 最强大的功能之一,使用组件化方式开发,可以封装可重用的代码,减少重复劳动

接下来,我们来注册一个组件
语法Vue.component(tagName, options)

注册组件

    Vue.component('component-a', {
      template: '<div>component-a</div>'
    })

component-a是注册的组件标签,下面就可以使用这个组件了

<div id="app">
             <component-a></component-a>
</div>

// 创建根实例
new Vue({
  el: '#app'
})

最后,渲染为:

<div id="app">
    <div>component-a!</div>
</div>

通过Vue.component方式注册的组件是一个全局组件 ,我们还可以创建局部组件,通过某个 Vue 实例/组件的实例选项 components 注册仅在其作用域中可用的组件

var Child = {
          template: '<div>A custom component!</div>'
        }
        var vm = new Vue({
            el: '#app',
            components:{
                'component-a':Child
            }
        })

局部注册的组件 将只在父组件模板中可用

组件通信
组件 A 在它的模板中使用了组件 B,它们之间必然需要相互通信,父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告知父组件
我们先来看一张图

在这里插入图片描述

从图上可以很清晰的看到,父子组件通信主要是使用prop和自定义事件,父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。
父子组件的关系可以总结为 prop 向下传递,事件向上传递。

来看个示例:

<div id="app">
             <div>
                接收到的子组件回复消息:{{replyMsg}}
             </div>
             <component-a v-bind:msg="msg" @reply="replay"></component-a>
        </div>
        <template id="componentA">
            <div>
                <div>我是组件a,接收到父类的消息是:{{msgfilter}}</div>
                <div @click="reply">回复</div>
            </div>
        </template>

Vue.component('component-a', {
          template: '#componentA',
          props:['msg'],
          data:function(){
            return{
                msgfilter:'处理后的消息-》'+this.msg
            }
          },
          methods:{
            reply:function(){
                this.$emit('reply','子组件消息')
            }
          }
        })
        var vm = new Vue({
            el: '#app',
            data:{
                msg:'父组件消息',
                replyMsg:''
            },
            methods:{
                replay:function(msg){
                    this.replyMsg = msg
                }
            }
        })

需要注意的是,组件里面的data必须是一个函数,通过return形式返回

1.父组件下发数据到子组件

在组件中通过v-bind添加一个参数将数据传递到子组件里,然后使用props接收传递过来的参数props:[‘msg’]

<component-a v-bind:msg="msg"></component-a>

渲染结果:
在这里插入图片描述

2.子组件通过事件给父组件发送消息
子组件通过$emit触发事件

this.$emit('reply','子组件消息')

在组件标签中通过v-on进行监听

<component-a v-bind:msg="msg" @reply="replay"></component-a>

监听到事件后触发reply函数,接收到子组件发送的消息

replay:function(msg){
                    this.replyMsg = msg
                }

渲染结果:

<div id="app">
    <div>
        接收到的子组件回复消息:子组件消息
    </div> 
    <div>
        <div>我是组件a,接收到父类的消息是:处理后的消息-》父组件消息</div> 
        <div>回复</div>
    </div>
</div>

以上可以看到我们是通过字符串数组来定义prop的,除此之外我们还可以用对象的形式来定义prop,用来为组件的 prop 指定验证规则,
type的值可以是这些:String Number Boolean Function Object Array Symbol,例如:

  props: {
    name: String,
    showDialog: {
        type: Boolean,
        default: false
    }
  }

实现一个dialog对话框组件
在这里插入图片描述

<div id="app" class="main">
        <div v-text="isLogin?'注销':'登录'" @click="login">登录</div>
        <div class="amount"><input type="tel" name="" v-model="amount"></div>
        <div class="btn_submit" @click="submit">确定</div>
        <v-dialog :show-dialog="showDialog" :msg="msg" :type="type" @close-dialog="closeDialog"></v-dialog>
    </div>
    <template id="dialog">
        <div class="dialog" v-if="showDialog">
            <div class="dialog_mask"></div>
            <div class="dialog_container">
                <div class="dialog_content">
                    <div class="dialog_content_top" v-text="msg">提示内容</div>
                    <div class="dialog_btn">
                        <a v-if="type==1" href="javascript:;" class="btn" @click="close">确定</a>
                        <a v-if="type==2" href="javascript:;" class="btn" @click="close">取消</a>
                        <a v-if="type==2" href="javascript:;" class="btn" @click="login">去登录</a>
                    </div>
                </div>
            </div>
        </div>
    </template>

Vue.component('v-dialog', {
            template: '#dialog',
            // props:['msg','type','showDialog'],
            props:{
                msg:String,
                type:Number,
                showDialog:{
                    type: Boolean,
                    default: false
                }
            },
            data:function(){
                return {
                }
            },
            methods:{
                close:function(){
                    // 触发父类关闭窗口事件
                    this.$emit('close-dialog');
                },
                login:function(){
                    console.log("登录跳转中...");
                    this.$emit('close-dialog');
                }
            }
        })
        // vue实例
        var vm = new Vue({
            el: '#app',
            data: {
                amount:'',
                msg:'',
                showDialog:false,
                type:1,// 提示类型  1单按钮提示框  2双按钮提示框
                isLogin:true
            },
            methods:{
                login:function(){
                    this.isLogin = !this.isLogin;
                },
                submit:function(){
                    //弹出对话框组件
                    if(!this.isLogin){//未登录
                        this.msg = "请先去登录再领取金额";
                        this.showDialog = !this.showDialog;
                        this.type = 2;
                        return;
                    }
                    if(this.amount){
                        if(this.amount<1 || this.amount>1000){
                            this.msg = "输入金额不能低于1元大于1000";
                            this.showDialog = !this.showDialog;
                            this.type = 1;
                        }else{
                            this.msg = "领取成功,请在账户中心查看";
                            this.showDialog = !this.showDialog;
                            this.type = 1;
                        }
                    }else{
                        this.msg = "领取金额不能为空";
                        this.showDialog = !this.showDialog;
                            this.type = 1;
                    }
                },
                closeDialog:function(){//关闭对话框
                    this.showDialog = false;
                }
            }
        })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值