vue组件化开发

一、注册组件步骤

1.Vue.extend():

  • 调用Vue.extend()创建的是一个组件构造器
  • 通常在创建组件构造器时,传入template代表自定义的组件模板
  • 该模板就是要显式的HTML代码。

2.Vue.component():

  • 调用Vue.component()将组件构造器注册成一个组件,并给它起一个组件的标签名称
  • 需要传递两个参数:1.注册组件的标签名 2.组件构造器

3.组件必须挂载在Vue的实例下,否则不会生效

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>

  <div id="app">
    <my-cpn></my-cpn>
    <my-cpn></my-cpn>
    <my-cpn></my-cpn>
  </div>

</body>
<script src="../js/vue.js"></script>
<script>
  // 1.创建组件构造器对象
  const cpnC = Vue.extend({
    template: `
    <div> 
      <h2>标题</h2>
      <p>内容111</p>
    </div>`
  })

  // 2.注册组件
  Vue.component('my-cpn', cpnC) //全局注册 ,全局组件可以在多个vue实例中使用
  const app = new Vue({
    el: "#app",
    data: {

    },
    //局部组件, 只能在指定的vue实例中使用
    components: {
      cpn: cpnC
    }

  })
</script>

</html>

二、注册组件的语法糖

省略Vue.extend(),直接使用对象代替

<script>
  // 全局注册
  Vue.component('cpn1', {
    template: `
    <div> 
      <h2>标题1</h2>
      <p>内容111</p>
    </div>`
  })

  const app = new Vue({
    el: "#app",
    data: {

    },
    // 局部注册
    components: {
      cpn2: {
        template: `
    <div> 
      <h2>标题2</h2>
      <p>内容222</p>
    </div>`
      }
    }

  })
</script>

三、模板分离的写法

1.通过script标签

 <!-- script标签,类型必须是text/x-template -->
 <script type="text/x-template" id="cpn">
 <div> 
      <h2>标题1</h2>
      <p>内容111</p>
    </div>
</script>

Vue.component('cpn', {
    template: '#cpn'
  })

2.通过template标签

<template id="cpn">
    <div>
      <h2>标题2</h2>
      <p>内容222</p>
    </div>
</template>

Vue.component('cpn', {
  template: '#cpn'
})

四、组件存放数据

组件对象也可以通过data属性存放数据,但data必须是一个函数,而且需要返回一个对象,对象内部存放数据。

<template id="cpn">
    <div>
      <h2>{{title}}</h2>
      <h2>标题2</h2>
      <p>内容222</p>
    </div>
  </template>

Vue.component('cpn', {
    template: '#cpn',
    data() {
      return {
        title: 'abc'
      }
    }

  })

为什么必须是函数?
每个组件实例的函数会返回一个单独的对象,每个对象之间不会相互影响,反而言之,返回同一个对象 会造成组件之间相互影响

五、父子组件通信

子组件不能引用父组件或者Vue实例中的数据,但实际开发中需要将数据从父组件传递给子组件,或者子组件发送给父组件。
比如: 服务器返回的数据有一部分是要给子组件展示的,这个时候就需要父传子了。

  • 通过props向子组件传递数据
  • 通过事件向父组件发送消息
  1. 父组件向子组件传递数据

1.1首先在父组件中注册子组件,
1.2在子组件中通过props定义变量接收,
1.3通过绑定属性的形式将值传递给子组件<cpn :cmovies="movies" :cmessage="message"></cpn>
1.4子组件中就可以使用传递过来的值了。

<body>
  <div id="app">
    <cpn :cmovies="movies" :cmessage="message"></cpn>
  </div>
  <template id="cpn">
    <div>
      {{cmovies}}
      <h2>{{cmessage}}</h2>
    </div>
  </template>
</body>
<script src="../js/vue.js"></script>
<script>

  // 父传子 props
  const cpn = {
    template: '#cpn',
    // props: ['cmovies', 'cmessage']
    props: {
      cmessage: {
        // 类型限制
        type: String,
        // 默认值
        default: '我很好',
        required: true
      },
      cmovies: {
        type: Array,
        default() {
          return ['aaa', 'bbb']
        }
      }
    }
  }

  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊",
      movies: ['海王', '海贼王', '海尔兄弟']
    },
    components: {
      cpn
    }
  })
</script>

注:> 类型是对象或者是数组时,默认值必须是一个函数

v-bind属性绑定时,不支持驼峰命名,例如(cInfo需改为c-info)。

  1. 子组件向父组件传递数据

2.1在子组件中通过$emit发射自定义事件
2.2在父组件中监听自定义事件

<!-- 子组件 -->
  <template id="cpn">
    <div>
      <button v-for="item in categories" @click="btnClick(item)">
        {{item.name}}
      </button>
    </div>
  </template>

<!-- 父组件 -->
  <div id="app">
    <cpn @item-click="cpnClick"></cpn>
  </div>
  
<script>
  // 子组件  
  const cpn = {
    template: '#cpn',
    data() {
      return {
        categories: [
          { id: 'aaa', name: '热门推荐' },
          { id: 'bbb', name: '手机数码' },
          { id: 'ccc', name: '家用电器' },
          { id: 'ddd', name: '电脑办公' },
        ]
      }
    },
    methods: {
      btnClick(item) {
        // 子组件发射事件
        this.$emit('item-click', item)
      }
    }
  }
  const app = new Vue({
    el: "#app",
    methods: {
      cpnClick(item) {
        console.log('cpnClick', item)
      }
    },
    components: {
      cpn
    }
  })

六、父子组件直接访问

1.父组件通过$children直接访问子组件

在父组件中通过$children获取的是一个vue组件数组,可以调用里面的方法

2.父组件通过$refs直接访问子组件

默认返回的是一个空对象,需要在应用子组件的地方加上ref="xxx"

  <!-- 父组件 -->
  <div id="app">
    <cpn></cpn>
    <cpn ref="aaa"></cpn>
    <button @click="btnClick">点击</button>
  </div>

  <!-- 子组件 -->
  <template id="cpn">
    <div>
      子组件
    </div>
  </template>
</body>
<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    data() {
      return {
      }
    },
    methods: {
      showMessage() {
        console.log('showMessage111')
      },
    }
  }
  const app = new Vue({
    el: "#app",
    methods: {
      btnClick() {
        // console.log(this.$children);
        // this.$children[0].showMessage();
        // refs 对象类型,
        console.log(this.$refs.aaa);
      }
    },
    components: {
      cpn
    }
  })
</script>
  1. 子组件通过$parent访问父组件,使用较少
    4.访问根组件 $rootvue实例。
posted @ 2019-10-15 09:01  学一点也是好  阅读(...)  评论(...编辑  收藏