Vue组件开发1之父子组件之间的通信与访问

一、 组件

  1. 使用Vue.extend({template:``}) 构造组件
const myCpn1= Vue.extend({
    template:`
      <h2>this is component1</h2>
    `
  })
  1. 注册组件Vue.component(“使用时的名称”,“构造的组件名”),使用该方法构造的组件为全局组件
Vue.component("my-cpn",myCpn)
  1. 在生成的Vue对象的components属性中注册的组件为局部组件,注意components为复数
let app = new Vue({
    el: "#app",
    components:{
      my_cpn:myCpn,
    }
  })
  1. 组件的注册还可以在另一个组件的components属性中进行,注册后成为该组件的子组件,注意子组件只能在父组件内部使用,如果还需要在父组件外部使用,那就还得在Vue对象中再次注册
const myCpn1= Vue.extend({
    template:`
      <h2>this is component1</h2>
    `
  })
  const myCpn2=Vue.extend({
    template:`
      <div>
        <h2>this is in component2</h2>
        <mycpn1></mycpn1>     //mycpn1在组件mycpn2内部进行了注册,成了mycpn2的子组件
      </div>
    `,
    components:{
      mycpn1:myCpn1,
    }
  })
  1. 使用组件
<div id="app">
  <mycpn2></mycpn2>
  <mycpn1></mycpn1>
</div>


二、组件语法糖写法

语法糖写法,系统在内部会自动调用Vue.extend()函数去处理

1. **构造并注册**全局组件
Vue.component("mycpn1",{
    template:`
      <h1>hello world</h1>
    `
  })
  1. 局部组件
let app = new Vue({
    el: "#app",
    components:{
      mycpn2:{
        template:'<h1>语法糖局部注册</h1>'
      }
    }
  })
  1. 构造并并注册子组件的方法和上面类似,不再赘述

三. 模板分离写法

可以看出,到目前为止所有的模板的HTML标签均写在javascript里面,看起来比较乱,所以Vue提供了两种模板分离的写法
  1. script标签
<script type="text/x-template" id="mycpn2">  //此处要注意到的是script标签的类型
  <h1>模板分离</h1>
</script>
<script>
  let app = new Vue({
    el: "#app",
    components:{
      mycpn2:{
        template:"#mycpn2"   //通过id将模板和对应的内容联系起来
      }
    }
  })
</script>
  1. template标签
 <template id="mycpn2_tmp">
  <h2>模板分离2</h2>
</template>
<script>
  let app = new Vue({
    el: "#app",
    components:{
      mycpn2:{
        template:"#mycpn2_tmp"
      }
    }
  })
</script>

四、组件使用的数据

组件使用的数据必须用data函数来返回,利用的是函数的作用域,防止多次调用组件时数据交互之间产生干扰。
let app = new Vue({
    el: "#app",
    components:{
      mycpn2:{
        template:"#mycpn2_tmp",
        data(){
          return {
            message:"hello, world"
          }
        }
      }
    }
  })

五、父子组件数据通信

  1. 父===>子 props,通过在组件内部定义props属性
<div id="app">
	<mycpn1 :cmovies="movies" :cmessage="message"></mycpn1>   //组件的使用
</div>
<template id="cpn">  //注意在template中只能从一个根标签出发,这里如果我将div去掉直接让ul和h2同级出现会报错
  <div>
    <ul>
      <li v-for="item in cmovies">{{item}}</li>
    </ul>
    <h2>hello</h2>
  </div>
</template>
<script src="../static/vue.js"></script>

<script>
  let app = new Vue({
    el: "#app",
    data:{
      movies:["鬼吹灯","阿凡达","快乐星球"],
      message:"hello, world"
    },
    components:{
      mycpn1:{
        template:"#cpn",
        props:["cmovies","cmessage"]    //poros属性传递来自父组件的数据,这里是数组写法,还有更常用的对象写法
      }
    }
  })
</script>

对象写法1

props:{
          cmovies:Array,
          message:String,
        }

对象写法2

props:{
          cmovies:{
            type:Array,    
            default(){     //需要注意的是,如果数据的类型为对象或者是数组时,默认值要以范湖的形式返回
              return ["Null"]
            }
          },
          cmessage:{
            type:String,
            default:"chenchen"
          },
        }

大坑注意:在组件的使用过程中,子组件和父组件传递时是不支持驼峰标识的,需要进行转换

<mycpn1 :c-movies="movies" :cmessage="message"></mycpn1>   //在使用时,cMovies==>c-movies
props:{
          cMovies:{
            type:Array,    
            default(){    
              return ["Null"]
            }
          },
        }

六、子组件到父组件的数据通信(一般为事件)

大致过程可以总结为:
a. 在子组件内部监听事件 b. 在methods中处理监听到的事件 c. methods中处理事情时,向父组件发射一个约定好的事件 d. 在父组件中会一直监听这个事件,一旦事件被触发,会交给自己的methods去处理

实例代码

  <div id="app">
    <cpn :categories="categories" @btnclick="handleClick"></cpn>    //在父组件中监听btnclick事件,然后交给自己的handleClick函数去处理
  </div>
  <template id="cpn">
    <div>
      <button v-for="item in categories" @click="btnClick(item)">{{item}}</button> //子组件监听click事件,然后交给自己btnClick()函数处理
    </div>
  </template>
  <script src="../static/vue.js"></script>
  <script>
    const cpn={
      template:"#cpn",
      props:{
        categories:{
          default() {
            return [];
          },
        }
      },
      data(){
        return {
          message:"hello"
        }
      },
      methods:{
        btnClick(item){
          this.$emit("btnclick",item)     //子组件处理click事件时没有做别的操作,只是触发了父组件一直在监听的事件
        },
      }
    }
    const app= new Vue({
      el:"#app",
      data:{
        categories:["服装","家电","数码相机","图书","出行"],
      },
      components:{
        cpn
      },
      methods:{
        handleClick(item){
          console.log(item);
        }
      }
    })
  </script>

七、 父组件到子组件的访问

通信和访问有什么不同?而且确实有差别,通信是指二者之间进行数据的传递,而访问是指直接那到父组件或者子组件。父组件拿子组件通常有两种方式:

方式一: this.$children[num]

console.log(this.$children);   //会以列表的形式打印出所有的子组件
console.log(this.$children[0].name,"child0");//找到第一个子组件并打印其name属性
console.log(this.$children[1].name,"child1");//找到第二个子组件并打印其name属性

方式二: this.$refs(更常用)

<div id="app">
    <cpn1 ref="aaa"></cpn1>    // 在使用组件的时候给组件添加上ref属性
    <cpn2 ref="bbb"></cpn2>
    <button v-on:click="btnClick">按钮</button>
</div> 
console.log(this.$refs.aaa.name);  //直接通过ref定义的名称来获取对应的子组件
console.log(this.$refs.bbb.name);

八、 子组件到父组件的访问

子组件到父组件通常也有两种方式,分别为$parent和$root:

方式一: this.$parent 访问父组件

console.log(this.$parent.name);

方式二: this.$root访问根组件

console.log(this.$root.name);
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值