1.组件化思想

页面上会存在许多结构类似,只是数据不同的标签组合,比如上中下布局、导航、表格的样式等等,这些只有数据不同,结构大体上基本相似的元素组合在vue中就被称为组件
之所以要有组件是因为这些结构类似的元素组合会在页面上出现多次,如果每次都写一大堆元素对于后期的管理不友好,如果使用组件则像单个标签一样方便,能够极大简化代码的开发
组件同时还有助于编写出结构清晰的页面
image.png
像图中可以对整个页面进行高度抽象,全部封装为一个个组件,在开发时可以最大化的复用组件,减少代码量

2.组件的分类与使用

组件分为全局组件和局部组件,使用Vue.component进行注册的组件称为全局组件,所有的vue实例中都可以使用,在实例中注册的组件称为局部组件,只有当前实例中可以使用
Vue.component方法接收两个参数,第一个是组件名称,此名称即为页面上的标签名称,第二个参数是一个对象,该对象中可配置的东西和vue实例中可配置的基本类似

Vue.component('comp', {
    data(){
      return {
        count: 0
      }
    },
    template: `
      <div>
        {{count}}
        <button @click="count++">+</button>
      </div>
    `
  })

通过template属性确定每个组件中会使用到的元素,当在页面上使用组件名时默认会展示该标签中的所有内容

<div id="app">
  <comp>
</comp></div>

image.png
需要复用时直接使用多个组件名即可

<div id="app">
  <comp></comp>
  <comp></comp>
  <comp></comp>
</div>

3.编写组件的步骤

一般开发中最常用见的方式就是局部组件了,局部组件的使用分为三个步骤
第一步,先在vue实例中定义组件内部的一些信息

let comp = {
  data(){
    return {
      count: 0
    }
  },
  template: `
<div>
{{count}}
<button @click="count++">+</button>
</div>
`
}

这里的配置项和vue实例中的很相似,用法基本一样,通过一个对象表示组件中的所有内容
第二步,在vue实例的components中注册该组件,key值即为组件名称,value值即为组件的配置信息

let app = new Vue({
  el: '#app',
  components: {
    comp: comp
  },
  data: {

  }
})

第三步,在页面上使用此组件,使用方式和全局组件一样

<div id="app">
  <comp></comp>
</div>

image.png
全局组件和局部组件的区别就在于组件配置对象是通过哪种方式注册的
全局组件必须在根实例创建之前进行注册
组件中的data必须是一个函数,因为组件可能创建多个,如果都使用一个对象的话那么它的值就会变成一样的,为了保证每个组件使用不同的值,因此需要将data定义为函数,并在函数中为每个组件对象返回一个data对象
在使用v-for遍历组件时需要为每个单独的组件绑定唯一的key值

4.父子组件与传值

根据组件所在的位置将其分为多种类型,通常如果一个组件在另一个组件中定义,那么最外层的组件就称为父组件,里层的组件称为子组件

let child = {
  data(){
    return {
      count: 0
    }
  },
  template: `
<div>
child:{{count}}
<button @click="count++">+</button>
</div>
`
}
let parent = {
  data(){
    return {
      count: 0
    }
  },
  components:{
    child: child
  },
  template: `
<div>
parent:{{count}}
<button @click="count++">+</button>
<child></child>
</div>
`
}

let app = new Vue({
  el: '#app',
  components: {
    parent: parent
  },
  data: {

  }
})

上面定义了parent组件和child组件,将child组件注册到parent中,parent组件注册到vue实例中,对于child来说,parent组件就是它的父组件
使用时只需要使用父组件就可以将以注册的子组件也展示出来

<div id="app">
  <parent></parent>
</div>

image.png
父子组件除了可以独立使用、嵌套使用之外,还可以通过一些方式实现父子组件之间相互传值
父组件向子组件传值
对于父组件来说,子组件和普通的标签一样,只需要使用v-model绑定值即可,需要做的是子组件在自己的options中配置好可以接受哪些属性,这些属性和data中的属性用法相同

  let child = {
    props: ['valP'],
    data(){
      return {
        count: 0
      }
    },
    template: `
      <div>
        child:{{count}}
        <br>
        valP: {{valP}}
        <button @click="count++">+</button>
      </div>
    `
  }
  let parent = {
    data(){
      return {
        count: 0
      }
    },
    components:{
      child: child
    },
    template: `
      <div>
        parent:{{count}}
        <button @click="count++">+</button>
        <child valp="parent bind value"></child>
      </div>
    `
  }

image.png
子组件的options中使用props指定自己具有的属性,具体的写法可参考官网
image.png
一般推荐使用对象写法,指定默认值、类型和是否必填
子组件向父组件传值
子组件可通过发射一个事件,在事件中通过参数的方式传值,父组件像监听普通标签的事件一样监听子组件的事件,在方法中即可获取子组件传递过来的值

  let child = {
    props: ['valP'],
    data(){
      return {
        count: 0
      }
    },
    template: `
      <div>
        child:{{count}}
        <br>
        valP: {{valP}}
        <button @click="count++">+</button>
        <button @click="emit">向父组件发送value值</button>
      </div>
    `,
    methods:{
      emit(){
        this.$emit('click', 'childvalue')
      }
    }
  }
  let parent = {
    data(){
      return {
        count: 0
      }
    },
    components:{
      child: child
    },
    template: `
      <div>
        parent:{{count}}
        <button @click="count++">+</button>
        <child valp="parent bind value" @click="clk"></child>
      </div>
    `,
    methods: {
      clk(event){
        console.log('child', event)
      }
    }
  }

当页面上点击子组件按钮后,就可以获取到子组件传递过来的值
image.png

5.父子组件相互访问

首先给父组件添加ref属性

<div id="app">
  <parent ref="parent"></parent>
</div>

在页面上可以通过此属性访问父元素
image.png
通过父组件中的$children属性可以直接访问到子组件中的所有信息,比如访问它的属性值
image.png
同样的方式,通过子组件的中的属性也可以找到父组件,比如访问父组件中的属性值
image.png
因此,只要是有关系的组件,都可以通过一个将其全部找出来,如果没有关系的,可以通过定义ref属性直接访问,所有的组件都是vue实例的子组件
除了父子组件之外,还会有其他没有关系的组件,这些组件之间的访问方式和值的传递方式就需要用到vuex

Logo

前往低代码交流专区

更多推荐