vue项目实战(三):组件操作与组件通信+迅速复用官方组件

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
在这里插入图片描述

概述:组件化开发

就这个图,看看进行,主要就是说Vue的重点之一就在于组件化开发。
在这里插入图片描述

一、局部组件

局部组件的使用:生子挂子用子

1-局部组件的创建

  • 使用如下的代码进行一个局部组件的创建,template定义局部组件的样式。
   var App={
     data(){
       //返回的一定是一个数据对象
       return{

       }
     },
     template:'<div>我是入口组件</div>'
   }

2-局部组件的挂载

  • 使用如下的代码进行局部组件的挂载,用key:value键值对,挂载创建的value局部组件,并在父组件种用key值进行调用。
    new Vue({
      el: '#app',
      data: {
        
      },
      //挂载子组件
      components:{
        App: App//key:value 挂上App组件
      }
    })

3-局部组件的调用

  • 调用局部组件有两种方式,都是使用闭合标签调用(i)在父组件的template种进行使用,(ii)在vue对象绑定的dom元素中使用标签进行调用。
  <div id="app">
      <App></App>
  </div>
	//父组件直接可以使用,如何使用?使用标签引用
   template:'<App></App>'

如果我们此时打印父子组件的关系,那么她会这样显示
在这里插入图片描述

二、全局组件

使用如下的代码创建三个全局组件,它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。也可以被别的局部组件所使用,即App局部组件。全局组件自动挂载。

   Vue.component("Vcontent" ,{
     template:'<div>我是侧边栏组件</div>'
   })
    Vue.component("Vheader",  {
     template:'<div>我是头部组件</div>'
   })
   Vue.component("Vaside", {
     template:'<div>我是内容组件</div>'
   })
   //局部入口组组件的声明
   var App={
     template: '<div><Vheader/><Vaside/><Vcontent/>我是入口组件</div>',
   };

当然无论是全局组件还是局部组件,都是麻雀虽小,五脏俱全,可以作为一个Vue对象进行完善,既可以有data,也可以有method,完善之后再合并在一起,使用vue对象绑定到dom上,然后数据驱动视图------------

1、问题:组件内容无法分发:v-slot插槽的使用

如下代码要实现的效果是,将子组件Vbtn在父组件中引用,并显示登陆注册按钮,

   Vue.component("Vbtn", {
     template:`
        <button>按钮</button>
     `
   })
   Vue.component("Parent",{
     data(){
       return{
         msg: "I am the data from the Parent"
       }
     },
     template:`
      <div>
          <h2>I am the parent.</h2>
          <Vbtn>登陆</Vbtn>
          <Vbtn>注册</Vbtn>
        </div>
     `
   });

但是我们的运行效果是这样的
在这里插入图片描述
可以看到button显示的文字依然是Vbtn的文字,并不是我们调用时显示的文字。这时我们需要用到v-slot按钮,我们将Vbtn的定义修改为如下形式

   Vue.component("Vbtn", {
     template:`
        <!--插槽:Vue提供的内置全局组件slot,承载分发内容的出口-->
        <button>
          <slot>
            <!--这里是你分发的内容-->
            </slot>
          </button>
     `
   })

这样就好了
在这里插入图片描述

2、V-slot的进阶使用-玩转官方组件

官方文档中可以找到非常多的button的样式,也有其他组件的样式,我们要如何把他们应用到我们的程序里面呢。(以button为例)

  • 有了v-slot的基础,我们可以先写出button的名字
   Vue.component("Vbtn", {
     template:`
        <!--插槽:Vue提供的内置全局组件slot,承载分发内容的出口-->
        <button>
          <slot>
            <!--这里是你分发的内容-->
            </slot>
          </button>
     `
   })
   Vue.component("Parent",{
     data(){
       return{
         msg: "I am the data from the Parent"
       }
     },
     template:`
      <div>
          <h2>I am the parent.</h2>
          <Vbtn>主要按钮</Vbtn>
          <Vbtn>成功按钮</Vbtn>
        </div>
     `
   });
  • 然后呢,我们给我们的子组件一个defaultclass,怎么做呢,我们先吧默认按钮的样式复制下来,然后写一个<style/>,将该样式命名为default赋予我们的Vbtn组件。
    在这里插入图片描述
   Vue.component("Vbtn", {
     template:`
        <!--插槽:Vue提供的内置全局组件slot,承载分发内容的出口-->
        <button class="default">
          <slot>
            <!--这里是你分发的内容-->
            </slot>
          </button>
     `
   })

在这里插入图片描述
然后呢?我们如何添加其他的样式?我们先按照上面的方法取出两个按钮的样式–
在这里插入图片描述
将他们分别定义成css属性,

    .success {
    color: #fff;
    background-color: #67c23a;
    border-color: #67c23a;
    }
    .info {
    color: #fff;
    background-color: #909399;
    border-color: #909399;
    }

然后我们如何在父组件中复用时,给子组件不同的class?还记得v-bind命令吗?捆绑一切属性并动态改变!

  • 首先我们在子组件的定义中引入<button class="default" :class='type'>,:即v-bind,捆绑从父组件传来的参数type,自然的子组件需要prop命令接受参数props:['type']
  • 父组件使用Vbtn时传入参数type<Vbtn type='success'>主要按钮</Vbtn>即可。
   Vue.component("Vbtn", {
     template:`
        <!--插槽:Vue提供的内置全局组件slot,承载分发内容的出口-->
        <button class="default" :class='type'>
          <slot>
            <!--这里是你分发的内容-->
            </slot>
          </button>
     `,
     props:['type']
   })
   Vue.component("Parent",{
     data(){
       return{
         msg: "I am the data from the Parent"
       }
     },
     template:`
      <div>
          <h2>I am the parent.</h2>
          <Vbtn type='success'>主要按钮</Vbtn>
          <Vbtn type='info'>成功按钮</Vbtn>
        </div>
     `
   });

在这里插入图片描述

三、组件通信

在这里插入图片描述

1、父子之间通信

(1)先给父组件中绑定自定义的属性

使用如下的代码再给Child子组件绑定父组件的数据msg,(v-bind的缩写)

   Vue.component("Child",{
     template:`
      <div>
          <h3>I am the child.</h3>
        </div>
     `
   });
   Vue.component("Parent",{
     data(){
       return{
         msg: "I am the data from the Parent"
       }
     },
     template:`
      <div>
          <h2>I am the parent.</h2>
          <Child :childData="msg/>
        </div>
     `
   });

(2)在子组件中使用props接受父组件传递的数据

只需要将全局组件Child改成如下形式就接受了父组件传来的数据

   Vue.component("Child",{
     template:`
      <div>
          <h3>I am the child.</h3>
        </div>
     `,
     props:['childData']
   });

(3)尽情操作

比如我们可以使用如下代码,在子组件中将input的内容与父组件的数据进行双向绑定。但是注意,这里的双向绑定,修改的只是childData,而不会影响父组件中msg属性的值。

   Vue.component("Child",{
     template:`
      <div>
          <h3>I am the child.</h3>
          <input type="textarea" v-model='childData'></input>
        </div>
     `,
     props:['childData']
   });

一开始如左图,最后一行是msg直接输出,倒数第二行是childData直接输出,我们修改text文本框的内容会如何?
在这里插入图片描述
可以看到只有childData的内容发生了改变
在这里插入图片描述
因此我们只使用v-model时无法到达目的的,需要新的子-》父通信机制。

2、子父通信

(1). 在父组件中绑定自定义的事件。(这里绑定的是事件而不是属性)

先来分析一下对父组件的操作

   Vue.component("Parent",{
     data(){
       return{
         msg: "I am the data from the Parent"
       }
     },
     template:`
      <div>
          <h2>I am the parent.</h2>
          <Child :childData="msg" @childHandle="childHandle"/>
          <h2>{{msg}}</h2>
        </div>
     `,
     methods:{
       childHandle(){
         
       }
     }
   });

注意我们这里使用了<Child :childData="msg" @childHandle="childHandle"/> v-on的对象并不是一个事件,而是我们在methods中自定义的函数名,他将接受子组件在这里传回来的值。

(2). (重点)在子组件中触发原生事件,在函数中使用$emit触发父组件中的事件处理函数。

   Vue.component("Child",{
     template:`
      <div>
          <h3>I am the child.</h3>
          <input type="text" v-model="childData" @input="changeValue(childData)"/>
          </div>
     `,
     props:['childData'],
     methods:{
      changeValue(val){
        //在函数中使用$emit触发父组件的事件,两个参数
        //$emit(自定义的事件名,消息)
        this.$emit("childHandle", val)
      }
     }
   });

注意这里的一些细节问题,

  1. 首先@input="changeValue(childData)"我们使用v-on绑定的input事件传入一个参数,这个参数就是我们想传回父组件的参数。
  2. 处理事件的函数中,我们将传入的参数使用$emit进行操作,这个内置函数的功能有两个,一个是触发我们父组件中的处理函数childHandle,同时将参数传递给childHandle。(自定义的事件一定要使用$emit去触发)
  3. 父组件接受参数,用如下代码,父组件接受到子组件传送来的val参数,然后就可以用val参数进行自身参数的更新。
     methods:{
       childHandle(val){
         console.log(val);
       }
     }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值