AngularJS 将进入一个为期 3,文章名字叫vue源码之

作者: 前端  发布:2019-11-20

依据 MobX 塑造视图框架无关的数目层-与 Vue 的组合

2018/07/09 · JavaScript · mobx

原稿出处: kuitos   

mobx-vue 如今已进入 mobxjs 官方组织,接待试用求 star!

几周前自个儿写了黄金年代篇作品描述了 mobx 与 angularjs 结合使用的法子及目的(老树发新芽—使用 mobx 加快你的 AngularJS 应用),此番介绍一下什么样将 MobX 跟 Vue 结合起来。

深入分析vue是什么促成数量变动改过视图的.

老树发新芽—使用 mobx 加速你的 AngularJS 应用

2018/05/23 · JavaScript · AngularJS, mobx

最早的作品出处: kuitos   

三月首的时候,Angular 官方博客宣布了一则新闻:

AngularJS is planning one more significant release, version 1.7, and on July 1, 2018 it will enter a 3 year Long Term Support period.

即在 四月1日 AngularJS 发表 1.7.0 版本之后,AngularJS 将跻身叁个期限 3 年的 LTS 时代。也正是说 二零一八年2月1日 起至 2021年十二月30日,AngularJS 不再统后生可畏别的会促成 breaking changes 的 features 或 bugfix,只做供给的难题修复。详细音信见这里:Stable AngularJS and Long Term Support

来看那则消息时作者恐怕感动颇多的,作为本人的前端启蒙框架,笔者从 AngularJS 上得出到了那一个多的滋养。即便 AngularJS 作为大器晚成款不错的前端 MVW 框架已经完美的达成了自个儿的历史职分,但考虑到正是到了 2018 年,相当多供销合作社依据 AngularJS 的品类仍处服兵役阶段,结合自己过去一年多在 mobx 上的探幽索隐和实践,小编决定给 AngularJS 强行再续一波命。(搭车求治推延症良方,十二月底起草的文章10月份才写完,新闻都要过期了)

本文首若是带领大家分析$mount。

安装

npm i mobx-vue -S

1
npm i mobx-vue -S

前记

预备干活

在起来以前,大家须求给 AngularJS 搭配上一些现代化 webapp 开荒套件,以便前边能更方便人民群众地装载上 mobx 引擎。

$mount所做的办事从大意上来说至关心器重要分为3步:

使用

mobx-vue 的采取特别轻易,只须求接受 connect 将你用 mobx 定义的 store 跟 vue component 连接起来就能够:

<template> <section> <p v-text="amount"></p> <p v-for="user in users" :key="user.name">{{user.name}}</p> </section> </template> <script lang="ts"> import { Connect } from "mobx-vue"; import Vue from "vue"; import Component from "vue-class-component"; class ViewModel { @observable users = []; @computed get amount() { return this.users.length } <a href='; fetchUsers() {} } @Connect(new ViewModel()) @Component() export default class App extends Vue { mounted() { this.fetchUsers(); } } </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
<template>
    <section>
        <p v-text="amount"></p>
        <p v-for="user in users" :key="user.name">{{user.name}}</p>
    </section>
</template>
 
<script lang="ts">
    import { Connect } from "mobx-vue";
    import Vue from "vue";
    import Component from "vue-class-component";
    class ViewModel {
        @observable users = [];
        @computed get amount() { return this.users.length }
        <a href='http://www.jobbole.com/members/Francesco246437'>@action</a> fetchUsers() {}
    }
 
    @Connect(new ViewModel())
    @Component()
    export default class App extends Vue {
        mounted() {
            this.fetchUsers();
        }
    }
</script>

四个月前看了vue源码来深入分析哪些做到响应式数据的, 小说名字叫vue源码之响应式数据, 最后剖析到, 数据变动后会调用Watcher的update()方法. 那么时隔12月让我们世襲看看update()做了什么. (那四个月用react-native做了个档期的顺序, 也无意总括了, 因为临近太简单了).

AngularJS 配合 ES6/next

当今是二零一八年,使用 ES6 开辟应用已经成为事实规范(有望的推荐直接上 TS )。怎么样将 AngularJS 搭载上 ES6 这里不再赘言,能够看自个儿事先的那篇小说:Angular1.x + ES6 开拓风格指南

1.假诺你的option里面未有 render 函数,那么,通过 compileToFunctions 将HTML模板编写翻译成能够生成VNode的Render函数。

Why MobX/mobx-vue

咱俩精通,mobx 跟 vue 都以基于 数据威吓&重视搜集的艺术来完成响应式机制的。mobx 官方也一再关联 inspired by vue,那么我们为什么还要将七个大致千篇生机勃勃律的东西组成起来呢?

Yes, it’s weird.

二零一六年本人在营造企业级组件库的时候开端思量四个标题,大家怎么着在代码库基于某后生可畏框架的事态下,能以尽量小的代价在未来将构件库迁移到别的框架/库 下?总不能依附新的技巧全体重写三次呢,那也太浪费生命了。且不说对于根基控件来讲,交互作用/行为 逻辑基本上是可明确的,最多也正是 UI 上的部分调动,并且只是为了尝试新技术开支集团人力物力将根底库推导重写也是老大不职业的做法。那么大家一定要承当被框架绑架而只可以沦为某一技艺栈从此以往泥潭深陷吗?对于前端这种框架半衰期更短的园地来说肯定是不足选择的,结果只是便是要么自个儿跑路坑后来人,要么招不到人来一同填坑… 轻巧的话大家爱莫能助享用新技能带给的各种红利。

在 MVVM 架构视角下,越是重型的行使其复杂度越是聚焦在 M(Model) 跟 VM(ViewModel) 这两层,尤其是 Model 层,理论上相应是能脱离上层视图独立运行独立发表独立测量检验的存在。而相应的两样视图框架只是采取了分歧绑定语法的动态模板引擎而已,那么些观点作者在头里的几篇作品里都汇报过。所以假如大家将视图层做的很薄,我们迁移的财力自然会降低到二个可担任的框框,以至有望通过工具在编写翻译期自动生成差异框架的视图层代码。

要成功 Model 以致 ViewModel 独立可复用,大家供给的是生机勃勃种能够扶助大家描述各数据模型间信任关系图且框架中立的通用状态管理方案。此时期作者尝试过 ES6 accessor、redux、rxjs 等方案,但都不顺遂。accessor 过于底层且异步不和睦、redux 开辟体验太差(参考Redux数据流管理架构有怎样致命劣势,未来会怎么改良?)、rxjs 过重等等。直到后来看见 MobX:MobX 语法丰盛不难、弱主见(unopinioned)、oop 向、框架中立等特色偏巧适合笔者的急需。

在过去的一年多里,小编分别在 react、angularjs、angular 上尝试过基于 MobX 构建 VM/M 层,此中有四个上线项目,七个民用途目,奉行意义基本上也高达了自个儿的意料。在架设上,大家只需求利用相应的 connector,就能够依靠相符数据层,在区别框架下自如的切换。那样看来,那套思路现在就剩 Vue 未有被证实了。

在 mobx-vue 以前,社区豆蔻梢头度有大器晚成对好好的 connector 完成,如 movue vue-modex 等,但主题都以依据 vue 的插件机制且 inspired by vue-rx,除了利用起来相对烦琐的标题外,最大的难题是其促成基本都以借助Vue.util.defineReactive 来做的,也正是说依旧基于 Vue 自有的响应式机制,那在早晚水准不止浪费了 MobX 的reactive 技能,并且会为搬迁到此外视图框架下埋下了不鲜明的种子(终究你比不大概确认保障是 Vue 依旧 MobX 在响应状态变化)。

参考:why mobx-vue

能够状态下相应是由 mobx 管理数据的信赖关系,vue 针对 mobx 的响应做出 re render 动作就可以,vue 只是一个独自的动态模板渲染引擎,就好像 react 同样。

在如此的二个背景下,mobx-vue 诞生了。

本文叙事形式为树藤摸瓜, 顺着看源码的逻辑走叁回, 查看的vue的本子为2.5.2. 本身fork了生龙活虎份源码用来记录注释.

依赖组件的运用架构

AngularJS 在 1.5.0 版本后新扩充了一多级动人心魄的性状,如 onw-way bindings、component lifecycle hooks、component definition 等,基于那一个特色,大家能够方便的将 AngularJS 系统创设成叁个纯组件化的运用(假使您对这一个特点很熟知可一贯跳过至 AngularJS 搭配 mobx)。我们多个个来看:

  • onw-way bindings 单向绑定
    AngularJS 中使用 来定义组件的单向数据绑定,例如我们这样定义一个组件:
angular .module('app.components', []) .directive('component', ()
=&gt; ({ restrict: 'E', template: '&lt;p&gt;count:
{{$ctrl.count}}&lt;/p&gt;&lt;button ng-click="$ctrl.count =
$ctrl.count + 1"&gt;increase&lt;/button&gt;' scope: { count: '&lt;'
}, bindToController: true, controllerAs: '$ctrl', })

<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-5b8f6aab02f2c952921585-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f2c952921585-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f2c952921585-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f2c952921585-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f2c952921585-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f2c952921585-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f2c952921585-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f2c952921585-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f2c952921585-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f2c952921585-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f2c952921585-11">
11
</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-5b8f6aab02f2c952921585-1" class="crayon-line">
angular
</div>
<div id="crayon-5b8f6aab02f2c952921585-2" class="crayon-line crayon-striped-line">
    .module('app.components', [])
</div>
<div id="crayon-5b8f6aab02f2c952921585-3" class="crayon-line">
    .directive('component', () =&gt; ({
</div>
<div id="crayon-5b8f6aab02f2c952921585-4" class="crayon-line crayon-striped-line">
        restrict: 'E',
</div>
<div id="crayon-5b8f6aab02f2c952921585-5" class="crayon-line">
        template: '&lt;p&gt;count: {{$ctrl.count}}&lt;/p&gt;&lt;button ng-click=&quot;$ctrl.count = $ctrl.count + 1&quot;&gt;increase&lt;/button&gt;'
</div>
<div id="crayon-5b8f6aab02f2c952921585-6" class="crayon-line crayon-striped-line">
        scope: {
</div>
<div id="crayon-5b8f6aab02f2c952921585-7" class="crayon-line">
            count: '&lt;'
</div>
<div id="crayon-5b8f6aab02f2c952921585-8" class="crayon-line crayon-striped-line">
        },
</div>
<div id="crayon-5b8f6aab02f2c952921585-9" class="crayon-line">
        bindToController: true,
</div>
<div id="crayon-5b8f6aab02f2c952921585-10" class="crayon-line crayon-striped-line">
        controllerAs: '$ctrl',
</div>
<div id="crayon-5b8f6aab02f2c952921585-11" class="crayon-line">
    })
</div>
</div></td>
</tr>
</tbody>
</table>


使用时:



{{app.count}} component count="app.count"&gt;component&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-5b8f6aab02f35150522417-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f35150522417-2">
2
</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-5b8f6aab02f35150522417-1" class="crayon-line">
{{app.count}}
</div>
<div id="crayon-5b8f6aab02f35150522417-2" class="crayon-line crayon-striped-line">
component count=&quot;app.count&quot;&gt;component&gt;
</div>
</div></td>
</tr>
</tbody>
</table>

当我们点击组件的 increase 按钮时,可以看到组件内的 count 加 1
了,但是 `app.count`并不受影响。

区别于 AngularJS
赖以成名的双向绑定特性 `scope: { count: '='}`,单向数据绑定能更有效的隔离操作影响域,从而更方便的对数据变化溯源,降低
debug 难度。  
双向绑定与单向绑定有各自的优势与劣势,这里不再讨论,有兴趣的可以看我这篇回答:[单向数据绑定和双向数据绑定的优缺点,适合什么场景?](https://www.zhihu.com/question/49964363/answer/136022879)
  • component lifecycle hooks 组件生命周期钩子1.5.3 起头新扩展了多少个零器件的生命周期钩子(指标是为更有利的向 Angular2+ 迁移卡塔尔国,分别是 $onInit $onChanges $onDestroy $postLink $doCheck(1.5.8扩展),写起来差不离长这么:
class Controller { $onInit() { // initialization }
$onChanges(changesObj) { const { user } = changesObj; if(user &&
!user.isFirstChange()) { // changing } } $onDestroy() {} $postLink()
{} $doCheck() {} } angular .module('app.components', [])
.directive('component', () =&gt; ({ controller: Controller, ... }))

<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-5b8f6aab02f3a441625873-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-13">
13
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-14">
14
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-15">
15
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-16">
16
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-17">
17
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-18">
18
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-19">
19
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-20">
20
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-21">
21
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-22">
22
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-23">
23
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-24">
24
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3a441625873-25">
25
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3a441625873-26">
26
</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-5b8f6aab02f3a441625873-1" class="crayon-line">
class Controller {
</div>
<div id="crayon-5b8f6aab02f3a441625873-2" class="crayon-line crayon-striped-line">
    
</div>
<div id="crayon-5b8f6aab02f3a441625873-3" class="crayon-line">
    $onInit() {
</div>
<div id="crayon-5b8f6aab02f3a441625873-4" class="crayon-line crayon-striped-line">
        // initialization
</div>
<div id="crayon-5b8f6aab02f3a441625873-5" class="crayon-line">
    }
</div>
<div id="crayon-5b8f6aab02f3a441625873-6" class="crayon-line crayon-striped-line">
    
</div>
<div id="crayon-5b8f6aab02f3a441625873-7" class="crayon-line">
    $onChanges(changesObj) {
</div>
<div id="crayon-5b8f6aab02f3a441625873-8" class="crayon-line crayon-striped-line">
        const { user } = changesObj;
</div>
<div id="crayon-5b8f6aab02f3a441625873-9" class="crayon-line">
        if(user &amp;&amp; !user.isFirstChange()) {
</div>
<div id="crayon-5b8f6aab02f3a441625873-10" class="crayon-line crayon-striped-line">
            // changing
</div>
<div id="crayon-5b8f6aab02f3a441625873-11" class="crayon-line">
        }
</div>
<div id="crayon-5b8f6aab02f3a441625873-12" class="crayon-line crayon-striped-line">
    }
</div>
<div id="crayon-5b8f6aab02f3a441625873-13" class="crayon-line">
    
</div>
<div id="crayon-5b8f6aab02f3a441625873-14" class="crayon-line crayon-striped-line">
    $onDestroy() {}
</div>
<div id="crayon-5b8f6aab02f3a441625873-15" class="crayon-line">
    
</div>
<div id="crayon-5b8f6aab02f3a441625873-16" class="crayon-line crayon-striped-line">
    $postLink() {}
</div>
<div id="crayon-5b8f6aab02f3a441625873-17" class="crayon-line">
    
</div>
<div id="crayon-5b8f6aab02f3a441625873-18" class="crayon-line crayon-striped-line">
    $doCheck() {}   
</div>
<div id="crayon-5b8f6aab02f3a441625873-19" class="crayon-line">
}
</div>
<div id="crayon-5b8f6aab02f3a441625873-20" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f6aab02f3a441625873-21" class="crayon-line">
angular
</div>
<div id="crayon-5b8f6aab02f3a441625873-22" class="crayon-line crayon-striped-line">
    .module('app.components', [])
</div>
<div id="crayon-5b8f6aab02f3a441625873-23" class="crayon-line">
    .directive('component', () =&gt; ({
</div>
<div id="crayon-5b8f6aab02f3a441625873-24" class="crayon-line crayon-striped-line">
     controller: Controller,
</div>
<div id="crayon-5b8f6aab02f3a441625873-25" class="crayon-line">
     ...
</div>
<div id="crayon-5b8f6aab02f3a441625873-26" class="crayon-line crayon-striped-line">
 }))
</div>
</div></td>
</tr>
</tbody>
</table>

事实上在 1.5.3
之前,我们也能借助一些机制来模拟组件的生命周期(如 `$scope.$watch`、`$scope.$on('$destroy')`等),但基本上都需要借助`$scope`这座‘‘桥梁’’。但现在我们有了框架原生
lifecycle 的加持,这对于我们构建更纯粹的、框架无关的 ViewModel
来讲有很大帮助。更多关于 lifecycle 的信息可以看官方文档:[AngularJS
lifecycle
hooks](https://code.angularjs.org/1.6.7/docs/api/ng/service/%24compile#life-cycle-hooks)
  • component definitionAngularJS 1.5.0 后扩充了 component 语法用于更有利清楚的定义三个组件,如上述例子中的组件大家得以用component语法改写成:
JavaScript

angular .module('app.components', []) .component('component', {
template: '&lt;p&gt;count: {{$ctrl.count}}&lt;/p&gt;&lt;button
ng-click="$ctrl.onUpdate({count: $ctrl.count +
1})"&gt;increase&lt;/button&gt;' bindings: { count: '&lt;',
onUpdate: '&' }, })

<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-5b8f6aab02f3e495620996-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3e495620996-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3e495620996-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3e495620996-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3e495620996-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3e495620996-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3e495620996-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6aab02f3e495620996-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6aab02f3e495620996-9">
9
</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-5b8f6aab02f3e495620996-1" class="crayon-line">
angular
</div>
<div id="crayon-5b8f6aab02f3e495620996-2" class="crayon-line crayon-striped-line">
    .module('app.components', [])
</div>
<div id="crayon-5b8f6aab02f3e495620996-3" class="crayon-line">
    .component('component', {
</div>
<div id="crayon-5b8f6aab02f3e495620996-4" class="crayon-line crayon-striped-line">
        template: '&lt;p&gt;count: {{$ctrl.count}}&lt;/p&gt;&lt;button ng-click=&quot;$ctrl.onUpdate({count: $ctrl.count + 1})&quot;&gt;increase&lt;/button&gt;'
</div>
<div id="crayon-5b8f6aab02f3e495620996-5" class="crayon-line">
        bindings: {
</div>
<div id="crayon-5b8f6aab02f3e495620996-6" class="crayon-line crayon-striped-line">
            count: '&lt;',
</div>
<div id="crayon-5b8f6aab02f3e495620996-7" class="crayon-line">
     onUpdate: '&amp;'
</div>
<div id="crayon-5b8f6aab02f3e495620996-8" class="crayon-line crayon-striped-line">
        },
</div>
<div id="crayon-5b8f6aab02f3e495620996-9" class="crayon-line">
    })
</div>
</div></td>
</tr>
</tbody>
</table>

本质上`component`就是`directive`的语法糖,bindings
是 `bindToController + controllerAs + scope` 的语法糖,只不过`component`语法更简单语义更明了,定义组件变得更方便,与社区流行的风格也更一致(熟悉
vue 的同学应该已经发现了
					

本文由9159.com发布于前端,转载请注明出处:AngularJS 将进入一个为期 3,文章名字叫vue源码之

关键词: