vue、react、angular的区别

版权声明:复制发表请附上原创博客地址 https://blog.csdn.net/weixin_41077029/article/details/83341842

文档正在不停完善中,欢迎各位提建议和修改错误。

  vue2.0 react angular2 angular(官方不维护了)
基础                       Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。      
作者 尤雨溪 Facebook Google Google
官网 https://reactjs.org/ https://cn.vuejs.org/ https://www.angular.cn/  
框架 MVVM 不是一个MVC框架,只是其中一个层次(V)。 MVC MVVM
时间 2014 2013 2016 2009
大小 25k 151k 764k 143k
语言 JSX ES5 ES6 JSX ES5 ES6 TypeScript JavaScript
DOM Virtual Vitual    
Mobile Support Weex React Native Ionic Ionic
Designing Templates JS Centric JS into HTML JS into HTML
数据绑定 双向 单向 双向 双向
Rendering 服务器端 服务器端 服务器端 客户端
应用场景 对于不会持续的小型的 Web 应用,使用 Vue 能带来短期内较高的开发效率。 React 配合严格的 Flux 架构,适合超大规模多人协作的复杂项目。 面向大型企业应用 适合 SPA,面向较小的应用程序。
优点 o 有完整的官方中文文档。
o 数据双向绑定思路与 Angular 类似。
o 组件化与数据流则与 React 类似,不同组件间单项数据流可防止主模块数据被污染。
o 使用脚手架工具 vue-cli 可以快速地构建项目:单文件 Vue 组件,热加载,保存时检查代码,单元测试等,优秀的组件化,配合 router 等大型项目也可以轻易拿下。
o Vue.js 中指令和组件分得更清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元(有自己的视图和数据逻辑)。
o 采用 Virtual DOM 的思路,速度快,性能好。
o 可以直接使用 ES6 的语法,通过 webpack 编译成浏览器兼容的 ES5,可以提高开发效率。
o 状态管理时,都是使用this.setData,简单直观。
o React 可以在服务器上预渲染应用再发送到客户端。它可以从预渲染的静态内容中恢复一样的记录到动态应用程序中。搜索引擎的爬虫程序依赖的是服务端响应而不是 JavaScript 的执行,预渲染你的应用有助于搜索引擎优化。
React更加关注UI的组件化,能较好的实现代码重用。

 
o 有 Angular 1.0 的优点。
o 可以使用 ES6 的语法。
o 可以通过懒加载来引入依赖注入。
o 是一套完整的框架,Angular 有自带的数据绑定、render 渲染、AngularUI 库,过滤器,directive(模板),服务 q(defer), http,inject(依赖注入), factory, provide 等等一系列工具。
o 整个框架充满了 DI 的思路,耦合性非常低。
缺点 o 单项数据流,父子组件或平行组件间传递大量数据时需要基于 Vuex。
o 不内置例如 AJAX,Route 等功能到核心包,而是以插件的方式加载。
o 社区/组件生态相对 Angular 和 React 来说不够强大,现成的插件和组件不够完善。
o 大量数据时,首次渲染性能不如 React。
o 和 Angular 相比,React 的组件比较少,
o React 比较“轻”,只有一个 view 层,当业务比较复杂,需要较完整的框架时,要引入 Flux, Redux。
o 本身内容比较新,API 存在较大变化的风险。
o Angular 的 2.0 版本几乎是推翻 1.0 版本重做的,要学习大量的东西,如模块、控制器、指令等,学习成本高。
o 新,资料少,缺乏开发经验。
o 环境搭建耗时。
o 官方不在维护该框架。
脚手架 vue-clivue-iview-cli react-iview angular-cli
安装:npm install -g @angular/clio React
 
属性绑定        
数据绑定        
通过分析选择用vue的原因 通过分析框架的特点并结合项目分析对比后,最终决定选择 Vue 框架来进行开发。 原因如下:
1. Vue 是通过 Virtual Dom 抽象层来实现页面渲染,避免了高成本的常规 DOM 操作,尽管 Vue React 都使用了 Virtual Dom 实现这一点,但 Vue Virtual Dom 实现(复刻自 snabbdom)是更加轻量化的,所以在这里给 Vue 续一秒(查水表)
2. 对比 Vue React,它们都是 JavaScript 编写的,听起来这十分简单和优雅。然而不幸的事实是,React JavaScript 内的 HTML CSS 会产生很多痛点。JSX vs TemplatesTemplates 可读性,书写优雅,逻辑清晰所以给 Vue 再续一秒(+1s)
3. Vue 的一些语法和 Angular 的很相似,但在 API 与设计两方面上 Vue.js 都比 Angular 1 简单得多,因此你可以快速地掌握它的全部特性并投入开发。所以 Vue + 1s
4. Angular 1 使用双向绑定,Vue 在不同组件间强制使用单向数据流。这使应用中的数据流更加清晰易懂。所以 Vue++
5. Angular 2 的学习曲线是非常陡峭的。即使不包括 TypeScript,它的开始指南中所用的就有 ES2015 标准的 JavaScript18 NPM 依赖包,4 个文件和超过 3 千多字的介绍,这一切都是为了完成个 Hello World。而Vue’s Hello World就非常简单。甚至我们并不用花费一整个页面去介绍它。所以如果项目经理选 Angular 2那也只好去学习(ci zhi)
6. jQuery Zepto 不在考虑范围内。
     
基本构架 <div id="app">
  {{ message }}
</div>
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
class HelloBox extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}

ReactDOM.render(
  <HelloBox name="Taylor" />,
  mountNode
);
注意:
1.<script>标签的type必须为 type="text/babel",因为需要browser.min.js来解析jsx的语法内容
2.MessageBox的首字母必须大写,否则直接解析成一个标签,并且不作显示
3.所有标签都要闭合
    <MessageBox/>的结束符“/”必须要有
    <br/>
4.
标签内的class属性必须写出className,因为他可能和createClass可能产生冲突
5.样式必须是驼峰式写法(fontSize
6.render里的标签尤其只有一个分结点(即最外层只能有一个标签包含其他的标签)
   
循环 v-for
  <div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
.map/for循环  ,没有自己的循环语句
<script type="text/babel"> 
        var arr = ["
张三","李四","王五"]; 
        ReactDOM.render( 
            <ul> 
                { 
                    arr.map(function(name){ 
                        return <li>{name}</li> <span style="color:#ff0000;">//
必须要return出来否则在dom中不会显示</span> 
                    }) 
                }    
            </ul>, 
            document.querySelector("#example") 
        ) 
    </script>  
ngFor
<li *ngFor="let hero of heroes">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
 
钩子函数(生命周期) 1.beforeCreate 组件实例刚被创建,组件属性计算之前,如data属性等(可以在这加个loading事件)
 2.created:组件实例创建完成,属性已绑定,但DOM还未生成,$el属性还不存在(在这结束loading,还做一些初始化,实现函数自执行)
3.beforeMount:模板编译/挂载之前(完成了 el data 初始化)
4.mounted:模板编译/挂载之后(ajax获取数据阶段。在这发起后端请求,拿回数据,配合路由钩子做一些事情)
5.beforeUpdate:组件更新之前(指view层的数据变化前,不是data中的数据改变前触发)
6.updated:组件更新之后(data里的值被修改后触发)
7.activatedfor keep-alive,组件被激活时调用
8.deactivatedfor keep-alive,组件被移除时调用
9.beforeDestory:组件销毁前调用(你确认删除XX吗?)
10.destoryed:组件销毁后调用(Vue实例销毁。当前组件已被删除,清空相关内容)
一、Mounted阶段:加载阶段或者说初始化阶段,这个阶段组件由jsx转换成真实的Dom
1.getDefaultProps:设置默认属性
2.getInitialState:设置默认状态
3.componentWillMount:组件即将加载时候运行的函数(通常在这里执行ajax等操作)
4.render:必不可少
5.componentDidMount:组件加载完毕时候运行的函数。

二、Update阶段:组件运行中阶段,当组件修改自身状态或者父组件修改子组件属性时候发生的阶段。
1.componentWillReceiveProps:组件将要接受新组件
2.shouldComponentUpdate:组件是否更新
    //组件进行性能提升的时候就是靠 shouldComponentUpdate这个函数
    shouldComponentUpdate:function(nextProps){//是一个问句,要不要随父组件更新,如果写了这个函数,即使里面没有设置return false/true,都不会随父组件更新,即默认是return false
        // console.log(nextProps)//
返回{nameinput里输入的值}
        console.log('b.shouldComponentUpdate')
        // return false;//
表示子组件不随父组件不更新,只执行a.b.cde函数都不执行,执行顺序为1234d54ab4ab4ab...
        return true;//
表示子组件随父组件的更新而更新,abcde都执行,执行顺序为1234d54abcdeabcde...
    },

3.componentWillUpdate: 组件即将更新
4.render:必不可少
5.componentDidUpdate:组件更新完毕时候运行的函数。

三、Unmount阶段:组件卸载阶段,这个一般是组件被浏览器回收的阶段。(一般不需要关注的阶段)
1.componentWillUnmount:开发者需要来销毁(组件真正删除之前调用,比如计时器和事件监听器)
ngOnChanges当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在 ngOnInit之前。(接口:OnChanges)(范围:指令和组件)
ngOnInit在第一轮 ngOnChanges 完成之后调用。 ( 译注:也就是说当每个输入属性的值都被触发了一次 ngOnChanges 之后才会调用 ngOnInit ,此时所有输入属性都已经有了正确的初始绑定值 )(接口:OnInit)(范围:指令和组件)
ngDoCheck在每个 Angular 变更检测周期中调用。(接口:DoCheck)(范围:指令和组件)
ngAfterContentInit当把内容投影进组件之后调用。(接口:AfterContentInit)(范围:组件)
ngAfterContentChecked每次完成被投影组件内容的变更检测之后调用。(接口:AfterContentChecked)(范围:组件)
ngAfterViewInit初始化完组件视图及其子视图之后调用。after initializing the component’s views and child views.(接口:AfterViewInit)(范围:组件)
ngAfterViewChecked每次做完组件视图和子视图的变更检测之后调用。(接口:AfterViewChecked)(范围:组件)
ngOnDestroy Angular 每次销毁指令 / 组件之前调用。(接口:OnDestroy)(范围:指令和组件)
 
路由 vue-router
官网:https://router.vuejs.org/zh-cn/
routes.js
1.引入模块
    import Home from './components/Home.vue';
    import User from './components/user/User.vue';
2.
定义路由并暴露接口
    export const routes = [     {path:'/',component:Home,name:'home'},//name给路由设置名字,为了方便router-link的时候不用拼接字符串,方便些     {path:'/user',component:User,children:[// /user      user下的模块
            {path:"",component:UserStart},// /user/
            {path:":id",component:UserDetail},// /user/:id           {path:":id/edit",component:UserEdit,name:'userEdit'}// /user/:id/edit
        ]}
]
    Notice:url
设参(/:id)
   
接参:在对应的component后的.vue中,本处为User.vue

main.js
3.1引用下载的VueRouter和配置的路由(routes.js
    import VueRouter from 'vue-router';//1.引用路由模块
    import {routes} from './routes';//3.引用路由配置变量
3.2使用
    Vue.use(VueRouter);//2.
3.3
创建router实例,然后传routes配置参数
    const router=new VueRouter({//4.创建实例
    routes//routes:routes的简写  //5.将路由变量实例化成路由对象
    })
3.4
new Vue中实例化router
    new Vue({
      el: '#app',
      router,
      render: h => h(App)
    })


app.vue里的html里显示路由
<router-view></router-view>      
   

 知识点:     
app.vue主组件中显示路由内容需要用<router-view></router-view> 来进行渲染
在路由中设置
name属性后可以利用router-link来设置:to参数,以便跳转到指定的组件模块
react-router
官网:https://github.com/ReactTraining/react-router2
分为router2router4
本处将router2
index.js(入口文件)
var React = require('react');
var ReactDOM = require('react-dom');

//
引入路由部分
var Router = require('react-router').Router;//路由的模块
var Route = require('react-router').Route;//路由
var hashHistory = require('react-router').hashHistory;

//
引入模块
var App = require('./modules/App')
var About = require('./modules/About')
var Repos = require('./modules/Repos')

var Index = React.createClass({
    render:function(){
        return(
            <Router history = {hashHistory}>
                <Route path="/" component={App}/>
                <Route path="/about" component={About}/>
                <Route path="/repos" component={Repos}/>               
            </Router>
        )
    }
})
ReactDOM.render(<Index/>,document.getElementById('app'))


App.js
1.引入链接
var Link = require('react-router').Link;
2.render
下的div标签内写点击链接跳转的代码
<ul>
    <li><Link to="/about">About</Link></li>
    <li><Link to="/repos">Repos</Link></li>                   
</ul>
 
 router4
3.App.js里面直接引用
3.1引用
import {Home} from './Components'
3.2div
里换成
    ReactDOM.render(
    <BrowserRouter>{/*BrowserRouter
相当于2.0Router*/}
        <div>
            <ul>
                <li><NavLink to="/" activeClassName="active">Home</NavLink></li>
            </ul>
            <Route path="/" component={Home} exact={true}/>{/*Route
4.0是拿来渲染的,相当于2.0{this.props.children}。在2.0是拿来设置路由的。*/}
        </div>
    </BrowserRouter>,
document.getElementById('app')
)
angular/router二函数。
官网:
https://www.angular.cn/guide/router
案例:
index.html
<base href="/">
.module.ts(import)
import { RouterModule, Routes } from '@angular/router';
.module.ts(except)
const appRoutes: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  { path: 'hero/:id',      component: HeroDetailComponent },
  {
    path: 'heroes',
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '',
    redirectTo: '/heroes',
    pathMatch: 'full'
  },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: true } // <-- debugging purposes only
    )
    // other imports here
  ],
  ...
})
export class AppModule { }

.compontent.ts(template)//实现点击跳转
  <h1>Angular Router</h1>
  <nav>
    <a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
    <a routerLink="/heroes" routerLinkActive="active">Heroes</a>
  </nav>
  <router-outlet></router-outlet>

注意:path不能以斜杠(/)开头
 
路由的钩子函数 全局钩子函数:
before each:意思是在 每次每一个路由改变的时候都得执行一遍。
它的三个参数:

to: (Route路由对象即将要进入的目标 路由对象    to对象下面的属性: path   params  query   hash   fullPath    matched   name    meta(在matched下,但是本例可以直接用)
from: (Route路由对象当前导航正要离开的路由
next: (Function函数)   一定要调用该方法来 resolve 这个钩子。  调用方法:next(参数或者空)   ***必须调用
next(无参数的时候):  进行管道中的下一个钩子,如果走到最后一个钩子函数,那么  导航的状态就是 confirm

afterEachafter 钩子没有 next 方法,不能改变导航,代表已经确定好了导航怎么去执行后,附带的一个执行钩子函数

组件内的钩子函数:(
beforeRouteEnter beforeRouteLeave 再加一个 watch函数
每个路由都有Enter和Leave钩子,用户进入或离开该路由时触发。
1.onEnter钩子函数
<Route path="inbox" component={Inbox}>
  <Route
    path="messages/:id"
    onEnter={
      ({params}, replace) => replace(`/messages/${params.id}`)
    }
  />
</Route>
 

2.setRouteLeaveHook方法为Leave钩子指定routerWillLeave函数   
componentDidMount() {
        this.props.router.setRouteLeaveHook(
            this.props.route,
            this.routerWillLeave
        )
    }

    routerWillLeave(nextLocation) {
        return '
确认要离开?';
    }
Router Event路由器事件(即钩子函数)
NavigationStart本事件会在导航开始时触发。
RoutesRecognized本事件会在路由器解析完URL,并识别出了相应的路由时触发
RouteConfigLoadStart 本事件会在Router对一个路由配置进行惰性加载之前触发。
RouteConfigLoadEnd本事件会在路由被惰性加载之后触发。
NavigationEnd本事件会在导航成功结束之后触发。
NavigationCancel本事件会在导航被取消之后触发。 这可能是因为在导航期间某个路由守卫返回了false
NavigationError这个事件会在导航由于意料之外的错误而失败时触发。

路由器部件
Router(路由器):为激活的URL显示应用组件。管理从一个组件到另一个组件的导航
RouterModule(路由器模块):一个独立的Angular模块,用于提供所需的服务提供商,以及用来在应用视图之间进行导航的指令。
Routes(路由数组):定义了一个路由数组,每一个都会把一个URL路径映射到一个组件。
Route(路由):定义路由器该如何根据URL模式(pattern)来导航到组件。大多数路由都由路径和组件类构成。
RouterOutlet(路由出口):该指令(<router-outlet>)用来标记出路由器该在哪里显示视图。
RouterLink(路由链接):该指令用来把一个可点击的HTML元素绑定到路由。 点击带有绑定到字符串或链接参数数组的routerLink指令的元素就会触发一次导航。
RouterLinkActive(活动路由链接):当HTML元素上或元素内的routerLink变为激活或非激活状态时,该指令为这个HTML元素添加或移除CSS类。
ActivatedRoute(激活的路由):为每个路由组件提供提供的一个服务,它包含特定于路由的信息,比如路由参数、静态数据、解析数据、全局查询参数和全局碎片(fragment)。
RouterState(路由器状态):路由器的当前状态包含了一棵由程序中激活的路由构成的树。它包含一些用于遍历路由树的快捷方法。
链接参数数组:这个数组会被路由器解释成一个路由操作指南。我们可以把一个RouterLink绑定到该数组,或者把它作为参数传给Router.navigate方法。
路由组件:一个带有RouterOutletAngular组件,它根据路由器的导航来显示相应的视图。
 
ajax数据请求 axios,resource      
ref传值       
 1.传值
 <input type="text" value="调试 vuejs 2.0" ref="input1">  
 
 2.
接参
this.$refs.input1可以访问到该组件实例,其实就是dom元素节点。
1.传值
<input ref="myInput" />
 
 2.
接参
var input = this.refs.myInput;
 0
 0 0
 0 0
 0 0
 0 0
 0
 
url传参 方法一:
this.$router.push({
                        name: 'routePage',
                        query/params: {
                            routeParams: params
                        }

方法二:
两种方式
<a v-link="{ name: 'history', params: { deviceId: deviceId, dataId: dataId }}">history</a>
学习网址:http://blog.csdn.net/qq_23158083/article/details/68488831
 

.props.params 
 传一个对象:
 1.在路由设置里
    <Route path='/user/:data' component={UserPage}></Route>
2.在跳转文件里
import {Link,hashHistory} from 'react-router';
var data = {id:3,name:sam,age:36};
data = JSON.stringify(data);
var path = `/user/${data}`;

方法一:<Link to={path}>用户</Link>>
 
方法二:ashHistory.push(path);
3.
在跳转到的文件里:
接参:var data = JSON.parse(this.props.params.data);
var {id,name,age} = data;

传一个值:
 1.在路由设置里
    <Route path='/user/:name' component={UserPage}></Route>
2.
在跳转文件里
import {Link,hashHistory} from 'react-router';
方法一:<Link to="/user/sam">用户</Link>
 
方法二:hashHistory.push("/user/sam");
3.
在跳转到的文件里:
接参:
this.props.params.name
 
 
二、query
 1.在路由设置里
    <Route path='/user' component={UserPage}></Route> 
2.
在跳转文件里
import {Link,hashHistory} from 'react-router';
 var data = {id:3,name:sam,age:36};
var path = {
  pathname:'/user',
  query:data,
}

方法一:<Link to={path}>用户</Link>
 
方法二:hashHistory.push(path);
3.
在跳转到的文件里:
接参:
var data = this.props.location.query;
var {id,name,age} = data;
 

.state
 1.在路由设置里
    <Route path='/user' component={UserPage}></Route>
2.
在跳转文件里
import {Link,hashHistory} from 'react-router';
var data = {id:3,name:sam,age:36};
var path = {
  pathname:'/user',
  state:data,
}

方法一:<Link to={path}>用户</Link>
 
方法二:hashHistory.push(path);
3.
在跳转到的文件里:
接参:
var data = this.props.location.query;
var {id,name,age} = data;
state
方式依然可以传递任意类型的数据,而且可以不以明文方式传输。
   
url参数的获取方法  this.$route.params
例如:
ready: function(){
        console.log('deviceid: ' + this.$route.params.deviceId);
        console.log('dataId: ' + this.$route.params.dataId);
    }
  this.props.
例如:
router4的获取参数值方式
       { this.props.match.params.id }
   
router2的获取方式
      参考网址:http://blog.csdn.net/starwmx520/article/details/50772943
      //
通过this.props.params.XX
     //
通过this.props.location.query.XX
   
         
  vuex redux    
含义 Vue中,多组件的开发给我们带来了很多的方便,但同时当项目规模变大的时候,多个组件间的数据通信和状态管理就显得难以维护。而Vuex就此应运而生。将状态管理单独拎出来,应用统一的方式进行处理,在后期维护的过程中数据的修改和维护就变得简单而清晰了。Vuex采用和Redux类似的单向数据流的方式来管理数据。用户界面负责触发动作(Action)进而改变对应状态(State),从而反映到视图(View)上      
  State设置状态,但它不会进行直接状态的修改。负责存储整个应用的状态数据,一般需要在使用的时候在跟节点注入store对象,后期就可以使用this.$store.state直接获取状态  
  
mapState 辅助函数。当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键
    ...mapState使用对象展开运算符将此对象混入到外部对象中

 Getter  只获取状态,不做任何修改
 mapGetters 辅助函数
   
Mutation   
    }    }   }   
   commit
:提交载荷、】store.commit('increment', 10)  
    }    }   }
Action   
    }    }   }   
    }    }   }
Module   
    }    }   }   
    }    }   }
   
    }    }   }
   
    }    }   }
   
    }    }   }
   
    }    }   }
   
    }
     http://blog.csdn.net/sinat_17775997/article/details/54943797
    }   }
   
    }
   }
   
    }   }
   
    }   }
   
    }   }
   
    }   }
   
    }   }
   
    }
   
  State
Getter
Mutation
Action
Module
     
angular2       MVC
         
         

猜你喜欢

转载自blog.csdn.net/weixin_41077029/article/details/83341842