Vue

5. Vue 组件化

2019-05-29  本文已影响14人  璎珞纨澜

Vue 组件官网:https://cn.vuejs.org/v2/guide/components.html

组件化的思想

通过 Element 体会组件的威力

Element 是基于 Vue 开发的一个知名的第三方组件库,它能帮助我们更加快速的构建应用。
Element 官网

使用:

组件是什么

组件在代码中的直观体现就是封装了一个自定义的 HTML 标签

使用组件

组件的定义方式分为两种,全局定义和局部定义:

全局注册

注册:
基本形式:Vue.component('组件名字', 组件模板对象)
方式 一:

Vue.component('my-component', 
  Vue.extend({
    template: '<div>A custom component!</div>'
  })
)
new Vue({
  el: '#app'
})

方式二:

Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})
new Vue({
  el: '#app'
})

方式三:

<template id="tmpl">
  <div>A custom component!</div>
</template>
<script>
  Vue.component('my-component', {
    template: '#tmpl'
  })
  new Vue({
    el: '#app'
  })
</script>

方式四:

<script type="text/x-template" id="tmpl">
  <div>A custom component!</div>
</script>
<script>
  Vue.component('my-component', {
    template: '#tmpl'
  })
  var vm = new Vue({
    el: '#app'
  })
</script>

在模板中使用组件:

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

渲染结果:

<div id="app">
  <div>A custom component!</div>
</div>

局部注册

不必把每个组件都注册到全局。可以通过某个 Vue 实例/组件的实例选项 components 注册,仅作用在其作用域中可用的组件:
注册:

new Vue({
  el: '#app'
  components: {
    // <my-component> 将只能在父组件模板中可用
    // 键名就是组件名称,值是一个对象,对象中配置组件的选项
    'my-component': {
      template: '<div>A custom component!</div>'
    }
  }
})

使用:

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

组件的模板

组件的复用

data: function () {
  return {
    count: 0
  }
}

组件的组织

放到匿名自执行函数中,将某些代码包裹起来可以实现块级作用域的效果,减少全局变量的数量,减少命名冲突,在匿名自执行函数执行结束后变量就会被内存释放掉,从而也会节省了内存。

图解 Vue 组件化构建方式

从程序角度实现组件化应用构建的架构方式如下图,这种方式的缺点是:

todoMVC 的 Vue 组件化构建

组件通信

在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。


父子组件关系

父子组件通信:Props Down

  1. 在父组件中通过子组件标签声明属性的方式传递数据。注意:只有 v-bind 才可以传递动态数据。
<child message="hello!"></child>
  1. 在子组件中声明 props 接收父组件传递的数据,组件接收到 props 就可以像访问 data 中的数据一样,来访问 props 中的数据并使用。
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 就像 data 一样,prop 也可以再模板中使用
  // 同样也可以再 vm 实例中通过 this.message 来使用
  template: '<span>{{ message }}</span>'
})
  1. Vue 组件通信原则:单向数据流
    父组件数据的改变可以影响到子组件,但是子组件不要去修改父组件的数据。因为当你的组件嵌套过深的时候,在子组件中修改某个父组件的数据可能会让你的应用数据流变得非常复杂而难以理解。

注意:在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。引用类型数据虽然可以修改,但是不建议使用,因为这样就违背了 Vue 组件的通信原则

思考:那子组件要改数据呢?子组件能不能把数据给父亲呢,让父组件自己去修改自己的数据呢?

父子组件通信:Event Up

父组件使用 prop 传递数据给子组件。但子组件怎么跟父组件通信呢?这个时候 Vue 的自定义事件系统就派的上用场了。

  1. 在子组件中调用 $emit() 方法发布一个事件
Vue.component('button-counter', {
  template: `<button v-on:click="incrementCounter">{{ counter }}</button>`
  data: function() {
    return {
      counter: 0
    }
  }
  methods: {
    incrementCounter: function () {
      this.counter += 1
      // 发布一个名字叫 increment 的事件
      this.$emit('increment')
    }
  }
})
  1. 在父组件中提供一个子组件内部发布的事件处理函数
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal : function () {
      this.total += 1
    }
  }
})
  1. 在子组件的模板的标签上订阅子组件内部发布的事件
<div id="counter-event-example">
  <p>{{ total }}</p>
  <!--订阅子组件内部发布的 increment 事件,当子组件内部 $emit('increment') 
      发布的时候,就会调用到父组件中的 incrementTotal 方法-->
  <button-counter @increment="incrementTotal"></button-counter>
</div>

非父子组件通信:Event Bus

专业组件通信:Vuex

箭头函数绑定父级上下的 this

路由、和服务端交互、webpack

上一篇下一篇

猜你喜欢

热点阅读