Vue2.0 梳理系列 | 组件化通信

Vue 相关知识梳理系列文章将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!


从1989年 Tim 发明了超文本标记语言 HTML 开始,前端的发展就此开始了。从开始的静态网页,再到 ASP、JSP 和 PHP 等创建动态 HTML 方式的诞生,之后是 JavaScript的加入,JavaScript 操作 HTML,JQuery 的诞生。从 MVC 模式演变到 MVVM框架模式等等,前端在悄无声息间茁壮成长。

2013年,在 Google 工作的尤雨溪,受到 Angular 的启发,开发出了一款轻量框架,最初命名为 Seed。2013年12月,更名为 Vue,图标颜色是代表勃勃生机的绿色,版本号是 0.6.0。2014.01.24,Vue 正式对外发布,版本号是 0.8.0。

2015.10.26,vue-router、vuex、vue-cli 相继发布,标志着 Vue 从一个视图层库发展为一个渐进式框架。2016.10.01,Vue 2.0 发布,它吸收了 React 的虚拟 Dom 方案,还支持服务端渲染。2019.12.05,在万众期待中,尤雨溪公布了 Vue 3 源代码,目前 Vue 3 处于 Alpha 版本。

本系列旨在梳理 Vue 2.0 相关知识,接下来让我们一起Vue的旅途吧!


组件化的使用

  • 创建组件构造器 vue.extend() 

调用 vue.extend() 创建的是一个组件构造器。通常在创建组件构造器时,传入 template 代表我们自定义组件的模板。该模板就是在使用到组件的地方,要显示的HTML代码。

  • 注册组件 vue.component()

调用 vue.component() 是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。( 所以需要传递两个参数:注册组件的标签名和组件构造器。)

  • 使用组件(全局组件

<body>
    <div id="app">
    //3.使用组件
        <my-cpn></my-cpn>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
    //1.创造组件构造器对象
        const cpnC = Vue.extend({
            template:  //模板 
                <div>
                    <h2>title</h2>
                    <p>哈哈哈哈哈哈</p>
                    <p>嘎嘎嘎嘎嘎</p>
                </div>
        });
    //2.注册组件:此组件为全局组件(组件标签名,组件构造器
        Vue.component('my-cpn',cpnC)
            let app = new Vue({
                el: '#app'
        })
</script>
</body>

局部组件

局部组件(只能在当前vue实例中使用)。

全局组件(可以再多个vue的实例下使用)。

<body>
<div id="app">
    //3.使用组件
    <my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
    //1.创造组件构造器对象
    const cpnC = Vue.extend({
        template:  //模板 
            <div>
                <h2>title</h2>
                <p>哈哈哈哈哈哈</p>
                <p>嘎嘎嘎嘎嘎</p>
            </div>
    });
    //2.注册组件--此组件为局部组件
   let app = new Vue({
       el: '#app',
       components:{
     <!--cpn使用组件时的标签名-->
        cpn:cpnC
       }
   })
</script>
</body>

组件语法糖注册

省去了调用 Vue.extend() 的步骤,而是可以直接使用一个对象来代替。

 <!--注册全局组件语法糖-->
Vue.component('my-cpn',{   <!--my-cpn组件标签名-->
    template:        //模板
        <div>
            <h2>lalalala</h2>
            <p>哈哈哈哈哈哈</p>
            <p>嘎嘎嘎嘎嘎</p>
        </div>                                               
})
 <!--注册局部组件语法糖-->
components: {
    'my-cpn':{  <!--my-cpn组件标签名-->
        template:   //模板
            <div>
                <h2>lalalala</h2>
                <p>哈哈哈哈哈哈</p>
                <p>嘎嘎嘎嘎嘎</p>
            </div>
    }
}

组件模板的分离写法

将 HTML 分离出来写,然后挂载到对应的组件上,使结构清晰。

  • 使用<script>标签

  • 使用<template>标签

<body>
 <!--方法1:使用<script>标签-->
    <div id="app">
        <my-cpn></my-cpn>
    </div>
<script type='text/x-temolate' id="myCpn">
    <div>
        <h2>lalala</h2>
        <p>哈哈哈哈哈哈</p>
    </div>
</script>
<script src="../js/vue.js"></script>
<script>
    let app = new Vue({
        el: '#app',
        components: {
            'myCpn': {
            template: '#myCpn'
            }
        }
    })
</script>
</body>
<<body>
 <!--方法2:使用<template>标签-->
    <div id="app">
        <my-cpn></my-cpn>
    </div>


  <template id='myCpn'>
      <div>
          <h2>lalala</h2>
          <p>哈哈哈哈哈哈</p>
      </div>
  </template>
<script src="../js/vue.js"></script>
<script>
    let app = new Vue({
        el: '#app',
        components: {
            'myCpn': {
                template: '#myCpn'
            }
        }
    })
</script>
</body>

父组件和子组件

<body>
   <div id="app">
         <parent-cpn></parent-cpn>
     </div>
    <script src="../js/vue.js"></script>
    <script>
        //1.创建一个子组件构造器
        const childComponent = Vue.extend({
            template:
            <div>child子组件内容</div>
        })
        //1.创建一个父组件构造器
        const parentComponent = Vue.extend({
            template:
            <div>
                parent父组件内容
                <child-cpn></child-cpn>
            </div>
            ,
            component:{
                'child-cpn': childComponent
            }
        })
        let app = new Vue({
            el: '#app',
             components: {
               'parent-cpn': parentComponent
             }
         })
</script>
</body>

父级向子级传递 props

在组件中,使用选项 props 来声明需要从父级接收到的数据。

props 的值有两种方式:

  • 字符串数组,数组中的字符串就是传递时的名称。

  • 对象,对象可以设置传递时的类型,也可以设置默认值等。

props 选项是使用一个数组。除了数组之外,也可以使用对象,当需要对props进行类型等验证时,就需要对象写法。验证都支持的数据类型String、Number、Boolean、Array、Object、Date、Function、Symbol。

<<body>
    <div id="app">
        <cpn :cmovies="movies" :messages="message"></cpn> //传数据
    </div>
   <template id="cpn">
        <div>
            <ul>
                <li>v-for="item in cmovies"{{item}}</li>
            </ul>
            <h2>{{messages}}</h2>
        </div>
    </template>
    <script src="../js/vue.js"></script>
    <script>
     //父传子:props
        const cpn = {
            template: '#cpn',
            props: ['cmovies' ,'messages'],//被传数据
            data() {    //data必须return
                return {}
            },
        }
        const app = new Vue({
            el: '#app',
            data: {      
                 message: '你好啊',
                 movies: ['1','2','3']
            },
            components: {    ///局部组件
                cpn  //增强写法
            }
         })
</script>
</body>

子级向父级传递 events

当子组件需要向父组件传递数据时,就要用到自定义事件。

自定义事件的流程:

  • 在子组件中,通过$emit()来触发事件。

  • 在父组件中,通过v-on来监听子组件事件。

<<body>
       <!--父组件模板-->
    <div id="app">
        //2.监听子组件事件
        <cpn @item-click="cpnClick"></cpn>
    </div>
   <!--子组件模板-->
   <template id="cpn">
        <div>
            <button v-for="item in categories"
                @click="btnClick">{{item.name}}
            </button>
        </div>
    </template>
    <script src="../js/vue.js"></script>
    <script>
    //子组件
    const cpn = {
        template: '#cpn',
        data() {
            return {
                categories: [    //分类
                    {id:'a', name: '热门推荐'},
                    {id:'b', name: '手机数码'}
                ]
            }
        },
        methods: {
            btnClick(item){
             //1.自定义事件  触发事件(自定义事件名字,参数)
                this.$emit('item-click',item)
            }
        }
    }
  //2.父组件
    const app =new Vue({
        el: '#app',
            data: {
            message: '你好'
        },
        components: {
            cpn
        },
        methods: {
            cpnClick(item){
                console.log('cpnClick',item);
            }
        }
  })
</script>
</body>


 


父子组件的访问方式

父组件访问子组件:使用 $children 或 $refs

子组件访问父组件:使用 $parent

this.$children 是一个数组类型,它包含所有子组件对象。

$refs 针对一个子组件。

$refs 和 ref 指令通常是一起使用的。

首先,我们通过ref给某一个子组件绑定一个特定的 ID 。

其次,通过 this.$refs.ID 就可以访问到该组件了。

$refs 父传子

<body>
   <!--父组件模板-->
<div id="app">
    <cpn></cpn>
    <button @click='btnClick'>按钮</button>
</div>
   <template id="cpn">
        <div>子组件</div>
    </template>
    <script src="../js/vue.js"></script>
    <script>


    const app =new Vue({
        el: '#app',
        data: {
            message: '你好',
        },
        methods: {
            btnClick(){
                console.log(this.$children);
                //可直接调用子组件方法
                this.$children[0].showPassage()
            }
        },
        components: {
            cpn: {
                template: '#cpn',
                data(){
                    return {
                        name: '子组件name',
                    }
                }
            }
        },    
        methods: {
            showMessage(){
                console.log('showMessage');
            }
        }
    })
</script> 
</body>

$parent 子传父

子组件不能引用父组件或Vue实例的数据,用父组件将数据传递给子组件。

   <body>
   <!--父组件模板-->
   <div id="app">
    <cpn ref="aaa"></cpn>
    <button @click='btnClick'>按钮</button>
   </div>
   <template id="cpn">
        <div>子组件</div>
    </template>
    <script src="../js/vue.js"></script>
    <script>


    const app =new Vue({
    el: '#app',
    data: {
        message: '你好',
    },
    methods: {
        btnClick(){
            //$ref 对象类型,默认是一个空的对象
            console.log(this.$refs.aaa.name);
        }
    },
    components: {
        cpn: {
            template: '#cpn',
            data(){
                return {
                    name: '子组件name',
                }
            }
        }
    },    
    methods: {
        showMessage(){
            console.log('showMessage');
        }
    }
  })
</script> 
</body>

Vue 相关知识梳理系列文章将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!

葛媛

HFun 前端攻城狮

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值