13 vue 组件化 父子组件

6/30/2021 vue

组件基础 — Vue.js (opens new window)

# 组件化创建与注册

Vue.extend Vue.component

<div id="app">
  <!--3.使用组件-->
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
  <div>
      <my-cpn></my-cpn>
  </div>
</div>

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

  // 2.注册组件 (全局组件)
  Vue.component('my-cpn', cpnC)

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })

</script>

# 全局组件 & 局部组件

注册的位置不一样

<script>
  // 1.创建组件构造器
  const cpnC = Vue.extend({
    template: `
      <div>
        <h2>我是标题</h2>
        <p>我是内容,哈哈哈哈啊</p>
      </div>
    `
  })

  // 2.注册组件(全局组件, 意味着可以在多个Vue的实例下面使用)
  // Vue.component('cpn', cpnC)

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      // 局部组件,"cpn" 是使用组件时的标签名
      cpn: cpnC
    }
  })

  const app2 = new Vue({
    el: '#app2'
  })
</script>

# 父组件 子组件

子组件只能在直接父组件中使用,无法在祖父组件中使用(除非另外注册)

root -> cpn2 -> cpn1

<script>
  // 1.创建第一个组件构造器(子组件)
  const cpnC1 = Vue.extend({
    template: `
      <div>
        <h2>我是标题1</h2>
        <p>我是内容, 哈哈哈哈</p>
      </div>
    `
  })

  // 2.创建第二个组件构造器(父组件)
  const cpnC2 = Vue.extend({
    template: `
      <div>
        <h2>我是标题2</h2>
        <p>我是内容, 呵呵呵呵</p>
        <cpn1></cpn1>
      </div>
    `,
    components: {
      cpn1: cpnC1
    }
  })

  // root组件
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn2: cpnC2
    }
  })
</script>

# 组件注册简化写法

// 定义一个名为 button-counter 的新组件(全局组件)
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
  // 注册局部组件的简化写法
  const app = new Vue({
    el: '#app',
    components: {
      'cpn2': {
        template: `
          <div>
            <h2>我是标题</h2>
            <p>我是内容</p>
          </div>
    `
      }
    }
  })

# 模版定义的抽离

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

<template id="cpn">
  <div>
    <h2>我是标题</h2>
    <p>我是内容,呵呵呵</p>
  </div>
</template>

<script>

  // 注册一个全局组件
  Vue.component('cpn', {
    template: '#cpn'
  })

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })
</script>

# 组件中的 data 必须是一个函数

组件多实例的数据共享问题

组件基础 — data 必须是一个函数 (opens new window)

# 通过 Prop 向子组件传递数据

组件基础 — 通过 Prop 向子组件传递数据 (opens new window)

API — props (opens new window)

这里的文档很详细了: Prop — Vue.js (opens new window)

静态赋值:

<blog-post title="My journey with Vue"></blog-post>

动态绑定(v-bind):

<!-- 动态赋予一个变量的值 -->
<blog-post v-bind:title="post.title"></blog-post>

<!-- 动态赋予一个复杂表达式的值 -->
<blog-post
  v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>

注意:
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。

# Prop 的大小写 (camelCase vs kebab-case)

<div id="app">
  <!-- 这里 c-info 是 html 属性,需要是 kebab-case -->
  <cpn :c-info="info" :child-my-message="message" v-bind:class></cpn>
</div>

<template id="cpn">
  <div>
    <!-- 这里是引用标量,使用变量的真实名称 -->
    <h2>{{cInfo}}</h2>
    <h2>{{childMyMessage}}</h2>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    props: {
      // js 代码中的命名 camelCase
      cInfo: {
        type: Object,
        default() {
          return {}
        }
      },
      childMyMessage: {
        type: String,
        default: ''
      }
    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      info: {
        name: 'why',
        age: 18,
        height: 1.88
      },
      message: 'aaaaaa'
    },
    components: {
      cpn
    }
  })
</script>

# 监听子组件事件

组件基础 — 监听子组件事件 (opens new window)

API — emit (opens new window)

自定义事件 — Vue.js (opens new window)

# 访问元素 & 组件

  • $children
  • $refs
  • $parent

处理边界情况 — 访问元素 & 组件 (opens new window)

  • $children 在父组件的代码中,使用 this.$children 访问所有的子组件

  • $refs

<!-- 对子组件的使用 -->
<cpn ref="usernameInput"></cpn>
// 引用这个组件
this.$refs.usernameInput
  • $parent

在子组件的代码中,使用 this.$parent 访问父组件

访问父组件会破坏子组件的独立性,增加耦合

  • $root

访问根组件

更新时间: Sunday, July 4, 2021 15:59