精华一页纸,长远探究前端组件化开发

深远研究前端组件化开发

2017/11/02 · 基本功技术 ·
组件化

原稿出处: 前端微志   

亚洲必赢官网 1

前者组件化开发,已经有多年的历史了,不管是服务端渲染,仍旧前者SPA,都有了相比早熟的组件化开发的方案。
随着组件化开发的推广,前端社区中进献了众多科学的前端组件,都提供开箱即用的方案,使得更好的发布组件化的优势。
前端团队内,即使有人对前者组件化的知情不够长远,就不能支付出好的机件,会给项目标保安带来更大的老本。
翻阅全文约 8 分钟。

作者:zollero

正文先发于:
新浪专栏 前端微志
微信公众号 前端微志


这几年,从陷入 “React、Vue 和 Angular
哪个品质好?”的争执,到今天的相继框架(库)的生态尤其周到,商量质量差别已经远非价值了。而境内的前端娱乐圈,最火的就是
React 和 Vue 了,而 Angular 由于历史由来,在境内的占有率确实不高。

乘机前端生态 jade、less、scss、typeScript 和 webpack
等工具的一应俱全,前端的组件化开发成效已经有了很大的提高。

专程是像 Ant Design、Element UI、iView
这几个卓越的前端组件库的风行,更是将组件化开发发挥到了极端。开发一个前端页面已经变得卓殊的长足,尤其是在做管理体系的页面,脚手架搭建、添加依赖包、配置路由、创制页面、引入组件,很快的就可以创设一个系统。

如若你须求 SEO,React 和 Vue 的 SSR 框架 Next.js 和 Nuxt.js
更是提供了开箱即用的购并方案,也使开发“同构页面系统“(谷歌(Google)It)变得更为简便易行。

上面切入主旨,深刻研商下前端组件。

Vue和微信小程序的不一致、比较

2018/08/04 · 基本功技术 ·
Vue,
小程序

原稿出处:
卖女孩的小火柴   

写了vue项目和小程序,发现两头有广大相同之处,在此想总计一下双边的共同点和区分。

原文链接
:深切琢磨前端组件化开发

同 angularJS、Vue一样,React 也是一种替换框架,拔取JSX语法举行替换

什么样是前者组件化开发

率先,大家要搞领悟什么是前者组件化开发?

你应当碰着过,将一个页面的几百行,甚至上千行的代码逻辑写在一个 js
文件中的意况。经常那种代码都很难读下去,更别说要维护起来,添加新功用,移除一些老功效了,因为您不了然改动一个地方,会不会冒出奇怪的
bug。

这些时候,你就要求采取组件化开发,拆分功用,封装组件,单独维护。

现代化前端框架平时都是兑现 MVVM 的方案,数据层(M)和
视图层(V)相互连接,同时改变,使得页面交互保持中度的一致性。

借使您熟识 Java,Python,Go 等后端开发语言,你应当对 package
(包)的概念很精通,前端的组件化在概念上与后端的 package
很相像,只然而前端的零件涉及到越来越多的是显示和互动方面的逻辑。当然,前端组件与后端架构的微服务概念类似,可以通晓成一个组件就是一个劳务组件,只提供某个服务。

前端组件化开发,就是将页面的某一局地单独出来,将这一片段的
数据层(M)、视图层(V)和
控制层(C)用黑盒的样式全方位封装到一个零部件内,揭揭发一些开箱即用的函数和属性供外部组件调用。

一个前端组件,包罗了
HTML、CSS、JavaScript,包蕴了组件的模板、样式和互相等内容,基本上涵盖了组件的富有的始末,外部只要依照组件设定的习性、函数及事件处理等展开调用即可,完全不用考虑组件的其中贯彻逻辑,对表面来说,组件是一个一心的黑盒。

组件可以多层封装,通过调用多少个小器件,最终封装成一个大组件,供外部调用。比如:一个
Input 输入框 是一个零件,一个 Select下拉挑选框
也是一个零部件,可以用 form 在那三个零件上包裹一层,就是一个 Form
的组件

有一部分相比较常用的前端组件,像 vue-router,vuex,react-router,redux,mobx
等,都是基于 Vue 和 React 的零部件,它们只注意于 路由、状态存储
的劳作,并且把这么些业务做好。

万一采纳好组件化开发,开发一个页面,如同搭积木一样,将次第零部件拼接到一起,最后融合到一块儿,就是一个总体的系统。

一、生命周期

先贴两张图:

生命周期

react.min.js – React 的焦点库

组件化开发的长处

毕竟,前端的组件化开发,可以很大程度上下滑系统依次职能的耦合性,并且增加了成效内部的聚合性。这对前者工程化及下降代码的保安的话,是有很大的利益的。

耦合性的低沉,升高了系统的伸展性,下降了付出的复杂度,提高开发效能,下降开发费用。

零件封装的好,加班也少了,bug
也少了,就有越来越多日子喝喝咖啡、打打农药了。:)亚洲必赢官网 2

vue生命周期

亚洲必赢官网 3

一个零件,需要显然了然在生命周期的不比阶段做该做的事。

react-dom.min.js – 提供与 DOM 相关的效应

怎么设计一个零部件

既是前端组件化开发这么好,那要怎么设计一个好的机件呢?

透过反复实践,统计了一部分零部件设计时的大旨绪想。

小程序生命周期

亚洲必赢官网 4

相比较,小程序的钩函数要简单得多。

vue的钩子函数在跳转新页面时,钩子函数都会接触,可是小程序的钩函数,页面不一样的跳转格局,触发的钩子并不均等。

  • onLoad: 页面加载
    一个页面只会调用一遍,可以在 onLoad 中得到打开当前页面所调用的
    query 参数。
  • onShow: 页面突显
    老是打开页面都会调用三次。
  • onReady: 页面初次渲染达成
    一个页面只会调用五回,代表页面已经准备妥当,可以和视图层进行互动。
    对界面的装置如wx.setNavigationBarTitle请在onReady随后设置。详见生命周期
  • onHide: 页面隐藏
    navigateTo或尾部tab切换时调用。
  • onUnload: 页面卸载
    redirectTonavigateBack的时候调用。

伊始化阶段,读取属性的值,假设要求做多少和逻辑处理的话,在这一个等级进行。

browser.min.js – 用于将 JSX 语法转为 JavaScript 语法

专一

要想设计一个好的机件,组件也必要专一

统筹组件要按照一个尺度:一个组件只在意做一件事,且把那件事做好

一个效果一旦得以拆分成多个成效点,那就可以将种种效用点封装成一个组件,当然也不是组件的颗粒度越小越好,只要将一个零部件内的意义和逻辑控制在一个可控的限量内即可。

举个例子。页面上有一个 Table 列表和一个分页控件,就足以将 Table
封装为一个组件,分页控件 封装成一个零部件,最终再把 Table组件 和 分页组件
封装成一个零件。Table 组件仍可以再拆分成多个 table-column
组件,及显示逻辑等。

数码请求

在页面加载请求数据时,两者钩子的施用有些近乎,vue一般会在created或者mounted中呼吁数据,而在小程序,会在onLoad或者onShow中呼吁数据。

属性值变化时,倘诺属性爆发变化,且须要对转移后的多少开展处理的话,在那个等级举办拍卖。

1、典型用法

可配置性

一个零件,要显然它的输入和输出分别是何许。

零件除了要显得默许的始末,还需求做一些动态的适配,比如:一个组件内有一段文本,一个图纸和一个按钮。那么字体的水彩、图片的规则、按钮的职位、按钮点击事件的处理逻辑等,都是足以做成可配备的。

要做可配置性,最主旨的办法是通过品质向组件传递配置的值,而在组件开始化的宣示周期内,通过读取属性的值做出相应的来得修改。还有局地格局,通过调用组件揭表露来的函数,向函数传递有效的值;修改全局
CSS样式;向组件传递特定事件,并在组件内监听该事件来实施函数等。

在做可配置性时,为了让组件尤其健全,有限支撑组件接收到的是实用的性质、函数接收到的是实惠的参数,须要做一些校验。

一. 性质的值的校验

对品质的值进行校验,一般要考虑以下多少个地点。

1.属性值的品种是还是不是是有效的。假若某个属性要求传递一个数组,那么传递过来的值不是数组时,就要抛出很是,并付诸对应的升迁。

2.属性是或不是是必填的。有的属性的值,是组件内不足缺失的时,就假若必填的,在组件初步化时要做是否传递的检查,若是没有传递,则须要抛出尤其,并提交相应的升迁。如若属性不是必填的,可以设定一个默许值,当属性没有被设置时,就接纳默许值。

得益于 React、Vue
内部贯彻的性质检查,且这个属性检查会在组件先导化阶段默许执行,你可以很简单的给组件设置属性的检讨。React
中得以应用 React.PropTypes 进行项目检查装置,Vue 中只必要给组件设置
props 即可。

在 React 中进行项目检查:

// title.jsx (Title组件) import React, { Component, PropTypes } from
‘react’; export default class Title extends Component {
constructor(props) { super(props); } static propTypes = { title:
PropTypes.string.isRequired } render() { const { title } = this.props;
return ( <p>{ title }</p> ) } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// title.jsx (Title组件)
  import React, { Component, PropTypes } from ‘react’;
 
  export default class Title extends Component {
    constructor(props) {
      super(props);
    }
 
    static propTypes = {
      title: PropTypes.string.isRequired
    }
 
    render() {
      const { title } = this.props;
 
      return (
        <p>{ title }</p>
      )
    }
  }

在 Vue 中展开项目检查:

// title.vue (Title组件) <template> <p>{{ title }}</p>
</template> <script> export default { props: { title: {
type: String, required: true } } } </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// title.vue (Title组件)
  <template>
    <p>{{ title }}</p>
  </template>
 
  <script>
    export default {
      props: {
        title: {
          type: String,
          required: true
        }
      }
    }
  </script>

二. 函数的参数的校验

函数的参数校验,只要听从传统的主意开展校验即可。在函数内部顶部判定参数的值和类型,若是不知足需求,则抛出卓殊,并交给相应的升迁。

认清一个函数的第三个必填,且为 String 格式

// ES6 语法 changeTitle(title) { if (typeof title !== ‘string’) { throw
new Error(‘必须传入一个 title,才能改改 title。’) } //
知足条件,可以进行改动 this.title = title // vue 语法 this.setState({ //
react 语法,修改state的值 title }) }

1
2
3
4
5
6
7
8
9
10
11
// ES6 语法
  changeTitle(title) {
    if (typeof title !== ‘string’) {
      throw new Error(‘必须传入一个 title,才能修改 title。’)
    }
    // 满足条件,可以进行修改
    this.title = title   // vue 语法
    this.setState({      // react 语法,修改state的值
      title
    })
  }

二、数据绑定

VUE:vue动态绑定一个变量的值为要素的某部属性的时候,会在变量前边加上冒号:,例:

<img :src=”imgSrc”/>

1
<img :src="imgSrc"/>

小程序:绑定某个变量的值为因素属性时,会用三个大括号括起来,倘若不加括号,为被认为是字符串。例:

<image src=”{{imgSrc}}”></image>

1
<image src="{{imgSrc}}"></image>

 

零件销毁阶段,假若组件已经创制了一部分可能会对系统爆发部分副效能的事物,可以在这几个等级展开消除。比如
timeInterval、timeout 等。

入门例子

生命周期

一个组件,必要鲜明知道在生命周期的两样阶段做该做的事。

初阶化阶段,读取属性的值,要是急需做多少和逻辑处理的话,在这一个等级举办。

属性值变化时,即使属性发生变化,且须求对转移后的数额举行拍卖的话,在这几个阶段展开处理。

零件销毁阶段,就算组件已经创制了部分或许会对系统发生一些副效用的事物,可以在这么些阶段展开铲除。比如
timeInterval、timeout 等。

假若组件在渲染的时候报错,必要展示错误音讯。React v16 中提供了
componentDidCatch 生命周期函数,Vue v2.5 中提供了 errorCaptured
的钩子函数。

React
中提供了有的生命周期函数:componentWillMount,componentDidMount,component威尔ReceiveProps,shouldComponentUpdate,component威尔Update,componentDidUpdate,render,component威尔Unmount,componentDidCatch(React
v16)。

Vue
中提供了一部分生命周期函数:beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed,errorCapture,errorCaptured(Vue
v2.5)。

每个生命周期的现实性用法,请参见官方详细文档。

三、列表渲染

平素贴代码,两者依然有点相似
vue:

JavaScript

<ul id=”example-1″> <li v-for=”item in items”> {{
item.message }} </li> </ul> var example1 = new Vue({ el:
‘#example-1’, data: { items: [ { message: ‘Foo’ }, { message: ‘Bar’ }
] } })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>
 
var example1 = new Vue({
  el: ‘#example-1’,
  data: {
    items: [
      { message: ‘Foo’ },
      { message: ‘Bar’ }
    ]
  }
})

小程序:

JavaScript

Page({ data: { items: [ { message: ‘Foo’ }, { message: ‘Bar’ } ] } })
<text wx:for=”{{items}}”>{{item}}</text>

1
2
3
4
5
6
7
8
9
10
Page({
  data: {
    items: [
      { message: ‘Foo’ },
      { message: ‘Bar’ }
    ]
  }
})
 
<text wx:for="{{items}}">{{item}}</text>

精华一页纸,长远探究前端组件化开发。 

一经组件在渲染的时候报错,要求出示错误音信。React v16 中提供了
componentDidCatch 生命周期函数,Vue v2.5 中提供了 errorCaptured
的钩函数。

ReactDOM.render(

事件传递

Vue 中传递事件很简短,只须要在子组件内使用 this.$emit(‘event1’)
即可向外传递一个事变 event1,在父组件调用该子组件时,只必要监听 event1
事件,并交由对应事件处理逻辑即可。

Vue中事件传递

Vue子组件定义 child-component.vue

Vue.component(‘child-component’, { methods: { emitEvent() {
this.$emit(‘event1’, ‘This is a event.’) } }, mounted() {
this.emitEvent() } })

1
2
3
4
5
6
7
8
9
10
Vue.component(‘child-component’, {
  methods: {
    emitEvent() {
      this.$emit(‘event1’, ‘This is a event.’)
    }
  },
  mounted() {
    this.emitEvent()
  }
})

Vue 父组件调用子组件

<template> <div> <child-component @event1=”eventHandler”
/> </div> </template> <script> import
childComponent from ‘./child-component’ export default { components: {
childComponent }, methods: { eventHandler(event) { console.log(event) }
} } </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
  <div>
    <child-component @event1="eventHandler" />
  </div>
</template>
 
<script>
  import childComponent from ‘./child-component’
  export default {
    components: {
      childComponent
    },
    methods: {
      eventHandler(event) {
        console.log(event)
      }
    }
  }
</script>

而在 React 中,官方并未交给组件间的事件传递解决方案,这也是 React
中相比坑的一些。不过,依旧得以采用任何格局来完毕。

React 中,父组件可以运用 props
向子组件传值,而子组件向父组件传值,须要在父组件内定义函数并透过质量传递给子组件,在子组件内经过调用该属性对应的函数,传入参数,传递给父组件内的函数,并在父组件的该函数中做逻辑的拍卖。

React 子组件定义 child-component.js

class ChildComponent extends React.Components { render() { return (
<button onClick={ () => { this.props.clickHandler(‘This is a
click’) } }></button> ) } }

1
2
3
4
5
6
7
8
9
10
11
class ChildComponent extends React.Components {
  render() {
    return (
      <button onClick={
        () => {
          this.props.clickHandler(‘This is a click’)
        }
      }></button>
    )
  }
}

React 父组件调用子组件

import ChildComponent from ‘./child-component’ class ParentComponent
extends React.Components { clickHandler(message) { console.log(message)
} render() { return ( <child-component clickHandler={
this.clickHandler.bind(this) } /> ) } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import ChildComponent from ‘./child-component’
 
class ParentComponent extends React.Components {
  clickHandler(message) {
    console.log(message)
  }
 
  render() {
    return (
      <child-component
        clickHandler={ this.clickHandler.bind(this) }
        />
    )
  }
}

四、显示与隐藏元素

vue中,使用v-ifv-show决定元素的显得和隐身

小程序中,使用wx-ifhidden操纵元素的展现和隐形

 

React
中提供了一部分生命周期函数:component威尔Mount,componentDidMount,component威尔ReceiveProps,shouldComponentUpdate,component威尔Update,componentDidUpdate,render,component威尔Unmount,componentDidCatch(React
v16)。

Hello, world!

,

document.getElementById(‘example’)

);

过程:

I、使用框架 ReactDOM.render 方法操作dom

II、首个参数时是 插入的 JSX 语法生成的要素 ;首个参数是绑定
到的DOM的节点

万一要分析 JSX,则type 要设定为

JSX:类似 HTML + JS的语法,编译后开展了优化,效能更高

2、基础概念

I、表达式

ReactDOM.render(

后记

前者组件化开发的执行,是一个很长的经过,百折不挠并不止优化,推动系统总体的优化。

末端会再改进小说,讲讲“怎么支付一个 vue 第三方组件”。

三番五次还会写越多关于 React 和 Vue 的小说,欢迎关心。

五、事件处理

vue:使用v-on:event绑定事件,或者接纳@event绑定事件,例如:

<button v-on:click=”counter += 1″>Add 1</button> <button
v-on:click.stop=”counter+=1″>Add1</button> //阻止事件冒泡

1
2
<button v-on:click="counter += 1">Add 1</button>
<button v-on:click.stop="counter+=1">Add1</button>  //阻止事件冒泡

小程序中,全用bindtap(bind+event),或者catchtap(catch+event)绑定事件,例如:

<button bindtap=”noWork”>今天不上班</button> <button
catchtap=”noWork”>明天不上班</button> //阻止事件冒泡

1
2
<button bindtap="noWork">明天不上班</button>
<button catchtap="noWork">明天不上班</button>  //阻止事件冒泡

 

Vue
中提供了一部分生命周期函数:beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed,errorCapture,errorCaptured(Vue
v2.5)。

{i == 1 ? ‘True!’ : ‘False’}

,

document.getElementById(‘example’)

);

和 angular和vue分歧的是,没有应用双括号{{}}, 而使用单括号 {}
取值和表明式运算

II、逻辑控制

因为是类HTML的语法,所以并未设计 一些 指令,都是
API操作;事件,也是应用的js 的原生事件,没有包装

React 的 JSX 使用大、小写的预订来分别本地组件的类(自定义组件)和 HTML
标签

3、绑定

同angularJS和Vue分化,React
没有绑定指令,所以她的绑定,是一直引用和操纵对象的情状(这么些目的是
state,具体参照下边关于state的叙说)

4、组件化

I、组件化的事例

var WebSite = React.createClass({

render: function() {

return (

);

}

});

var Name = React.createClass({

render: function() {

return (

有关往期小说

Vue v2.5 调整和换代不完全详解

亚洲必赢官网,React
16引入新定义“非常边界”,让您更好的拍卖模块内很是

用Next.js疾速上手React服务器渲染

内外端分离后的前端时代

1 赞 1 收藏
评论

亚洲必赢官网 5

六、数据双向绑定

各样生命周期的实际用法,请参见官方详细文档。

{this.props.name}

);

}

});

var Link = React.createClass({

render: function() {

return (

{this.props.site}

);

}

});

React.render(

,

document.getElementById(‘example’)

);

II、组件化的手续

一、注册组件

透过 React.createClass 创立类,创立一个 自定义标签替换规则

恒定属性 render 重返一个 HTML 模板

二、父控件(外层)向自定义组件(内层)传递数据

I、通过 this.props 传递数据

通过 getDefaultProps 获取默许数据

propTypes 属性可以校验传递的数额

II、操纵状态属性 state

React 把组件看成状态机,每个自定义组件,都会添加一个 state 对象

经过 this.state 可以得到state对象

由此 getInitialState 函数获取初叶的 state对象 存储的数据

透过 this.setState 本对象的方法来设置 state对象 存储的数额

var LikeButton = React.createClass({

getInitialState: function() {

return {liked: false};

},

handleClick: function(event) {

this.setState({liked: !this.state.liked});

},

render: function() {

var text = this.state.liked ? ‘喜欢’ : ‘不喜欢’;

return (

{text}自我。点自己切换状态。

);

}

});

React.render(

,

document.getElementById(‘example’)

);

state VS props

props 传递数据给子组件,不可变;state 因为可变,可以和用户交互

同angularJS和Vue相比,

5、组件 API 与生命周期

设置景况:setState

轮换状态:replaceState

安装属性:setProps

轮换属性:replaceProps

强制更新:forceUpdate

获取DOM节点:findDOMNode

判定组件挂载状态:isMounted

Mounting – 已经插入DOM

Updating – 正在重新渲染

Unmounint – 移除DOM

生命周期的章程 – 回调函数

componentWillMount

componentDidMount

componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate

componentDidUpdate

componentWillUnmount

6、ref 属性

以此和 vue的 el属性类似,可以收获整个因素,那样可以一本万利的操作元素

var MyComponent = React.createClass({

handleClick: function() {

// 使用原生的 DOM API 获取关节

this.refs.myInput.focus();

},

render: function() {

// 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs

return (

type=”button”

value=”点我输入框获取关节”

onClick={this.handleClick}

/>

);

}

});

ReactDOM.render(

,

document.getElementById(‘example’)

);

I、在必要操作的元素上,绑定 ref 属性

II、通过 react 组件对象的 this.refs 获取绑定的那几个特性

继续可以对取得的要素,举办操作

7、综合采用

I、通过 state 属性,已毕双向数据绑定 – 针对表单

var HelloMessage = React.createClass({

getInitialState: function() {

return {value: ‘Hello Runoob!’};

},

handleChange: function(event) {

this.setState({value: event.target.value});

},

render: function() {

var value = this.state.value;

return

1.设置值

vue中,只必要再表单要素上加上v-model,然后再绑定data中对应的一个值,当表单元素内容暴发变化时,data中对应的值也会相应变更,那是vue非常nice的一点。

JavaScript

<div id=”app”> <input v-model=”reason” placeholder=”填写理由”
class=’reason’/> </div> new Vue({ el: ‘#app’, data: {
reason:” } })

1
2
3
4
5
6
7
8
9
10
<div id="app">
    <input v-model="reason" placeholder="填写理由" class=’reason’/>
</div>
 
new Vue({
  el: ‘#app’,
  data: {
   reason:”
  }
})

但是在小程序中,却尚无这些成效。那如何做呢?

当表单内容爆发变化时,会触发布单元素上绑定的主意,然后在该措施中,通过this.setData({key:value})来将表单上的值赋值给data中的对应值。

上面是代码,可以感受一下:

JavaScript

<input bindinput=”bindReason” placeholder=”填写理由” class=’reason’
value='{{reason}}’ name=”reason” /> Page({ data:{ reason:” },
bindReason(e) { this.setData({ reason: e.detail.value }) } })

1
2
3
4
5
6
7
8
9
10
11
12
<input bindinput="bindReason" placeholder="填写理由" class=’reason’ value='{{reason}}’ name="reason" />
 
Page({
data:{
    reason:”
},
bindReason(e) {
    this.setData({
      reason: e.detail.value
    })
  }
})

当页面表单元素很多的时候,更改值就是一件体力活了。和小程序一比较,vuev-model简直爽的不要不要的。

事件传递

{value}

;

}

});

ReactDOM.render(

,

document.getElementById(‘example’)

);

a、通过原生事件 onchange 监听,指定监听函数 handleChange

b、在监听事件 中 调用 this.setState 更新绑定数据
(通过event能够获得各个数据)

II、通过 state 和 props 属性,已毕 内层触发外层更新数据

var Content = React.createClass({

render: function() {

return

点我

2.取值

vue中,通过this.reason取值

小程序中,通过this.data.reason取值

亚洲必赢官网 6

 

Vue 中传送事件很粗略,只须要在子组件内拔取 this.$emit(‘event1’)
即可向外传递一个轩然大波 event1,在父组件调用该子组件时,只必要监听 event1
事件,并交由对应事件处理逻辑即可。

{this.props.myDataProp}

}

});

var HelloMessage = React.createClass({

getInitialState: function() {

return {value: ‘Hello Runoob!’};

},

handleChange: function(event) {

this.setState({value: ‘菜鸟教程’})

},

render: function() {

var value = this.state.value;

return

updateStateProp = {this.handleChange}>

;

}

});

ReactDOM.render(

,

document.getElementById(‘example’)

);

a、通过原生事件 onClick 监听,指定监听函数 为外层传递来的 属性
this.props.updateStateProp

b、外层传递到内层的 属性 updateStateProp 指定为本人的监听事件
this.handleChange

c、外层监听事件 中 调用 this.setState 更新绑定数据
(通过event可以赢得各个数码)

外层传递到内层的 属性 updateStateProp

III、结合 ajax 请求,更新UI

React 组件的多少可以透过 componentDidMount 方法中的 Ajax
来博取,当从服务端获取数据库可以将数据存储在 state 中,再用
this.setState 方法重新渲染 UI。

var UserGist = React.createClass({

getInitialState: function() {

return {

username: ”,

lastGistUrl: ”

};

},

componentDidMount: function() {

this.serverRequest = $.get(this.props.source, function (result) {

var lastGist = result[0];

this.setState({

username: lastGist.owner.login,

lastGistUrl: lastGist.html_url

});

}.bind(this));

},

// 那里的 bind(this) 是因为 function 里面使用了 this.setState,此时的this
指针并从未指向外层的class对象,.bind()创造了一个新函数(原先函数的正片),当以此函数在被调用的时候,它的
this 关键词会被设置成被传播的值(那里指调用bind()时传出的参数)

componentWillUnmount: function() {

this.serverRequest.abort();

},

render: function() {

return (

{this.state.username} 用户最新的 Gist 共享地址:

{this.state.lastGistUrl}

);

}

});

ReactDOM.render(

{/* */}

,

mountNode

);

七、绑定事件传参

vue中,绑定事件传参挺容易,只须求在接触事件的章程中,把须要传递的数量作为形参传入就可以了,例如:

JavaScript

<button @click=”say(‘前天不上班’)”></button> new Vue({ el:
‘#app’, methods:{ say(arg){ consloe.log(arg) } } })

1
2
3
4
5
6
7
8
9
10
<button @click="say(‘明天不上班’)"></button>
 
new Vue({
  el: ‘#app’,
  methods:{
    say(arg){
    consloe.log(arg)
    }
  }
})

小程序中,不可能一向在绑定事件的主意中传唱参数,须要将参数作为属性值,绑定到元素上的data-特性上,然后在艺术中,通过e.currentTarget.dataset.*的格局获得,从而完结参数的传递,很坚苦有没有…

JavaScript

<view class=’tr’ bindtap=’toApprove’
data-id=”{{item.id}}”></view> Page({ data:{ reason:” },
toApprove(e) { let id = e.currentTarget.dataset.id; } })

1
2
3
4
5
6
7
8
9
<view class=’tr’ bindtap=’toApprove’ data-id="{{item.id}}"></view>
Page({
data:{
    reason:”
},
toApprove(e) {
    let id = e.currentTarget.dataset.id;
  }
})

亚洲必赢官网 7

 

Vue中事件传递

八、父子组件通讯

Vue子组件定义 child-component.vue

1.子零部件的使用

vue中,需要:

  1. 编写子组件
  2. 在要求采取的父组件中经过import引入
  3. vuecomponents中注册
  4. 在模板中行使

 

//子组件 bar.vue <template> <div class=”search-box”> <div
@click=”say” :title=”title” class=”icon-dismiss”></div>
</div> </template> <script> export default{ props:{
title:{ type:String, default:” } } }, methods:{ say(){
console.log(‘今天不上班’); this.$emit(‘helloWorld’) } } </script>
// 父组件 foo.vue <template> <div class=”container”> <bar
:title=”title” @helloWorld=”helloWorld”></bar> </div>
</template> <script> import Bar from ‘./bar.vue’ export
default{ data:{ title:”我是标题” }, methods:{ helloWorld(){
console.log(‘我接受到子组件传递的轩然大波了’) } }, components:{ Bar }
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//子组件 bar.vue
<template>
  <div class="search-box">
    <div @click="say" :title="title" class="icon-dismiss"></div>
  </div>
</template>
<script>
export default{
props:{
    title:{
       type:String,
       default:”
      }
    }
},
methods:{
    say(){
       console.log(‘明天不上班’);
       this.$emit(‘helloWorld’)
    }
}
</script>
 
// 父组件 foo.vue
<template>
  <div class="container">
    <bar :title="title" @helloWorld="helloWorld"></bar>
  </div>
</template>
 
<script>
import Bar from ‘./bar.vue’
export default{
data:{
    title:"我是标题"
},
methods:{
    helloWorld(){
        console.log(‘我接收到子组件传递的事件了’)
    }
},
components:{
    Bar
}
</script>

小程序中,需要:

  1. 编写子组件
  2. 在子组件的json文件中,将该公文宣称为组件
{ "component": true }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6a1146bfc908165305-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146bfc908165305-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6a1146bfc908165305-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6a1146bfc908165305-1" class="crayon-line">
{
</div>
<div id="crayon-5b8f6a1146bfc908165305-2" class="crayon-line crayon-striped-line">
  &quot;component&quot;: true
</div>
<div id="crayon-5b8f6a1146bfc908165305-3" class="crayon-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 在急需引入的父组件的json文件中,在usingComponents填写引入组件的零部件名以及路径
"usingComponents": { "tab-bar": "../../components/tabBar/tabBar" }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6a1146bff494634246-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146bff494634246-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6a1146bff494634246-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6a1146bff494634246-1" class="crayon-line">
&quot;usingComponents&quot;: {
</div>
<div id="crayon-5b8f6a1146bff494634246-2" class="crayon-line crayon-striped-line">
    &quot;tab-bar&quot;: &quot;../../components/tabBar/tabBar&quot;
</div>
<div id="crayon-5b8f6a1146bff494634246-3" class="crayon-line">
  }
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 在父组件中,直接引入即可
&lt;tab-bar currentpage="index"&gt;&lt;/tab-bar&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6a1146c02109159426-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6a1146c02109159426-1" class="crayon-line">
&lt;tab-bar currentpage=&quot;index&quot;&gt;&lt;/tab-bar&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


具体代码:  


// 子组件 &lt;!--components/tabBar/tabBar.wxml--&gt; &lt;view
class='tabbar-wrapper'&gt; &lt;view class='left-bar
{{currentpage==="index"?"active":""}}' bindtap='jumpToIndex'&gt;
&lt;text class='iconfont icon-shouye'&gt;&lt;/text&gt;
&lt;view&gt;首页&lt;/view&gt; &lt;/view&gt; &lt;view
class='right-bar {{currentpage==="setting"?"active":""}}'
bindtap='jumpToSetting'&gt; &lt;text class='iconfont
icon-shezhi'&gt;&lt;/text&gt; &lt;view&gt;设置&lt;/view&gt;
&lt;/view&gt; &lt;/view&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6a1146c06935082908-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146c06935082908-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6a1146c06935082908-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146c06935082908-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6a1146c06935082908-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146c06935082908-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6a1146c06935082908-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146c06935082908-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6a1146c06935082908-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146c06935082908-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f6a1146c06935082908-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a1146c06935082908-12">
12
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6a1146c06935082908-1" class="crayon-line">
// 子组件
</div>
<div id="crayon-5b8f6a1146c06935082908-2" class="crayon-line crayon-striped-line">
&lt;!--components/tabBar/tabBar.wxml--&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-3" class="crayon-line">
&lt;view class='tabbar-wrapper'&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-4" class="crayon-line crayon-striped-line">
  &lt;view class='left-bar {{currentpage===&quot;index&quot;?&quot;active&quot;:&quot;&quot;}}' bindtap='jumpToIndex'&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-5" class="crayon-line">
    &lt;text class='iconfont icon-shouye'&gt;&lt;/text&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-6" class="crayon-line crayon-striped-line">
    &lt;view&gt;首页&lt;/view&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-7" class="crayon-line">
  &lt;/view&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-8" class="crayon-line crayon-striped-line">
  &lt;view class='right-bar {{currentpage===&quot;setting&quot;?&quot;active&quot;:&quot;&quot;}}' bindtap='jumpToSetting'&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-9" class="crayon-line">
    &lt;text class='iconfont icon-shezhi'&gt;&lt;/text&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-10" class="crayon-line crayon-striped-line">
    &lt;view&gt;设置&lt;/view&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-11" class="crayon-line">
  &lt;/view&gt;
</div>
<div id="crayon-5b8f6a1146c06935082908-12" class="crayon-line crayon-striped-line">
&lt;/view&gt;
</div>
</div></td>
</tr>
</tbody>
</table>

亚洲必赢官网 8

2.父子组件间通讯

vue

父组件向子组件传递数据,只必要在子组件通过v-bind盛传一个值,在子组件中,通过props收纳,即可到位多少的传递,示例:

// 父组件 foo.vue <template> <div class=”container”> <bar
:title=”title”></bar> </div> </template>
<script> import Bar from ‘./bar.vue’ export default{ data:{
title:”我是标题” }, components:{ Bar } </script> // 子组件bar.vue
<template> <div class=”search-box”> <div :title=”title”
></div> </div> </template> <script> export
default{ props:{ title:{ type:String, default:” } } } </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 父组件 foo.vue
<template>
  <div class="container">
    <bar :title="title"></bar>
  </div>
</template>
<script>
import Bar from ‘./bar.vue’
export default{
data:{
    title:"我是标题"
},
components:{
    Bar
}
</script>
 
// 子组件bar.vue
<template>
  <div class="search-box">
    <div :title="title" ></div>
  </div>
</template>
<script>
export default{
props:{
    title:{
       type:String,
       default:”
      }
    }
}
</script>

子组件和父组件通讯可以因此this.$emit将艺术和数码传递给父组件。

小程序

父组件向子组件通讯和vue类似,但是小程序并未经过v-bind,而是直接将值赋值给一个变量,如下:

<tab-bar currentpage=”index”></tab-bar> 此处,
“index”就是要向子组件传递的值

1
2
3
<tab-bar currentpage="index"></tab-bar>
 
此处, “index”就是要向子组件传递的值

在子组件properties中,接收传递的值

properties: { // 弹窗标题 currentpage: { // 属性名 type: String, //
类型(必填),近期接受的类型蕴含:String, Number, Boolean, Object,
Array, null(表示任意档次) value: ‘index’ //
属性开头值(可选),若是未指定则会基于项目接纳一个 } }

1
2
3
4
5
6
7
properties: {
    // 弹窗标题
    currentpage: {            // 属性名
      type: String,     // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
      value: ‘index’     // 属性初始值(可选),如果未指定则会根据类型选择一个
    }
  }

子组件向父组件通信和vue也很接近,代码如下:

//子组件中 methods: { // 传递给父组件 cancelBut: function (e) { var that
= this; var my伊夫ntDetail = { pickerShow: false, type: ‘cancel’ } //
detail对象,提需求事件监听函数 this.trigger伊芙nt(‘myevent’,
my伊芙ntDetail) //myevent自定义名称事件,父组件中运用 }, } //父组件中
<bar bind:myevent=”toggleToast”></bar> // 获取子组件音信toggleToast(e){ console.log(e.detail) }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//子组件中
methods: {  
    // 传递给父组件
    cancelBut: function (e) {
      var that = this;
      var myEventDetail = { pickerShow: false, type: ‘cancel’ } // detail对象,提供给事件监听函数
      this.triggerEvent(‘myevent’, myEventDetail) //myevent自定义名称事件,父组件中使用
    },
}
 
//父组件中
<bar bind:myevent="toggleToast"></bar>
 
// 获取子组件信息
toggleToast(e){
    console.log(e.detail)
}

只要父组件想要调用子组件的方法

vue会给子组件添加一个ref属性,通过this.$refs.ref的值便得以获获得该子组件,然后便足以调用子组件中的任意方法,例如:

//子组件 <bar ref=”bar”></bar> //父组件
this.$ref.bar.子组件的主意

1
2
3
4
5
//子组件
<bar ref="bar"></bar>
 
//父组件
this.$ref.bar.子组件的方法

小程序是给子组件添加id或者class,然后经过this.selectComponent找到子组件,然后再调用子组件的艺术,示例:

//子组件 <bar id=”bar”></bar> // 父组件
this.selectComponent(‘#id’).syaHello()

1
2
3
4
5
//子组件
<bar id="bar"></bar>
 
// 父组件
this.selectComponent(‘#id’).syaHello()

小程序和vue在那一点上太相像了,有木有。。。
亚洲必赢官网 9

 

九、废话

还有为数不少地方没写,之后再逐月加上、精简。感觉自己写的有些冗余,大佬勿喷!!!
倘使认为有协助,希望协助点个赞和收藏

亚洲必赢官网 10

1 赞 2 收藏
评论

亚洲必赢官网 11

网站地图xml地图