从简单的列表页浅谈Vue组件

组件

什么是组件?

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 js 特性扩展。

例子

从简单的列表页浅谈Vue组件_第1张图片
screen.png

举个小例子:豆瓣电影排行榜

此例子包含文章列表,分页,这里把列表和分页分别当作单独的组件,加上父页面组件一共是3个

父组件:app.vue

子组件:list.vue pagination.vue

接口用的是豆瓣的jsonp,https://api.douban.com/v2/movie/top250

首先在main.js引入父组件,引入less,引入VueResource,实例化vue

//main.js

import Vue from 'vue'
import app from './example1/app.vue'
import './example1/style.less'

import VueResource from 'vue-resource'
Vue.use(VueResource)

new Vue({
  render: h => h(app)
}).$mount('#app')

从分页开始,在src/example1/components文件夹下建立一个pagination.vue文件





通过props从父组件接收数据。组件可以为props指定验证要求。如果未指定验证要求,Vue会发出警告,如果不需要验证,可以用数组形式

//pagination.vue

props: {
    //当前页码
    now: {
      type: Number,
      default: 1
    },
    //总页数
    all: {
      type: Number,
      default: 1,
      required: 1
    }
  }

父组件app.vue引入组件,并且把数据传给子组件








根据传入的数据计算分页数据

//pagination.vue

computed: {
    pages () {
      var pages = [];
      if(this.now > 1) pages.push({
        text: '上一页',
        num: this.now - 1
      });
      if(this.now - 1 > 2) pages.push({
        text: 1,
        num: 1
      });
      if(this.now - 1 > 3) pages.push({
        text: '...',
        num: 0
      });
      for (var i = 1; i <= this.all; i++) {
        if(this.now - i < 3 && this.now >= i || i - this.now < 3 && this.now <= i){
          pages.push({
            text: i,
            num: i
          });          
        }        
      }
      if(this.all - this.now > 3) pages.push({
        text: '...',
        num: 0
      });
      if(this.all - this.now > 2) pages.push({
        text: this.all,
        num: this.all
      });
      if(this.now < this.all) pages.push({
        text: '下一页',
        num: this.now + 1
      });
      
      return pages;
    }

  }

用v-for把分页渲染出来




子组件通过自定义事件向父组件传事件和数据

//pagination.vue

methods: {
    toPage (page) {
      this.$emit('toPage', page);

    }

  }

父组件监听这个事件,然后调用方法changePage




    

至此完成了父组件把数据丢给子组件处理,子组件把操作反馈给父组件这一过程

列表组件list.vue






来点动态的数据






几个点:

prop传递数据

组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:

自定义事件

父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件

slot分发内容

组件不知道它的挂载点会有什么内容。挂载点的内容是由父组件决定的;组件很可能有它自己的模版

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发 (或 “transclusion” 如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API ,参照了当前 Web 组件规范草案,使用特殊的 元素作为原始内容的插槽。

通过slot插槽将标题插入到子组件

作用域插槽

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译

作用域插槽是一种特殊类型的插槽,用作使用一个(能够传递数据到)可重用模板替换已渲染元素。
在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样

通过作用域插槽将子组件数据传给父组件,再作为自定义模板重新插入到子组件

计算

豆瓣接口接收参数和设计的不同,pages需要通过computed计算

分页的算法

你可能感兴趣的:(从简单的列表页浅谈Vue组件)