关于vue.js组件数据流的问题

一、组件

组件,可以说是现代前端框架中必不可少的组成部分。使用组件,不仅能极大地提高代码的复用率和开发者的开发效率,对于代码后期的维护也有着非常重要的意义。前端开发,由于历史遗留原因,WebComponent 虽然好用,但其发展情况却受到极大地限制,和很多新兴的前端技术一样,可望而不可即。基于这样的情况,聪明的开发者们尝试通过框架内部集成相应的功能来完成组件化,各种现代前端框架基本上都有各自的实现。这里我们来分析一下 vue 的组件,重点关注数据的流向。

二、vue 组件

vue 的组件,创建模板的时候是基于普通的 html 的,不需要学习 jsx、handlebars 等的特殊语法,所以相对来说,学习成本比较低,更容易上手。使用 vue 组件的时候,一般分为组件注册和组件调用两个部分。

(一)组件注册

Vue.component('pop-box', {
  template:  '<div class="component-box">\
    <div class="component-content">\
    ..........
    </div>\
  </div>',

  props: [...],

  data: function () {
    return ...;
  },

  methods: {
    ...
  },

  mounted () {
    ...
  },

  ...
});

利用 Vue.component 方法我们可以很轻松的创建一个全局可用的组件,当然也可以在实例或组件内部注册局部组件,但原理大同小异。Vue.component 的第一个参数是组件的名字,或者说唯一标识符(id),后续调用它将通过这个名字进行调用;第二个参数是一个对象,通常它包含了模板(template)、组件内维护的数据(data、computed)、方法(methods)、钩子函数(created 、 mounted...)等关键信息。

值得注意的是:

  1. 组件内的 data 必须是一个函数,它的返回值将作为实际的 “data”;
  2. vue1.x 和 vue2.x 的钩子函数略有不同,如果发现钩子函数不生效,记得确认 vue 的版本。

(二)组件调用

(1)开始标签 + 结束标签模式

<pop-box text="200" v-bind:number="200"></pop-box>

(2)无结束标签模式

<pop-box text="200" v-bind:number="200" />

调用 vue 组件有以上两种模式。两种模式上,如果没有使用 slot 那么实际上并没有任何区别,但如果需要使用 slot 的时候,便只能使用同时包含开始标签和结束标签的模式。

值得注意的是,上面绑定数据的时候,直接采用 property="value" 的形式,不管 value 是数字还是字符串,property 最终都是字符串类型。如果想让其变成数字类型,请使用 v-bind:property="value" 的形式,或者简写为 :property="value" 。

三、vue 组件数据流

vue 遵循了典型的单向数据流的原则,即数据总是由父组件传递到子组件,子组件在其内部可以有自己维护的数据,但它无权修改父组件传递给它的数据,当开发者尝试这样做的时候,vue 将会报错。这样做的好处是,防止多个子组件都尝试修改父组件状态时,让这一行为变得难以追溯。vue 中具体实现方式如下:

父组件通过绑定 props 的方式,将数据传递给子组件,但是子组件自己并没有权利修改这些数据,如果要修改,只能把修改这一个行为通过 event 的方式报告给父组件,由父组件本身决定改如何处理数据。

(一)简单实例

<div id="app">
  <my-counter @inc="increase" :counter="counter"></my-counter>
</div>
...
Vue.component('my-counter', {
  template:  '<div class="counter">\
    <div>{{counter}}</div>\
    <button @click="inc">increase</button>\
  </div>',

  props: ['counter'],

  methods: {
    inc: function () {
      this.$emit('inc');
    }
  }
});

var app = new Vue({
  el: '#app',
  data: {
    counter: 0
  },
  methods: {
    increase () {
      this.counter ++;
    }
  }
});

为了显得更简单这里只创建了一个 my-counter 组件作为子组件,我们可以姑且将 vue 的实例认为是一个父组件。

(二)分析数据流向分析

(1)我们在父组件中定义了一个数据叫 counter;
(2)调用组件的时候,通过 :counter="counter" 的方式,将父组件的 counter 以 prop 的方式传递到子组件中;
(3)子组件读取到 counter,并将其展示在模板中;
(4)用户点击按钮,counter 需要增加;
(5)子组件监听到这个事件,但它并不直接修改 counter,而是通过 this.$emit('inc'); 以自定义事件的形式,将需要增加的这一个事件报告给父组件;
(6)父组件中,由于通过执行过 @inc="increase" ,能够监听到子组件报告过来的事件,并在自己的 increase 方法中,实现 counter 的增加;
(7)父组件里的数据更新了,子组件里的数据也将自动更新,同时也将更新界面内容,这一过程由框架自动完成。

(三)总结

上面这一个示例,基本完整展示了 vue 主要的数据流向,但是这种基于 prop/evnet 的方式仅适用于存在直接的父子关系的组件,兄弟组件或者大量组件的数据流向如果再基于这种方式将会变得非常麻烦,这时可以考虑使用更加强大的状态管理模式。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2017-07-24

Vue.js组件使用开发实例教程

组件 组件可以扩展HTML元素,封装可重用的代码,在较高的层面上,组件是自定义元素,vue.js的编译器为它添加特殊功能,在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展. Vue.js的组件可以理解为预先定义好了行为的ViewModel类.一个组件可以预定义很多选项,但最核心的是以下几个: 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系. 初始数据(data):一个组件的初始数据状态.对于可复用的组件来说,这通常是私有的状态. 接受的外部参数(p

深入探讨Vue.js组件和组件通信

基本是按照官网的 Guide 全部梳理了一遍:http://vuejs.org/guide/index.html 这里我们以一个 Todo List 应用为例来把相关的只是都串起来,这篇里面的全部代码都在github上 https://github.com/lihongxun945/vue-todolist  Vue 实例 一个 Vue 应用是由一个 root vue instance 引导启动的,而 Vue instance 是这么创建的: var vm = new Vue({ // opti

vue.js表格组件开发的实例详解

前言 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 组件开发的基础 组件可以扩展 HTML 元素,封装可重用的代码.我理解为功能模块的模板吧. 对于vue来说,组件是这个样子的,我们在html里面写 <div id="example"> <my-compone

Vue.js一个文件对应一个组件实践

这方面官网给的示例是需要工具来编译的,但是nodejs又没有精力去学,只好曲线救国.VueJS的作者在另一个网站有一篇文章讲到可以用jQuery.getScript或RequireJS实现组件,却没有给示例,于是自己摸索出了一种方法. 用到的工具: vue.js --- 0.12.+ (需要0.12中async component支持) require.js text.js --- RequireJS text plugin https://github.com/requirejs/text 文

Vue.js组件tabs实现选项卡切换效果

今天给大家分享一个小颖自己写的vue组件,因为小颖也才接触vue没多久,如果有什么不足的地方,希望大家提出来,小颖加以改正.以下就是具体如何实现tabs啦. 调用示例: <template> <div class="tabs-contents"> <!-- 调用tabs组件 --> <tabs :flag.sync='tabsShowFlag' :navtitle='navTitle' :navdata='navData'> <di

Vue.js路由组件vue-router使用方法详解

使用Vue.js + vue-router 创建单页应用是非常简单的.只需要配置组件和路由映射,然后告诉 vue-router 在哪里渲染即可. 一.普通方式基本例子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue-router使用方法</title> </head> <bod

Vue.js每天必学之组件与组件间的通信

什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 使用组件 注册 之前说过,我们可以用 Vue.extend() 创建一个组件构造器: var MyComponent = Vue.extend({ // 选项... }) 要把这个构造器用作组件,需要用 `Vue.compone

详解vue.js2.0父组件点击触发子组件方法

之前关于vue.js2.0父组件的一点学习,最近需要回顾,就顺便发到随笔上了 <body> <div id="counter-event-example"> <p>{{ total }}</p> <button-counter v-on:ee="incrementTotal"></button-counter> <button-counter v-on:ee="increment

强大Vue.js组件浅析

什么是组件:组件是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能.在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展. 如何注册组件? 需要使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件.Vue.extend方法格式如下: var MyComponent = Vue.extend({ // 选项...后面再介绍 }) 如果想要其他地方使用这个创

详解vue.js组件化开发实践

前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然成为了第一个问题.鉴于目前web前端mvvm框架以及组件化开发方式的流行,决定技术栈采用:vue + es6 + 组件化. 这里首先简单说下web前端组件化开发方式的历程: 最早的组件化结构,代码结构可能如下: - lib/components/calendar |- calendar.css |-

Vue.js组件通信的几种姿势

写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出. 文章的原地址: https://github.com/answershuto/learnVue . 在学习过程中,为Vue加上了中文的注释 https://github.com/answershuto/learnVue/tree/master/vue-src ,希望可以对其他想学习Vue源码的小伙伴有所帮助. 可能会有理解存在偏差的地方,欢迎提issu

Vue.js组件tab实现选项卡切换

本文实例为大家分享了vue插件tab选项卡的具体代码,供大家参考,具体内容如下 效果图: 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> *{padding: 0;margin:

分分钟玩转Vue.js组件(二)

.btn-demo { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; background-color: #19b586; text-decoration: none; border: none; border-radius: 4px; color: #fff !important; text-decoration: none !important; cursor: poi

Vue.js组件tree实现无限级树形菜单

分享一段用 <ul>和<li>标签实现tree的代码,可能写的不是很好,如果大家有更好的希望分享下. 代码看这里喽: html代码: <div class="tree"> <nav class='navbar'> <ul class='nav nav-stacked'> <template v-for='item in menus'> <li role='presentation' v-if='!item.c

分分钟玩转Vue.js组件

组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢? 组件可以扩展HTML元素,封装可重用的HTML代码,我们可以将组件看作自定义的HTML元素. 组件的创建和注册 基本步骤 Vue.js的组件的使用有3个步骤:创建组件构造器.注册组件和使用组件. 下面的代码演示了这3个步骤: <!DOCTYPE html> <html> <body> <

Vue.js组件间通信方式总结【推荐】

平时在使用Vue框架的业务开发中,组件不仅仅要把模板的内容进行复用,更重要的是组件之间要进行通信.组件之间通信分为三种:父-子:子-父:跨级组件通信.下面,就组件间如何通信做一些总结. 1.父组件到子组件通过props通信 在组件中,使用选项props来声明需要从父级组件接受的数据,props的值可以是两种:一种是字符串数组,一种是对象.props中声明的数据与组件data函数return的主要区别在于props来自父级,而data中的组件是自己的数据,作用域是组件本身,这两种数据都可以在模板t