ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] * * * * * # 1 测试示例目录名称(benchmarks\,examples\,test\) * benchmarks\ 目录下主要包含Vue性能测试用例 * examples\ 目录下主要包含Vue简单使用示例 * test\ 目录下主要包含Vue单元测试用例 # 2 单元测试目录(test\)分析 * test\e2e\ 目录下是nightwatch测试文件 * helpers\ 目录下的文件在unit目录的单元测试时使用 * ssr\ 目录下的文件是服务器渲染测试文件 * unit\ 目录下的文件是单元测试文件 ## 2-1 测试助手目录(helpers\)分析 * classlist.js 注册toHaveClass函数,检查元素是否包含特定class * to-equal.js 注册toEqual函数,比较两个值是否相同 * to-have-been-warned.js 注册toHaveBeenWarned,警告信息 * trigger-event.js 注册triggerEvent,事件触发函数 * vdom.js 注册createTextVNode函数,创建虚拟节点 * wait-for-update.js 注册waitForUpdate函数,等待刷新 >以上注册都是在jasmine单元测试框架中进行注册 > jasmine是javascript的行为驱动测试框架 > 有关jasmine的语法 见 [jsamine用法](http://www.ibm.com/developerworks/cn/web/1404_changwz_jasmine/) ## 2-2 单元测试目录(unit\)分析 * index.js 单元测试入口文件,导入测试助手文件与所有测试文件 * features\ 功能性单元测试 * modules\ 模块单元测试 ## 2-3 功能单元测试目录(unit\features\)分析 ### .1(component\\)组件测试 > component.spec.js ~~~ ;核心代码 .... ;component的测试使用示例. vm = new Vue({ template: '<test></test>', components: { test: { data () { return { a: 123 } }, template: '<span>{{a}}</span>' } } }).$mount() ;实现一个test组件,test组件中的元素template属性<span>{{a}}</span> ;并且test组件的span中包含的数据data属性a:123. ;最后<test></test>渲染为<spane>123</span> .... vm = new Vue({ template: '<div><table><tbody><test></test></tbody></table></div>', components: { test: { data () { return { a: 123 } }, template: '<tr><td>{{a}}</td></tr>' } } }).$mount() ;与上面相同实现<test></test>组件 ... vm = new Vue({ template: '<div><table><tbody><tr is="test"></tr></tbody></table></div>', components: { test: { data () { return { a: 123 } }, template: '<tr><td>{{a}}</td></tr>' } } }).$mount() ;使用<tr is="test"></tr>使用test组件模板 ... vm = new Vue({ template: '<div><test inline-template><span>{{a}}</span></test></div>', data: { a: 'parent' }, components: { test: { data () { return { a: 'child' } } } } }).$mount() ;使用inline-template声明为行内组件 ... new Vue({ template: '<test></test>', components: { test: { data () { return { a: 123, b: 234 } }, template: '<p>{{a}}</p><p>{{b}}</p>' } } }).$mount() ; 组件中只可以包含一个根元素,不可使用多个元素并列 ... vm = new Vue({ template: '<component :is="view" :view="view"></component>', data: { view: 'view-a' }, components: { 'view-a': { template: '<div>foo</div>', data () { return { view: 'a' } } }, 'view-b': { template: '<div>bar</div>', data () { return { view: 'b' } } } } }).$mount() ; 使用:is="view" :view="view"动态切换组件内容 vm = new Vue({ template: '<div>' + '<component :is="$options.components.test"></component>' + '<component :is="$options.components.async"></component>' + '</div>', components: { test: { template: '<span>foo</span>' }, async: function (resolve) { resolve({ template: '<span>bar</span>' }) } } }).$mount() ;:is只可以用在名为component的组件元素中。 ;:is不可以用在其他名称的组件元素中 .... vm = new Vue({ template: '<div>' + '<component v-for="c in comps" :is="c.type"></component>' + '</div>', data: { comps: [{ type: 'one' }, { type: 'two' }] }, components: { one: { template: '<span>one</span>' }, two: { template: '<span>two</span>' } } }).$mount() ;在component中可以使用v-for ... vm = new Vue({ data: { ok: false, message: 'hello' }, template: '<test v-show="ok">{{message}}</test>', components: { test: { template: '<div><slot></slot> {{message}}</div>', data () { return { message: 'world' } } } } }).$mount() ; 在组件中使用v-show控制显示 ; 其中的message使用vue父级作用的值 vm = new Vue({ data: { ok: false, message: 'hello' }, template: '<test v-if="ok">{{message}}</test>', components: { test: { template: '<div><slot></slot> {{message}}</div>', data () { return { message: 'world' } } } } }).$mount() ; v-if在组件中的使用 ... vm = new Vue({ data: { list: [{ a: 1 }, { a: 2 }] }, template: '<test :collection="list"></test>', components: { test: { template: '<ul><li v-for="item in collection">{{item.a}}</li></ul>', props: ['collection'] } } }).$mount() ;使用:collection引用父级的props的list属性。 ;在子组件中使用v-for遍历collectiond的props属性 ~~~ > component-async.spec.js ~~~ ;核心实例代码 .... const vm = new Vue({ template: '<div><test></test></div>', components: { test: (resolve) => { setTimeout(() => { resolve({ template: '<div>hi</div>' }) // wait for parent update Vue.nextTick(next) }, 0) } } }).$mount() ;组件异步填充. ... vm = new Vue({ template: '<test></test>', components: { test: resolve => { setTimeout(() => { resolve({ template: '<div>hi</div>' }) // wait for parent update Vue.nextTick(next) }, 0) } } }).$mount() ;作为根元素填充 ... vm = new Vue({ template: '<component :is="view"></component>', data: { view: 'view-a' }, components: { 'view-a': resolve => { setTimeout(() => { resolve({ template: '<div>A</div>' }) Vue.nextTick(step1) }, 0) }, 'view-b': resolve => { setTimeout(() => { resolve({ template: '<p>B</p>' }) Vue.nextTick(step2) }, 0) } } }).$mount() ;:is="view" 根据view值动态切换组件渲染 vm = new Vue({ template: '<div><test v-for="n in list" :n="n"></test></div>', data: { list: [1, 2, 3] }, components: { test: resolve => { setTimeout(() => { resolve({ props: ['n'], template: '<div>{{n}}</div>' }) Vue.nextTick(next) }, 0) } } }).$mount() ;使用v-for循环遍历 ~~~ > component-keep-alive.spec.js ~~~ ;组件keep-alive属性的使用核心代码 .... one = { template: '<div>one</div>', created: jasmine.createSpy('one created'), mounted: jasmine.createSpy('one mounted'), activated: jasmine.createSpy('one activated'), deactivated: jasmine.createSpy('one deactivated'), destroyed: jasmine.createSpy('one destroyed') } two = { template: '<div>two</div>', created: jasmine.createSpy('two created'), mounted: jasmine.createSpy('two mounted'), activated: jasmine.createSpy('two activated'), deactivated: jasmine.createSpy('two deactivated'), destroyed: jasmine.createSpy('two destroyed') } components = { one, two } ;声明两个keep-alive组件的构子函数 function assertHookCalls (component, callCounts) { expect([ component.created.calls.count(), component.mounted.calls.count(), component.activated.calls.count(), component.deactivated.calls.count(), component.destroyed.calls.count() ]).toEqual(callCounts) } ;构子函数调用测试统计 const vm = new Vue({ template: '<div v-if="ok"><component :is="view" keep-alive></component></div>', data: { view: 'one', ok: true }, components }).$mount() ;ok控制组件使用 ;:is="view"控制组件的动态切换 vm = new Vue({ template: `<div> <component :is="view" class="test" keep-alive transition="test" transition-mode="out-in"> </component> </div>`, data: { view: 'one' }, components, transitions: { test: { afterLeave () { next() } } } }).$mount(el) ;使用transition="test" transition-mode="out-in"控制组件属性 ;class依次循环添加test-leave,test-leave-active,test-enter,test-enter-active,空,test-leave,test-leave-active,test-enter,test-enter-active,空等动画属性 ... vm = new Vue({ template: `<div> <component :is="view" class="test" keep-alive transition="test" transition-mode="in-out"> </component> </div>`, data: { view: 'one' }, components, transitions: { test: { afterEnter () { next() } } } }).$mount(el) ;与上个例子相似 ;class依次循环添加test-enter,test-enter-active,空,test-leave,test-leave-active,空,test-enter,test-enter-active,空,test-leave,test-leave-active,空等动画属性。 ... ~~~ > component-slot.spec.js ~~~ ;component-slot使用实例 ~~~~ ### .2(directives\\)指令测试 代码过多,按照组件的思路分析, ### .3(filter\\)过滤器测试 代码过多,按照组件的思路分析, ### .4(global-api\\)api扩展测试 代码过多,按照组件的思路分析, ### .5(instance\\)核心测试 代码过多,按照组件的思路分析, ### .6(options\\)选项测试 代码过多,按照组件的思路分析, ### .7(render\\)渲染测试 代码过多,按照组件的思路分析, ### .8(transition\\)动画测试 代码过多,按照组件的思路分析, ## 2-4 模块单元测试目录(unit\modules)分析 # 3 deom示例目录(examples\)分析 # 4 性能测试目录(benchmarks\)分析