【vue-03】组件化开发 component

vue组件化思想

组件化是vue的一个重要思想

它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构建我们的应用。

任何的应用都会被抽象成一颗组件树。

IMG_256

注册组件

组件的使用分成三个步骤:创建组件构造器、注册组件、使用组件。

注意:不论使用哪一种注册方式,template属性只能有一个,并且有且仅有一个根节点。

<body>
  <div id="app">
    <my-component></my-component>
    <my-component2></my-component2>
    <my-component3></my-component3>
    <my-component4></my-component4>
  </div>
</body>

<template id="temp">
  <div>
    <p>我是p标签</p>
    <h1>我是h1标签</h1>
    <div style="color: red;">哈哈哈</div>
  </div>
</template>
<script>
  var num = 10
  /**
   * 1 使用Vue.extend来注册 组件
   * 按照了Java的开发思想,变量名往往是驼峰规则。
   * 但是使用组件的时候一般不使用驼峰规则
   * 而是将驼峰规则全部改成小写,然后中间用-连接
   */
  Vue.component('myComponent', Vue.extend({
    // template就是组件要展示的内容,可以是html标签
    template: '<h3>这是用extend注册的组件</h3>'
  }))
  /**
   * 2.不使用extend去注册组件
   */
  Vue.component('myComponent2', {
    // template就是组件要展示的内容,可以是html标签
    template: '<div><h3>这是不用extend注册的组件</h3><h3>我是第二个h3</h3></div>'
  })
  // 不论使用哪一种注册方式,template属性只能有一个,并且有且仅有一个根节点。
  
  Vue.component('myComponent3', {
    // template就是组件要展示的内容,可以是html标签
    template: `<div><h3>组件中使用外部变量num:${num}</h3></div>`
  })
  // 3.使用template
  Vue.component('myComponent4', {
    template: '#temp'
  })
  let app = new Vue({
    el: '#app'
  })
</script>

私有组件

我们上面使用Vue.component注册组件时,注册的是全局的组件。这意味着我们可以再任意的Vue实例中,使用该组件

如果我们想要注册一个局部的私有组件,可以将组件挂载到某个实例上。

<body>
  <div id="app">
    <my-component></my-component>
    <my-comp></my-comp>
  </div>
  <div id="app2">
    <my-component></my-component>
  </div>
</body>

<script>
  /**
   * 注册的是全局组件
   */
  Vue.component('myComponent', Vue.extend({
    // template就是组件要展示的内容,可以是html标签
    template: '<h3>这是用extend注册的组件</h3>'
  }))
  let myComp = Vue.extend({
    // template就是组件要展示的内容,可以是html标签
    template: '<h3>我是私有组件</h3>'
  })
  let app = new Vue({
    el: '#app',
    components: {
      myComp 
      //'myComp':myComp 当名字和变量名相同的时候,名字可以省略
    }
  })
  let app2 = new Vue({
    el: '#app2'
  })
</script>

父子组件

​ 前面我们看到了组件树,组件和组件之间存在层级关系。这就是父组件与子组件。组件中也有components关键字,同样是使用components将子组件注册到父组件。

<body>
  <div id="app">
    <parent-com></parent-com>
  </div>
</body>

<script>
  // 1.创建一个子组件
  let childCom = Vue.extend({
    template: `
      <div>我是子组件内容。</div>
  })
  // 2.创建一个父组件
  let parentCom = Vue.extend({
    template: `
      <div>
        <h1>我是父组件内容</h1>
        <child-com></child-com>
      </div>
    `,
    components: {
      childCom
    }
  })
  let app = new Vue({
    el: '#app',
    components: {
      parentCom
    }
  })
</script>

组件的数据

组件是一个单独的功能模块的封装,这个模块有属于自己的HTML模板,也应该有属于自己的data。

我们先测试一下组件是否能使用Vue实例中的data。

<body>
  <div id="app">
    <my-com></my-com>
  </div>
</body>

<script>
  let myCom = Vue.extend({
    template: `<div>我是组件{{msg}}</div>`
  })
  let app = new Vue({
el: '#app',
    data: {
      msg: '哈哈哈'
    },
    components: {
      myCom
    }
  })
</script>

经过测试,我们发现不能使用。即使可以使用,如果将所有的数据都放到vue实例中,vue实例是不是会变得非常臃肿。

那么 组件的数据存放到哪里?

组件也有个data属性、methods、filters等等等等,使用方式与vue一致(data不一样。)

Data必须是一个方法,返回一个对象。其他的与vue实例使用方式一样。

<script>
  let myCom = Vue.extend({
    template: `<div>我是组件{{msg}}</div>`,
    data() {
      return {
        msg: '我是子组件的msg'
      }
    }
  })
  let app = new Vue({
    el: '#app',
    data: {
      msg: '哈哈哈'
    },
    components: {
      myCom
    }
  })
</script>

组件的通信

在开发中,往往会存在这个场景,让子组件使用父组件的数据。

比如我们从后台获取到一些数据后,这些数据需要传递到子组件去使用,或者我们获取到了很多的数据,这些数据分别需要分发到下面的各个子组件中使用。怎么操作?

父组件向子组件传值 props

组件中,可以使用props来声明需要从父级接受到的数据。

使用:

  1. 首先在父组件中使用v-bind将数据绑定给子组件
  2. 再在子组件中,使用props接收。

propsdatamethods平级,有两种使用方式。

  1. 字符串数组,数组中的字符串就是传递时的名称。
 props: [
      // 第二步,使用props接收.
      'msg'
    ]

具体例子

<body>
  <div id="app">
    <!-- 第一步,用绑定的方式,将父组件的数据绑定给子组件 -->
    <my-com :msg="msg"></my-com>
  </div>
</body>
<template id="myTemp">
  <div>
    <span>当前数量:{{count}}</span>
    <div>{{msg}}</div>
  </div>
</template>
<script>
  let myCom = Vue.extend({
    template: '#myTemp',
    data() {
      return {
        count: 0
      }
    },
    props: [
      // 第二步,使用props接收.
      'msg'
    ]
  })
  let app = new Vue({
    el: '#app',
    data: {
      msg: '我是父组件的msg'
    },
    components: {
      myCom
    }
  })
</script>
  1. 对象,对象可以设置传递时的类型和默认值。

Type支持的类型:String、Number、Boolean、Array、Object、Date、Function、Symbol

props: {
      msg: {
        type: String,
        default: '我是默认值,父组件没有传给我msg'
      }
    }

具体例子

<body>
  <div id="app">
    <!-- 第一步,用绑定的方式,将父组件的数据绑定给子组件 -->
    <my-com :msg="msg"></my-com>
  </div>
</body>
<template id="myTemp">
  <div>
    <span>当前数量:{{count}}</span>
    <div>{{msg}}</div>
  </div>
</template>
<script>
  let myCom = Vue.extend({
    template: '#myTemp',
    data() {
      return {
        count: 0
      }
    },
    // 第二步,使用props接收.
    props: {
      msg: {
        type: String,
        default: '我是默认值,父组件没有传给我msg'//如果父组件没有绑定的时候显示
      }
    }
  })
  let app = new Vue({
    el: '#app',
    data: {
      msg: '我是父组件的msg'
    },
    components: {
      myCom
    }
  })
</script>

父组件向子组件传递方法 $emit

我们可以使用自定义事件来完成。父组件调用子组件的方法,使用$emit来实现。

<body>
  <div id="app">
    <!-- 第一步,在子组件上,使用@符号为该组件绑定一个事件 -->
    <my-com @alert-msg="alertMsg"></my-com>
  </div>
</body>
<template id="myTemp">
  <div>
    <button @click="handlerMethod">点我</button>
  </div>
</template>
<script>
  let myCom = Vue.extend({
    template: '#myTemp',
    methods: {
      handlerMethod() {
        // 第一个参数表示要调用的方法。用alert-msg,而不是alertMsg
        // 第二个参数往后,就是我们需要传递的参数
        this.$emit('alert-msg', '调用')
      }
    }
  })
  let app = new Vue({
    el: '#app',
    data: {
      msg: '我是父组件的msg'
    },
    methods: {
      alertMsg(msg) {
        alert(msg)
      }
    },
    components: {
      myCom
    }
  })
</script>

父组件调用子组件方法 $refs

$refs是和ref一起使用的。通过ref给某个子组件绑定一个特定的ID,然后我们使用$refs.ID就可以访问到子组件了。

<body>
  <div id="app">
    <button @click="countAdd">点我</button>
    <!-- 第一步,给子组件绑定一个ref -->
    <my-com ref="myComp"></my-com>
  </div>
</body>
<template id="myTemp">
  <div>
    {{count}}
  </div>
</template>
<script>
  let myCom = Vue.extend({
    template: '#myTemp',
    data() {
      return {
        count: 1
      }
    },
    methods: {
      addCount() {
        this.count++
      }
    }
  })
  let app = new Vue({
    el: '#app',
    methods: {
      countAdd() {
        // 第二步,在父组件中使用this.$refs.id就行了
        console.log(this.$refs.myComp.count)
        this.$refs.myComp.addCount()
      }
    },
    components: {
      myCom
    }
  })
</script>
原文地址:https://www.cnblogs.com/10134dz/p/13594997.html