js代码写Vue和React

js代码写Vue和React

一、前提

1. MVC情景

需要对一个数字进行加减1的操作,代码如下:

  1. <body> 
  2. <div id="text"> 
  3.  
  4. </div> 
  5. <div> 
  6. <input type="button" value="increase" id="btn1"> 
  7. <input type="button" value="decrease" id="btn2"> 
  8. </div> 
  9. <script> 
  10. var a = 0 
  11. document.getElementById("text").innerHTML = a 
  12.  
  13. var btn1 = document.getElementById("btn1") 
  14. var btn2 = document.getElementById("btn2") 
  15.  
  16. btn1.onclick =() => {a++ 
  17. document.getElementById("text").innerHTML = a} 
  18.  
  19. btn2.onclick = function(){ 
  20. a-- 
  21. document.getElementById("text").innerHTML = a 
  22. } 
  23. </script> 
  24. </body> 

效果图
效果图

1-1. 问题1

以上代码中,复用性可读性非常差,例如document.getElementById("text").innerHTML = a反复出现,可以通过封装函数render()解决

  1. btn1.onclick = () => { 
  2. a++ 
  3. render() 
  4. } 
  5.  
  6. btn2.onclick = function () { 
  7. a-- 
  8. render() 
  9. } 
  10. render = () => { 
  11. document.getElementById("text").innerHTML = a 
  12. } 

1-2. 问题2

能不能让a变化的时候,DOM自动变化? 例如制作一个虚拟DOM计算与实际DOM差异,再一次性更新进去;或者每当DOM有变化,简单让其上树操作等

1-3. 解决方案

Angular、React、Vue的根据以上问题,提出了解决方案,即MVVM框架,都能够实现数据变化视图自动变化。但是他们三个人的原理完全不同:
1.Angular:脏检查,词法分析,进行隐形的视图的更新;
2.React:setState()等调用视图函数,配合DIFF算法和Virtual DOM让DOM的变化效率更高;
3.Vue : 数据劫持

鉴于Angular太高深,我们以下只分析React与Vue

2. React

用js模拟react的原理
React中封装了一些函数,只有通过这些函数改变a属性的值,才能引发视图的变化。比如下面案例中的setstate()函数,通过setState()函数改变a属性值,会引发视图的变化。

  1.  
  2. <!DOCTYPE html> 
  3. <html lang="en"> 
  4.  
  5. <head> 
  6. <meta charset="UTF-8"> 
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
  8. <meta http-equiv="X-UA-Compatible" content="ie=edge"> 
  9. <title>React原理</title> 
  10. </head> 
  11.  
  12. <body> 
  13. <div id="text"> 
  14.  
  15. </div> 
  16. <div> 
  17. <input type="button" value="increase" id="btn1"> 
  18. <input type="button" value="decrease" id="btn2"> 
  19. </div> 
  20. <script> 
  21. render = () => { 
  22. document.getElementById("text").innerHTML = obj.a 
  23. } 
  24. const obj = { 
  25. a: 0 
  26. } 
  27.  
  28. function setState(k, v) { 
  29. obj[k] = v 
  30. } 
  31. render() 
  32.  
  33. var btn1 = document.getElementById("btn1") 
  34. var btn2 = document.getElementById("btn2") 
  35.  
  36. btn1.onclick = () => { 
  37. setState("a", obj.a + 1) 
  38. render() 
  39. } 
  40.  
  41. btn2.onclick = function () { 
  42. setState("a", obj.a - 1) 
  43. render() 
  44. } 
  45. </script> 
  46. </body> 
  47.  
  48. </html> 

用React的写法写一个简单计数器如下:

  1. class Counter extends React.Component { 
  2. constructor(props) { 
  3. super(props); 
  4. this.state = { 
  5. count: 0 
  6. }; 
  7. // 套路1注册一个行为到this里,可以使之用在dom里例如onClick之流 
  8. this.increment=this.increment.bind(this); 
  9. this.decrement=this.decrement.bind(this); 
  10. this.reset=this.reset.bind(this); 
  11.  
  12.  
  13. } 
  14. // 对套路进行具体操作,用this.setState({})一般操作数据,或this.setState(state=>{state';XX}) 
  15. increment() { 
  16. this.setState({ 
  17. count:this.state.count+1 
  18. }) 
  19. } 
  20. decrement() { 
  21. this.setState({ 
  22. count:this.state.count-1 
  23. }) 
  24. } 
  25. reset() { 
  26. this.setState(state => ({ 
  27. count: 0 
  28. })); 
  29. } 
  30. // change code above this line 
  31. render() { 
  32. return ( 
  33. <div> 
  34. <button className='inc' onClick={this.increment}>Increment!</button> 
  35. <button className='dec' onClick={this.decrement}>Decrement!</button> 
  36. <button className='reset' onClick={this.reset}>Reset</button> 
  37. <h1>Current Count: {this.state.count}</h1> 
  38. </div> 
  39. ); 
  40. } 
  41. }; 

关系:
react中的this.state即为obj对象中的键值对
enter description here


二、Vue

1. 前提:ES6--setter,getter

你可以从对象中获得一个值,也可以给对象的属性赋值。

这些通常行为被称为 getters 以及 setters。

Getter 函数的作用是可以让返回一个对象私有变量的值给用户,而不需要直接去访问私有变量。

Setter 函数的作用是可以基于传进的参数来修改对象中私有变量的值。这些修改可以是计算,或者是直接替换之前的值。

  1. class Book { 
  2. constructor(author) { 
  3. this._author = author; 
  4. } 
  5. // getter 
  6. get writer(){ 
  7. return this._author; 
  8. } 
  9. // setter 
  10. set writer(updatedAuthor){ 
  11. this._author = updatedAuthor; 
  12. } 
  13. } 
  14. const lol = new Book('anonymous'); 
  15. console.log(lol.writer); // anonymous 
  16. lol.writer = 'wut'; 
  17. console.log(lol.writer); // wut 

了解了es6中setter与getter 那么我们用js写一个仿vue的例子:

  1. <!DOCTYPE html> 
  2. <html lang="en"> 
  3.  
  4. <head> 
  5. <meta charset="UTF-8"> 
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
  7. <meta http-equiv="X-UA-Compatible" content="ie=edge"> 
  8. <title>Vue</title> 
  9. </head> 
  10.  
  11. <body> 
  12. <div> 
  13. <p id="text">0</p> 
  14. <input type="button" value="increase" id="btn1"> 
  15. <input type="button" value="decrease" id="btn2"> 
  16. </div> 
  17. </body> 
  18. <script type="text/javascript"> 
  19. class Number { 
  20. constructor(v) { 
  21. this._count = v; 
  22. } 
  23. // getter 
  24. get count() { 
  25. return this._count; 
  26. } 
  27. // setter 
  28. set count(v) { 
  29. this._count = v; 
  30. } 
  31. } 
  32. const btn1 = document.getElementById("btn1"); 
  33. const btn2 = document.getElementById("btn2"); 
  34. const a = new Number(0); 
  35. render = () => { 
  36. document.getElementById("text").innerHTML = a.count 
  37. } 
  38.  
  39. btn1.onclick = () => { 
  40. a.count ++; 
  41. render() 
  42. } 
  43. btn2.onclick = () => { 
  44. a.count --; 
  45. render() 
  46. } 
  47. </script> 
  48.  
  49. </html> 

用vue写

  1. <template> 
  2. <div > 
  3. <p>{{count}}</p> 
  4. <input type="button" value="increase" id="btn1" @click=increase> 
  5. <input type="button" value="decrease" id="btn2" @click=decrease> 
  6. </div> 
  7.  
  8. </template> 
  9.  
  10. <script type='text/ecmascript-6'> 
  11. export default { 
  12. layout: 'blank', 
  13. data () { 
  14. return { 
  15. count:0 
  16. } 
  17. }, 
  18. methods:{ 
  19. increase:function(){ 
  20. this.count++ 
  21. }, 
  22. decrease:function(){ 
  23. this.count-- 
  24. } 
  25. } 
  26. } 
  27. </script> 
  28.  
  29. <style> 
  30.  
  31. </style> 

三、小结

vue比原生简化很多,render()直接用{{}}渲染,通过数据双向绑定,节约代码量,而且在export default中泾渭分明,易于上手;react虽然代码不简单,但是对于学过es5,es6,jquery库的同志友好,代码易读,这个案例也就研究了两个框架上树的方式,仅为皮毛,不涉及其中深入的算法。

猜你喜欢

转载自www.cnblogs.com/sxl6666/p/12218326.html
今日推荐