引言

这里先上一篇文章 React 和 Vue 特性和书写差异 这篇文章介绍了,React和Vue的一些基本的特性的书写差异。不过文章中的React组件的代码段使用的是TypeScript的语法。和ECMA5差异也不是很多,大家可以先看一下。

此外Vue还提供了一些像是Computed、watch、mixins等特性,来提高开发者的开发效率。而React向来比较简介,下面主要说computed、watch、mixins这三个特性使用React的语法如何实现。

计算属性(computed)

<!-- Vue -->
<template>
 <div>
 	
 </div>
</template>

<script>
export default {
  computed: {
  	fullName: function() {
	   return this.firstName + this.LastName
    }
  }

  props: {
  	firstName: String
  }
}
</script>


<!-- React -->

class MyComponent extends React.Component {
	getFirstName() {
	   const {
	      firstName,
		  lastName
	   } = this.props

       return firstName + lastName
    }

	render() {
		return (
			<div>{ this.firstName() }<div>
		)
	}
}

在React里没有Computed和Methods这样的分别,每次Props的值或者State的值改变的时候,都回去触发Render方法的重现渲染

观察者(watch)

<!-- Vue -->
<template>
	<div id="watch-example">
  		<p>
    		Ask a yes/no question:
    		<input v-model="question">
  		</p>
  		<p></p>
	</div>
</template>

<script>
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // 如果 `question` 发生改变,这个函数就会运行
    question: function (newQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.getAnswer()
    }
  },
  methods: {
    // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
    // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
    // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
    // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
    // 请参考:https://lodash.com/docs#debounce
    getAnswer: _.debounce(
      function () {
        if (this.question.indexOf('?') === -1) {
          this.answer = 'Questions usually contain a question mark. ;-)'
          return
        }
        this.answer = 'Thinking...'
        var vm = this
        axios.get('https://yesno.wtf/api')
          .then(function (response) {
            vm.answer = _.capitalize(response.data.answer)
          })
          .catch(function (error) {
            vm.answer = 'Error! Could not reach the API. ' + error
          })
      },
      // 这是我们为判定用户停止输入等待的毫秒数
      500
    )
  }
})
</script>

<!-- React -->
class Question extends React.Component {

	state = {
		question: '',
    	answer: 'I cannot give you an answer until you ask a question!'
	}

	componentWillUpdate(newProps, newState) {
		const newQuestion = newState.question
		if (this.state.question !== newState.question) {
			this.setState({
				answer: 'Waiting for you to stop typing...'
			})
			this.getAnswer()
		}
	}

	getAnswer () {
		// ...
		// 同上
	}

	handleOnChangeQuestion = (e) => {
		this.setState({
			question: e.target.value
		})
   }

	render() {
		const {
			answer,
			question
		} = this.state
		return (
		<div id="watch-example">
			<p>
				Ask a yes/no question:
				<input value={question} onChange={this.handleOnChangeQuestion}>
			</p>
			<p>{ answer }</p>
		</div>
    }
}

混合(mixins)

// Vue的Mixins

var mixin = {
  methods: {
    foo: function () {
      console.log('foo')
    },
    conflicting: function () {
      console.log('from mixin')
    }
  }
}

var vm = new Vue({
  mixins: [mixin],
  methods: {
    bar: function () {
      console.log('bar')
    },
    conflicting: function () {
      console.log('from self')
    }
  }
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"


// React原来有提供Mixins的功能,但是在后来的版本中废弃掉了,我们可以通过高阶组件的方式来实现相同的功能

function connectToMixins(Component) {
  const StoreConnection = React.createClass({

	mixin = {
		foo: function () {
		  console.log('foo')
		}
	}

    render() {
      return <Component {...mixin} />;
    }
  });
  return StoreConnection;
};


// 使用方式:

class Todolist extends React.Component {
    render() {
		const {
			foo,
			conflicting
		} = this.props

		foo() // => foo
		...
    }
}
TodolistContainer = connectToMixin(Todolist)

当然Vue也可以使用高阶组件的方式来实现Mixin啦,有兴趣的同学可以自己做一些,这里就不累述了。还有一点就是React不存在想全局注册Mixin这样的操作。