⑥ 组件化开发

  • 模块开发 -> 组件 Component -> 代码复用、便于维护

1. 组件是什么?

  • 组件是可复用的 Vue 实例,且带有一个名字。它们与 new Vue 接收相同的选项

2. data 必须是一个函数

  • 每个组件都会各自独立维护它的 data

  • 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝

3. 通过 props [字符串数组] 向子组件传递数据 + 函数:父传子

  • props 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个属性。

  • 一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在组件实例中访问这个值,就像访问 data 中的值一样。

  • 可以使用 v-bind 来动态传递 prop

<!-- 父组件 -->
<container :title="mytitle" :backMethods="getItem"></container>

data() {
  return {
    mytitle: 'my happy job'
  }
},
methods: {
    getItem() {
        // 函数体
    }
}

<!-- 子组件 -->
Vue.component('container', {
  // props: ['title'],
  props: {
    title: {type: String},
    backMethods: {type: Function}
  }
  template: '<h3>{{ title }}</h3>'
})

4. 监听子组件事件:子传父

  • 子组件可以通过调用内建的 $emit 方法并传入事件名称来触发一个事件
<!-- 父组件 -->
<container
  ...
  v-on:enlarge-text="postFontSize += 0.1"
></container>

<!-- 子组件 -->
<button v-on:click="$emit('enlarge-text')">
  Enlarge text
</button>
  • 使用事件抛出一个值 -- 在父级组件监听这个事件时,可通过 $event 访问到被抛出的这个值
<!-- 父组件 -->
<container
  ...
  v-on:enlarge-text="postFontSize += $event"
></container>

<!-- 子组件 -->
<button v-on:click="$emit('enlarge-text', 0.1)">
  Enlarge text
</button>

<!-- 父组件 -->
<container 
    ... 
    v-on:enlarge-text="onEnlargeText" 
></container>
methods: { 
  onEnlargeText: function (enlargeAmount) { 
    this.postFontSize += enlargeAmount 
  } 
}

<!-- 子组件 -->
<button v-on:click="$emit('enlarge-text', 0.1)">
  Enlarge text
</button>
  • 在组件上使用 v-model
<!-- 父组件 -->
<container v-model="searchText"></container>

<container 
    v-bind:value="searchText" 
    v-on:input="searchText = $event" 
></container>

<!-- 子组件 -->
Vue.component('container', {
  model: {
    prop: 'checked',
    event: 'change'
  },
    props: ['checked'],
    template: `
        <input
       type="checkbox"
            v-bind:checked="checked"
            v-on:input="$emit('change', $event.target.checked)"
        >
    `
})

5. 单文件组件 -- 高内聚,低耦合。易维护

  • 优点:完整语法高亮;commonJS 模块;组件作用域的 css
<template>
    <div class="container"></div>
</template>
<script>
    export default {
        name: 'cointainer',
        data() {
            return {

            }
        }
    }
</script>
<style>
</style>

6. prop

  • 对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态

单向数据流

  • 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用
props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}
  • 这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性。
props: {
  size: {type: Number},
  backMethod: {type: Function}
},
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
},
methods: {
  returnItem(status) {
    if(status == 'cancel') {
      this.backMethods(null)
    } else if(status == 'comfirm') {
      if(this.getItem == null) {
        this.backMethods(0)
      } else {
        this.backMethods(this.getItem)
      }
    }
  }
}
  • 禁用 attribute 继承 --- inheritAttrs: false  

  • inheritAttrs: false 选项不会影响 styleclass 的绑定

7. 自定义事件

  • 推荐始终使用 kebab-case 的事件名,因为 v-on 事件监听器在 DOM 模板中会被自动转换为全小写
原文地址:https://www.cnblogs.com/pleaseAnswer/p/13324165.html