├── .gitignore ├── 00-一言接口-文字打印 ├── index.html └── js │ └── jquery-3.1.1.min.js ├── 01-Vue基本模板 ├── index.html └── js │ └── vue.js ├── 02-Vue数据单向绑定 ├── index.html └── js │ └── vue.js ├── 03-Vue数据双向传递 ├── index.html └── js │ └── vue.js ├── 04-Vue指令v-once ├── index.html └── js │ └── vue.js ├── 05-Vue指令v-cloak ├── index.html └── js │ └── vue.js ├── 06-Vue指令v-text-v-html ├── index.html └── js │ └── vue.js ├── 07-Vue指令v-if ├── index.html └── js │ └── vue.js ├── 08-Vue指令v-show ├── index.html └── js │ └── vue.js ├── 09-Vue指令v-for ├── index.html └── js │ └── vue.js ├── 10-Vue指令v-bind ├── index.html └── js │ └── vue.js ├── 11-Vue指令绑定类名 ├── index.html └── js │ └── vue.js ├── 12-Vue指令绑定样式 ├── index.html └── js │ └── vue.js ├── 13-Vue指令v-on ├── index.html └── js │ └── vue.js ├── 14-Vue自定义全局指令 ├── index.html └── js │ └── vue.js ├── 15-Vue自定义局部指令 ├── index.html └── js │ └── vue.js ├── 16-Vue计算属性 ├── index.html └── js │ └── vue.js ├── 17-Vue计算属性和函数 ├── index.html └── js │ └── vue.js ├── 18-Vue自定义全局过滤器 ├── index.html └── js │ └── vue.js ├── 19-Vue自定义局部过滤器 ├── index.html └── js │ └── vue.js ├── 20-Vue过滤器练习-格式化时间 ├── index.html └── js │ └── vue.js ├── 21-Vue学生管理系统 ├── index.html └── js │ └── vue.js ├── 22-Vue过渡动画 ├── index.html └── js │ └── vue.js ├── 23-Vue过渡动画-JS钩子 ├── index.html └── js │ └── vue.js ├── 24-Vue过渡动画-Velocity ├── index.html └── js │ └── vue.js ├── 25-Vue过渡动画-自定义类名 ├── index.html └── js │ └── vue.js ├── 26-Vue过渡动画-Animate ├── index.html └── js │ └── vue.js ├── 27-Vue-v-for-key ├── index.html └── js │ └── vue.js ├── 28-Vue列表过渡 ├── index.html └── js │ └── vue.js ├── 29-Vue组件-自定义全局组件 ├── images │ ├── bg.jpg │ └── fm.jpg ├── index.html └── js │ └── vue.js ├── 30-Vue组件-自定义局部组件 ├── images │ ├── bg.jpg │ └── fm.jpg ├── index.html └── js │ └── vue.js ├── 31-Vue组件-data&methods ├── images │ ├── bg.jpg │ └── fm.jpg ├── index.html └── js │ └── vue.js ├── 32-Vue组件-组件切换 ├── images │ ├── bg.jpg │ └── fm.jpg ├── index.html └── js │ └── vue.js ├── 33-Vue组件-动态组件 ├── images │ ├── bg.jpg │ └── fm.jpg ├── index.html └── js │ └── vue.js ├── 34-Vue组件-组件动画 ├── images │ ├── bg.jpg │ └── fm.jpg ├── index.html └── js │ └── vue.js ├── 35-Vue组件-父子组件 ├── index.html └── js │ └── vue.js ├── 36-Vue组件-父子组件数据传递 ├── index.html └── js │ └── vue.js ├── 37-Vue组件-父子组件方法传递 ├── index.html └── js │ └── vue.js ├── 38-Vue组件-子父组件数据传递 ├── index.html └── js │ └── vue.js ├── 39-Vue组件-组件命名 ├── index.html └── js │ └── vue.js ├── 40-Vue组件-数据方法多级传递 ├── index.html └── js │ └── vue.js ├── 41-Vue组件-匿名插槽 ├── index.html └── js │ └── vue.js ├── 42-Vue组件-具名插槽 ├── index.html └── js │ └── vue.js ├── 43-Vue组件-v-slot指令 ├── index.html └── js │ └── vue.js ├── 44-Vue组件-作用域插槽 ├── index.html └── js │ └── vue.js ├── 45-Vue组件-数据传递练习 ├── index.html └── js │ └── vue.js ├── 46-Vuex-共享数据基本使用 ├── index.html └── js │ ├── vue.js │ └── vuex.js ├── 47-Vuex-修改共享数据 ├── index.html └── js │ ├── vue.js │ └── vuex.js ├── 48-Vuex-getters ├── index.html └── js │ ├── vue.js │ └── vuex.js ├── 49-VueRouter-基本介绍 ├── index.html └── js │ ├── vue-router.js │ └── vue.js ├── 50-VueRouter-传递参数 ├── index.html └── js │ ├── vue-router.js │ └── vue.js ├── 51-VueRouter-嵌套路由 ├── index.html └── js │ ├── vue-router.js │ └── vue.js ├── 52-VueRouter-命名视图 ├── index.html └── js │ ├── vue-router.js │ └── vue.js ├── 53-VueRouter-watch属性 ├── index.html └── js │ ├── vue-router.js │ └── vue.js ├── 54-Vue生命周期方法 ├── images │ └── lifecycle.png ├── index.html └── js │ └── vue.js ├── 55-Vue特殊特性 ├── index.html └── js │ └── vue.js └── 56-Vue-组件渲染方式 ├── index.html └── js └── vue.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | package-lock.json 8 | tests/**/coverage/ 9 | 10 | # Editor directories and files 11 | .idea 12 | .vscode 13 | *.suo 14 | *.ntvs* 15 | *.njsproj 16 | *.sln 17 | -------------------------------------------------------------------------------- /00-一言接口-文字打印/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 00-一言接口-文字打印 6 | 7 | 30 | 31 | 32 |
33 |
34 |
35 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /01-Vue基本模板/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 01-Vue基本模板 6 | 7 | 8 | 9 |
10 |

{{name}}

11 |
12 | 13 | 24 | 25 | 33 | -------------------------------------------------------------------------------- /02-Vue数据单向绑定/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 02-Vue数据单向绑定 6 | 7 | 8 | 9 |
10 |

{{name}}

11 |
12 | 13 | 24 | 25 | 35 | -------------------------------------------------------------------------------- /03-Vue数据双向传递/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 03-Vue数据双向传递 6 | 7 | 8 | 9 |
10 |

{{name}}

11 | 12 |
13 | 14 | 26 | 27 | 37 | -------------------------------------------------------------------------------- /04-Vue指令v-once/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 04-Vue指令v-once 6 | 7 | 8 | 9 |
10 |

原始数据:{{name}}

11 |

当前数据:{{name}}

12 |
13 | 14 | 25 | 26 | 39 | -------------------------------------------------------------------------------- /05-Vue指令v-cloak/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 05-Vue指令v-cloak 6 | 9 | 10 | 11 |
12 |

{{name}}

13 |

{{name}}

14 |
15 | 16 | 17 | 28 | 29 | 44 | -------------------------------------------------------------------------------- /06-Vue指令v-text-v-html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 06-Vue指令v-text-v-html 6 | 7 | 8 | 9 |
10 | 11 |

插值的方式: {{name}} 可以将指定的数据插入到指定的位置

12 | 13 |

插值的方式: {{msg}} 不会解析 HTML 标签

14 | 15 | 16 |

------

17 |

------

18 | 19 | 20 |

------

21 |

------

22 |
23 | 24 | 36 | 37 | -------------------------------------------------------------------------------- /07-Vue指令v-if/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 07-Vue指令v-if 6 | 7 | 8 | 9 |
10 |

我是true

11 |

我是false

12 | 13 |

我是true

14 |

我是false

15 | 16 |

我是true

17 |

我是false

18 | 19 |

我是成年人

20 |

我是未成年

21 | 22 |

优秀

23 |

良好

24 |

一般

25 |
26 | 27 | 41 | 42 | 60 | -------------------------------------------------------------------------------- /08-Vue指令v-show/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 08-Vue指令v-show 6 | 7 | 8 | 9 |
10 |

我是true

11 |

我是false

12 | 13 |

我是true

14 |

我是false

15 | 16 |

我是true

17 |

我是false

18 |
19 | 20 | 34 | 35 | 48 | -------------------------------------------------------------------------------- /09-Vue指令v-for/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 09-Vue指令v-for 6 | 7 | 8 | 9 |
10 | 13 | 14 | 17 | 18 | 21 | 22 | 25 |
26 | 27 | 45 | 46 | 53 | -------------------------------------------------------------------------------- /10-Vue指令v-bind/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10-Vue指令v-bind 6 | 7 | 8 | 9 |
10 |

{{name}}

11 |

12 | 13 | 14 | 15 |
16 | 17 | 28 | 29 | 47 | -------------------------------------------------------------------------------- /11-Vue指令绑定类名/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11-Vue指令绑定类名 6 | 7 | 22 | 23 | 24 |
25 |

这是段落

26 | 27 |

这是段落1: 通过数组绑定 class

28 | 29 |

这是段落2 通过三目运算符绑定 class

30 | 31 |

这是段落3:通过对应绑定 class

32 | 33 |

这是段落4: 通过实例中的对象来绑定 class

34 |
35 | 36 | 52 | 53 | 78 | -------------------------------------------------------------------------------- /12-Vue指令绑定样式/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12-Vue指令绑定样式 6 | 7 | 8 | 9 |
10 |

这是段落1

11 |

这是段落2

12 |

这是段落3

13 |
14 | 15 | 32 | 33 | 50 | -------------------------------------------------------------------------------- /13-Vue指令v-on/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13-Vue指令v-on 6 | 7 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 事件修饰符 .prevent 36 | 37 | 38 |
39 |
40 |
事件修饰符 .stop
41 |
42 |
43 | 44 | 45 |
46 |
47 |
事件修饰符 .self
48 |
49 |
50 | 51 | 52 |
53 |
54 |
事件修饰符 .capture
55 |
56 |
57 | 58 | 按键修饰符: 59 |
60 | 61 | 88 | 89 | 133 | -------------------------------------------------------------------------------- /14-Vue自定义全局指令/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14-Vue自定义全局指令 6 | 7 | 8 | 9 |
10 | 11 |

这是段落

12 | 13 | 14 |

这是段落传递颜色参数

15 | 16 | 17 | 18 |
19 | 20 | 57 | 58 | 92 | -------------------------------------------------------------------------------- /15-Vue自定义局部指令/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15-Vue自定义局部指令 6 | 7 | 8 | 9 |
10 |

这是段落1 使用了全局指令

11 | 12 |

这是段落1 使用了局部指令

13 |
14 |
15 |

这是段落2 使用了全局指令

16 | 17 |

这是段落2 使用了局部指令

18 |
19 | 20 | 58 | 59 | 77 | -------------------------------------------------------------------------------- /16-Vue计算属性/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16-Vue计算属性 6 | 7 | 8 | 9 |
10 |

{{name}}

11 |

{{age + 1}}

12 |

{{msg.split("").reverse().join("")}}

13 |

{{handleMsg}}

14 |
15 | 16 | 36 | 37 | 53 | -------------------------------------------------------------------------------- /17-Vue计算属性和函数/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17-Vue计算属性和函数 6 | 7 | 8 | 9 |
10 |

通过计算属性处理:{{cptMsg}}

11 |

通过计算属性处理:{{cptMsg}}

12 |

通过计算属性处理:{{cptMsg}}

13 |

通过计算属性处理:{{cptTime}} 次

14 | 15 |

通过方法处理: {{fnMsg()}}

16 |

通过方法处理: {{fnMsg()}}

17 |

通过方法处理: {{fnMsg()}}

18 |

通过方法处理:{{fnTime}} 次

19 |
20 | 21 | 50 | 51 | 61 | -------------------------------------------------------------------------------- /18-Vue自定义全局过滤器/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18-Vue自定义全局过滤器 6 | 7 | 8 | 9 |
10 | 11 |

{{name | formatStr | formatStr2}}

12 |
13 | 14 | 41 | 42 | 59 | -------------------------------------------------------------------------------- /19-Vue自定义局部过滤器/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19-Vue自定义局部过滤器 6 | 7 | 8 | 9 |
10 | 11 |

{{name | formatStr}}

12 |
13 |
14 |

{{name | formatStr}}

15 |
16 | 17 | 42 | 43 | 58 | -------------------------------------------------------------------------------- /20-Vue过滤器练习-格式化时间/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20-Vue过滤器练习-格式化时间 6 | 7 | 8 | 9 |
10 |

{{ time | dateFormat("yyyy-MM-dd") }}

11 |
12 | 13 | 41 | 42 | 48 | -------------------------------------------------------------------------------- /21-Vue学生管理系统/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 21-Vue学生管理系统 6 | 7 | 33 | 34 | 35 |
36 |
37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 61 | 62 |
序号姓名分数时间操作
57 | 编辑 58 | 删除
59 | 更多操作 60 |
63 |
64 | 65 | 141 | 142 | -------------------------------------------------------------------------------- /22-Vue过渡动画/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22-Vue过渡动画 6 | 7 | 53 | 54 | 55 |
56 | 57 | 58 |
59 |
60 | 61 | 62 |
63 |
64 |
65 | 66 | 82 | 83 | 106 | -------------------------------------------------------------------------------- /23-Vue过渡动画-JS钩子/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 23-Vue过渡动画-JS钩子 6 | 7 | 16 | 17 | 18 |
19 | 20 | 24 | 29 |
30 |
31 |
32 | 33 | 79 | 80 | 101 | -------------------------------------------------------------------------------- /24-Vue过渡动画-Velocity/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24-Vue过渡动画-Velocity 6 | 7 | 15 | 16 | 17 |
18 | 19 | 24 |
25 |
26 |
27 | 28 | 29 | 62 | 63 | 68 | -------------------------------------------------------------------------------- /25-Vue过渡动画-自定义类名/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25-Vue过渡动画-自定义类名 6 | 7 | 28 | 29 | 30 |
31 | 32 | 37 |
38 |
39 | > 40 |
41 | 42 | 58 | 59 | 71 | -------------------------------------------------------------------------------- /26-Vue过渡动画-Animate/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 26-Vue过渡动画-Animate 6 | 7 | 15 | 16 | 17 | 18 |
19 | 20 | 25 |
26 |
27 |
28 | 29 | 45 | 46 | 51 | -------------------------------------------------------------------------------- /27-Vue-v-for-key/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 27-Vue-v-for-key 6 | 7 | 8 | 9 |
10 |
11 | 12 | 13 |
14 | 20 |
21 | 22 | 47 | 48 | 60 | -------------------------------------------------------------------------------- /28-Vue列表过渡/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 28-Vue列表过渡 6 | 7 | 32 | 33 | 34 |
35 |
36 | 37 | 38 |
39 | 40 |
  • 41 | 42 | {{index}} - {{person.name}} 43 |
  • 44 |
    45 |
    46 | 47 | 77 | 78 | 90 | -------------------------------------------------------------------------------- /29-Vue组件-自定义全局组件/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/29-Vue组件-自定义全局组件/images/bg.jpg -------------------------------------------------------------------------------- /29-Vue组件-自定义全局组件/images/fm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/29-Vue组件-自定义全局组件/images/fm.jpg -------------------------------------------------------------------------------- /29-Vue组件-自定义全局组件/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 29-Vue组件-自定义全局组件 6 | 7 | 8 | 9 |
    10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
    19 | 20 | 26 | 27 | 33 | 77 | 78 | 142 | -------------------------------------------------------------------------------- /30-Vue组件-自定义局部组件/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/30-Vue组件-自定义局部组件/images/bg.jpg -------------------------------------------------------------------------------- /30-Vue组件-自定义局部组件/images/fm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/30-Vue组件-自定义局部组件/images/fm.jpg -------------------------------------------------------------------------------- /30-Vue组件-自定义局部组件/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 30-Vue组件-自定义局部组件 6 | 7 | 8 | 9 |
    10 | 11 | 12 |
    13 |
    14 | 15 | 16 |
    17 | 18 | 24 | 30 | 57 | 58 | 74 | -------------------------------------------------------------------------------- /31-Vue组件-data&methods/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/31-Vue组件-data&methods/images/bg.jpg -------------------------------------------------------------------------------- /31-Vue组件-data&methods/images/fm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/31-Vue组件-data&methods/images/fm.jpg -------------------------------------------------------------------------------- /31-Vue组件-data&methods/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 31-Vue组件-data&methods 6 | 7 | 8 | 9 |
    10 | 13 | 14 |

    {{app_data}}

    15 | 16 |
    17 | 18 | 19 | 20 |
    21 | 22 | 23 | 24 | 25 |
    26 | 34 | 35 | 41 | 42 | 92 | 93 | 104 | -------------------------------------------------------------------------------- /32-Vue组件-组件切换/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/32-Vue组件-组件切换/images/bg.jpg -------------------------------------------------------------------------------- /32-Vue组件-组件切换/images/fm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/32-Vue组件-组件切换/images/fm.jpg -------------------------------------------------------------------------------- /32-Vue组件-组件切换/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 32-Vue组件-组件切换 6 | 7 | 8 | 9 |
    10 | 11 |

    首页

    12 | 13 | 14 |
    15 | 16 | 17 | 18 | 19 |
    20 | 25 | 28 | 29 | 60 | 61 | 66 | -------------------------------------------------------------------------------- /33-Vue组件-动态组件/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/33-Vue组件-动态组件/images/bg.jpg -------------------------------------------------------------------------------- /33-Vue组件-动态组件/images/fm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/33-Vue组件-动态组件/images/fm.jpg -------------------------------------------------------------------------------- /33-Vue组件-动态组件/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 33-Vue组件-动态组件 6 | 7 | 8 | 9 |
    10 | 11 | 12 | 13 | 14 |
    15 | 21 | 24 | 25 | 54 | 55 | 65 | -------------------------------------------------------------------------------- /34-Vue组件-组件动画/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/34-Vue组件-组件动画/images/bg.jpg -------------------------------------------------------------------------------- /34-Vue组件-组件动画/images/fm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/34-Vue组件-组件动画/images/fm.jpg -------------------------------------------------------------------------------- /34-Vue组件-组件动画/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 34-Vue组件-组件动画 6 | 7 | 29 | 30 | 31 |
    32 | 33 | 34 | 35 | 36 |
    37 | 43 | 46 | 47 | 76 | 77 | 87 | -------------------------------------------------------------------------------- /35-Vue组件-父子组件/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 35-Vue组件-父子组件 6 | 7 | 8 | 9 |
    10 | 11 | 12 |
    13 | 18 | 19 | 26 | 27 | 32 | 33 | 59 | 60 | 70 | -------------------------------------------------------------------------------- /36-Vue组件-父子组件数据传递/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 36-Vue组件-父子组件数据传递 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 21 | 22 | 28 | 29 | 57 | 58 | ` 72 | -------------------------------------------------------------------------------- /37-Vue组件-父子组件方法传递/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 37-Vue组件-父子组件方法传递 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 19 | 20 | 25 | 26 | 59 | 60 | 70 | -------------------------------------------------------------------------------- /38-Vue组件-子父组件数据传递/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 38-Vue组件-子父组件数据传递 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 19 | 20 | 25 | 26 | 66 | 67 | 76 | -------------------------------------------------------------------------------- /39-Vue组件-组件命名/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 39-Vue组件-组件命名 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 19 | 20 | 26 | 27 | 66 | 67 | 78 | -------------------------------------------------------------------------------- /40-Vue组件-数据方法多级传递/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 40-Vue组件-数据方法多级传递 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 21 | 22 | 30 | 31 | 37 | 38 | 89 | 90 | 95 | -------------------------------------------------------------------------------- /41-Vue组件-匿名插槽/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 41-Vue组件-匿名插槽 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 27 | 28 | 37 | 38 | 62 | 63 | 85 | -------------------------------------------------------------------------------- /42-Vue组件-具名插槽/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 42-Vue组件-具名插槽 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 28 | 29 | 39 | 40 | 64 | 65 | 78 | -------------------------------------------------------------------------------- /43-Vue组件-v-slot指令/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 43-Vue组件-v-slot指令 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 28 | 29 | 39 | 40 | 64 | 65 | 76 | -------------------------------------------------------------------------------- /44-Vue组件-作用域插槽/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 44-Vue组件-作用域插槽 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 29 | 30 | 42 | 43 | 72 | 73 | 93 | -------------------------------------------------------------------------------- /45-Vue组件-数据传递练习/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 45-Vue组件-数据传递练习 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 13 | 20 | 21 | 29 | 35 | 36 | 86 | 87 | 103 | -------------------------------------------------------------------------------- /46-Vuex-共享数据基本使用/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 46-Vue组件-Vuex 6 | 7 | 8 | 9 | 10 |
    11 | 12 |
    13 | 14 | 20 | 26 | 27 | 32 | 33 | 68 | 69 | 78 | -------------------------------------------------------------------------------- /46-Vuex-共享数据基本使用/js/vuex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * vuex v2.0.0 3 | * (c) 2016 Evan You 4 | * @license MIT 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 | typeof define === 'function' && define.amd ? define(factory) : 9 | (global.Vuex = factory()); 10 | }(this, (function () { 'use strict'; 11 | 12 | var devtoolHook = 13 | typeof window !== 'undefined' && 14 | window.__VUE_DEVTOOLS_GLOBAL_HOOK__ 15 | 16 | function devtoolPlugin (store) { 17 | if (!devtoolHook) { return } 18 | 19 | store._devtoolHook = devtoolHook 20 | 21 | devtoolHook.emit('vuex:init', store) 22 | 23 | devtoolHook.on('vuex:travel-to-state', function (targetState) { 24 | store.replaceState(targetState) 25 | }) 26 | 27 | store.subscribe(function (mutation, state) { 28 | devtoolHook.emit('vuex:mutation', mutation, state) 29 | }) 30 | } 31 | 32 | function applyMixin (Vue) { 33 | var version = Number(Vue.version.split('.')[0]) 34 | 35 | if (version >= 2) { 36 | var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1 37 | Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit }) 38 | } else { 39 | // override init and inject vuex init procedure 40 | // for 1.x backwards compatibility. 41 | var _init = Vue.prototype._init 42 | Vue.prototype._init = function (options) { 43 | if ( options === void 0 ) options = {}; 44 | 45 | options.init = options.init 46 | ? [vuexInit].concat(options.init) 47 | : vuexInit 48 | _init.call(this, options) 49 | } 50 | } 51 | 52 | /** 53 | * Vuex init hook, injected into each instances init hooks list. 54 | */ 55 | 56 | function vuexInit () { 57 | var options = this.$options 58 | // store injection 59 | if (options.store) { 60 | this.$store = options.store 61 | } else if (options.parent && options.parent.$store) { 62 | this.$store = options.parent.$store 63 | } 64 | } 65 | } 66 | 67 | function mapState (states) { 68 | var res = {} 69 | normalizeMap(states).forEach(function (ref) { 70 | var key = ref.key; 71 | var val = ref.val; 72 | 73 | res[key] = function mappedState () { 74 | return typeof val === 'function' 75 | ? val.call(this, this.$store.state, this.$store.getters) 76 | : this.$store.state[val] 77 | } 78 | }) 79 | return res 80 | } 81 | 82 | function mapMutations (mutations) { 83 | var res = {} 84 | normalizeMap(mutations).forEach(function (ref) { 85 | var key = ref.key; 86 | var val = ref.val; 87 | 88 | res[key] = function mappedMutation () { 89 | var args = [], len = arguments.length; 90 | while ( len-- ) args[ len ] = arguments[ len ]; 91 | 92 | return this.$store.commit.apply(this.$store, [val].concat(args)) 93 | } 94 | }) 95 | return res 96 | } 97 | 98 | function mapGetters (getters) { 99 | var res = {} 100 | normalizeMap(getters).forEach(function (ref) { 101 | var key = ref.key; 102 | var val = ref.val; 103 | 104 | res[key] = function mappedGetter () { 105 | if (!(val in this.$store.getters)) { 106 | console.error(("[vuex] unknown getter: " + val)) 107 | } 108 | return this.$store.getters[val] 109 | } 110 | }) 111 | return res 112 | } 113 | 114 | function mapActions (actions) { 115 | var res = {} 116 | normalizeMap(actions).forEach(function (ref) { 117 | var key = ref.key; 118 | var val = ref.val; 119 | 120 | res[key] = function mappedAction () { 121 | var args = [], len = arguments.length; 122 | while ( len-- ) args[ len ] = arguments[ len ]; 123 | 124 | return this.$store.dispatch.apply(this.$store, [val].concat(args)) 125 | } 126 | }) 127 | return res 128 | } 129 | 130 | function normalizeMap (map) { 131 | return Array.isArray(map) 132 | ? map.map(function (key) { return ({ key: key, val: key }); }) 133 | : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); }) 134 | } 135 | 136 | function isObject (obj) { 137 | return obj !== null && typeof obj === 'object' 138 | } 139 | 140 | function isPromise (val) { 141 | return val && typeof val.then === 'function' 142 | } 143 | 144 | function assert (condition, msg) { 145 | if (!condition) { throw new Error(("[vuex] " + msg)) } 146 | } 147 | 148 | var Vue // bind on install 149 | 150 | var Store = function Store (options) { 151 | var this$1 = this; 152 | if ( options === void 0 ) options = {}; 153 | 154 | assert(Vue, "must call Vue.use(Vuex) before creating a store instance.") 155 | assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.") 156 | 157 | var state = options.state; if ( state === void 0 ) state = {}; 158 | var plugins = options.plugins; if ( plugins === void 0 ) plugins = []; 159 | var strict = options.strict; if ( strict === void 0 ) strict = false; 160 | 161 | // store internal state 162 | this._options = options 163 | this._committing = false 164 | this._actions = Object.create(null) 165 | this._mutations = Object.create(null) 166 | this._wrappedGetters = Object.create(null) 167 | this._runtimeModules = Object.create(null) 168 | this._subscribers = [] 169 | this._watcherVM = new Vue() 170 | 171 | // bind commit and dispatch to self 172 | var store = this 173 | var ref = this; 174 | var dispatch = ref.dispatch; 175 | var commit = ref.commit; 176 | this.dispatch = function boundDispatch (type, payload) { 177 | return dispatch.call(store, type, payload) 178 | } 179 | this.commit = function boundCommit (type, payload, options) { 180 | return commit.call(store, type, payload, options) 181 | } 182 | 183 | // strict mode 184 | this.strict = strict 185 | 186 | // init root module. 187 | // this also recursively registers all sub-modules 188 | // and collects all module getters inside this._wrappedGetters 189 | installModule(this, state, [], options) 190 | 191 | // initialize the store vm, which is responsible for the reactivity 192 | // (also registers _wrappedGetters as computed properties) 193 | resetStoreVM(this, state) 194 | 195 | // apply plugins 196 | plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); }) 197 | }; 198 | 199 | var prototypeAccessors = { state: {} }; 200 | 201 | prototypeAccessors.state.get = function () { 202 | return this._vm.state 203 | }; 204 | 205 | prototypeAccessors.state.set = function (v) { 206 | assert(false, "Use store.replaceState() to explicit replace store state.") 207 | }; 208 | 209 | Store.prototype.commit = function commit (type, payload, options) { 210 | var this$1 = this; 211 | 212 | // check object-style commit 213 | if (isObject(type) && type.type) { 214 | options = payload 215 | payload = type 216 | type = type.type 217 | } 218 | var mutation = { type: type, payload: payload } 219 | var entry = this._mutations[type] 220 | if (!entry) { 221 | console.error(("[vuex] unknown mutation type: " + type)) 222 | return 223 | } 224 | this._withCommit(function () { 225 | entry.forEach(function commitIterator (handler) { 226 | handler(payload) 227 | }) 228 | }) 229 | if (!options || !options.silent) { 230 | this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); }) 231 | } 232 | }; 233 | 234 | Store.prototype.dispatch = function dispatch (type, payload) { 235 | // check object-style dispatch 236 | if (isObject(type) && type.type) { 237 | payload = type 238 | type = type.type 239 | } 240 | var entry = this._actions[type] 241 | if (!entry) { 242 | console.error(("[vuex] unknown action type: " + type)) 243 | return 244 | } 245 | return entry.length > 1 246 | ? Promise.all(entry.map(function (handler) { return handler(payload); })) 247 | : entry[0](payload) 248 | }; 249 | 250 | Store.prototype.subscribe = function subscribe (fn) { 251 | var subs = this._subscribers 252 | if (subs.indexOf(fn) < 0) { 253 | subs.push(fn) 254 | } 255 | return function () { 256 | var i = subs.indexOf(fn) 257 | if (i > -1) { 258 | subs.splice(i, 1) 259 | } 260 | } 261 | }; 262 | 263 | Store.prototype.watch = function watch (getter, cb, options) { 264 | var this$1 = this; 265 | 266 | assert(typeof getter === 'function', "store.watch only accepts a function.") 267 | return this._watcherVM.$watch(function () { return getter(this$1.state); }, cb, options) 268 | }; 269 | 270 | Store.prototype.replaceState = function replaceState (state) { 271 | var this$1 = this; 272 | 273 | this._withCommit(function () { 274 | this$1._vm.state = state 275 | }) 276 | }; 277 | 278 | Store.prototype.registerModule = function registerModule (path, module) { 279 | if (typeof path === 'string') { path = [path] } 280 | assert(Array.isArray(path), "module path must be a string or an Array.") 281 | this._runtimeModules[path.join('.')] = module 282 | installModule(this, this.state, path, module) 283 | // reset store to update getters... 284 | resetStoreVM(this, this.state) 285 | }; 286 | 287 | Store.prototype.unregisterModule = function unregisterModule (path) { 288 | var this$1 = this; 289 | 290 | if (typeof path === 'string') { path = [path] } 291 | assert(Array.isArray(path), "module path must be a string or an Array.") 292 | delete this._runtimeModules[path.join('.')] 293 | this._withCommit(function () { 294 | var parentState = getNestedState(this$1.state, path.slice(0, -1)) 295 | Vue.delete(parentState, path[path.length - 1]) 296 | }) 297 | resetStore(this) 298 | }; 299 | 300 | Store.prototype.hotUpdate = function hotUpdate (newOptions) { 301 | updateModule(this._options, newOptions) 302 | resetStore(this) 303 | }; 304 | 305 | Store.prototype._withCommit = function _withCommit (fn) { 306 | var committing = this._committing 307 | this._committing = true 308 | fn() 309 | this._committing = committing 310 | }; 311 | 312 | Object.defineProperties( Store.prototype, prototypeAccessors ); 313 | 314 | function updateModule (targetModule, newModule) { 315 | if (newModule.actions) { 316 | targetModule.actions = newModule.actions 317 | } 318 | if (newModule.mutations) { 319 | targetModule.mutations = newModule.mutations 320 | } 321 | if (newModule.getters) { 322 | targetModule.getters = newModule.getters 323 | } 324 | if (newModule.modules) { 325 | for (var key in newModule.modules) { 326 | if (!(targetModule.modules && targetModule.modules[key])) { 327 | console.warn( 328 | "[vuex] trying to add a new module '" + key + "' on hot reloading, " + 329 | 'manual reload is needed' 330 | ) 331 | return 332 | } 333 | updateModule(targetModule.modules[key], newModule.modules[key]) 334 | } 335 | } 336 | } 337 | 338 | function resetStore (store) { 339 | store._actions = Object.create(null) 340 | store._mutations = Object.create(null) 341 | store._wrappedGetters = Object.create(null) 342 | var state = store.state 343 | // init root module 344 | installModule(store, state, [], store._options, true) 345 | // init all runtime modules 346 | Object.keys(store._runtimeModules).forEach(function (key) { 347 | installModule(store, state, key.split('.'), store._runtimeModules[key], true) 348 | }) 349 | // reset vm 350 | resetStoreVM(store, state) 351 | } 352 | 353 | function resetStoreVM (store, state) { 354 | var oldVm = store._vm 355 | 356 | // bind store public getters 357 | store.getters = {} 358 | var wrappedGetters = store._wrappedGetters 359 | var computed = {} 360 | Object.keys(wrappedGetters).forEach(function (key) { 361 | var fn = wrappedGetters[key] 362 | // use computed to leverage its lazy-caching mechanism 363 | computed[key] = function () { return fn(store); } 364 | Object.defineProperty(store.getters, key, { 365 | get: function () { return store._vm[key]; } 366 | }) 367 | }) 368 | 369 | // use a Vue instance to store the state tree 370 | // suppress warnings just in case the user has added 371 | // some funky global mixins 372 | var silent = Vue.config.silent 373 | Vue.config.silent = true 374 | store._vm = new Vue({ 375 | data: { state: state }, 376 | computed: computed 377 | }) 378 | Vue.config.silent = silent 379 | 380 | // enable strict mode for new vm 381 | if (store.strict) { 382 | enableStrictMode(store) 383 | } 384 | 385 | if (oldVm) { 386 | // dispatch changes in all subscribed watchers 387 | // to force getter re-evaluation. 388 | store._withCommit(function () { 389 | oldVm.state = null 390 | }) 391 | Vue.nextTick(function () { return oldVm.$destroy(); }) 392 | } 393 | } 394 | 395 | function installModule (store, rootState, path, module, hot) { 396 | var isRoot = !path.length 397 | var state = module.state; 398 | var actions = module.actions; 399 | var mutations = module.mutations; 400 | var getters = module.getters; 401 | var modules = module.modules; 402 | 403 | // set state 404 | if (!isRoot && !hot) { 405 | var parentState = getNestedState(rootState, path.slice(0, -1)) 406 | var moduleName = path[path.length - 1] 407 | store._withCommit(function () { 408 | Vue.set(parentState, moduleName, state || {}) 409 | }) 410 | } 411 | 412 | if (mutations) { 413 | Object.keys(mutations).forEach(function (key) { 414 | registerMutation(store, key, mutations[key], path) 415 | }) 416 | } 417 | 418 | if (actions) { 419 | Object.keys(actions).forEach(function (key) { 420 | registerAction(store, key, actions[key], path) 421 | }) 422 | } 423 | 424 | if (getters) { 425 | wrapGetters(store, getters, path) 426 | } 427 | 428 | if (modules) { 429 | Object.keys(modules).forEach(function (key) { 430 | installModule(store, rootState, path.concat(key), modules[key], hot) 431 | }) 432 | } 433 | } 434 | 435 | function registerMutation (store, type, handler, path) { 436 | if ( path === void 0 ) path = []; 437 | 438 | var entry = store._mutations[type] || (store._mutations[type] = []) 439 | entry.push(function wrappedMutationHandler (payload) { 440 | handler(getNestedState(store.state, path), payload) 441 | }) 442 | } 443 | 444 | function registerAction (store, type, handler, path) { 445 | if ( path === void 0 ) path = []; 446 | 447 | var entry = store._actions[type] || (store._actions[type] = []) 448 | var dispatch = store.dispatch; 449 | var commit = store.commit; 450 | entry.push(function wrappedActionHandler (payload, cb) { 451 | var res = handler({ 452 | dispatch: dispatch, 453 | commit: commit, 454 | getters: store.getters, 455 | state: getNestedState(store.state, path), 456 | rootState: store.state 457 | }, payload, cb) 458 | if (!isPromise(res)) { 459 | res = Promise.resolve(res) 460 | } 461 | if (store._devtoolHook) { 462 | return res.catch(function (err) { 463 | store._devtoolHook.emit('vuex:error', err) 464 | throw err 465 | }) 466 | } else { 467 | return res 468 | } 469 | }) 470 | } 471 | 472 | function wrapGetters (store, moduleGetters, modulePath) { 473 | Object.keys(moduleGetters).forEach(function (getterKey) { 474 | var rawGetter = moduleGetters[getterKey] 475 | if (store._wrappedGetters[getterKey]) { 476 | console.error(("[vuex] duplicate getter key: " + getterKey)) 477 | return 478 | } 479 | store._wrappedGetters[getterKey] = function wrappedGetter (store) { 480 | return rawGetter( 481 | getNestedState(store.state, modulePath), // local state 482 | store.getters, // getters 483 | store.state // root state 484 | ) 485 | } 486 | }) 487 | } 488 | 489 | function enableStrictMode (store) { 490 | store._vm.$watch('state', function () { 491 | assert(store._committing, "Do not mutate vuex store state outside mutation handlers.") 492 | }, { deep: true, sync: true }) 493 | } 494 | 495 | function getNestedState (state, path) { 496 | return path.length 497 | ? path.reduce(function (state, key) { return state[key]; }, state) 498 | : state 499 | } 500 | 501 | function install (_Vue) { 502 | if (Vue) { 503 | console.error( 504 | '[vuex] already installed. Vue.use(Vuex) should be called only once.' 505 | ) 506 | return 507 | } 508 | Vue = _Vue 509 | applyMixin(Vue) 510 | } 511 | 512 | // auto install in dist mode 513 | if (typeof window !== 'undefined' && window.Vue) { 514 | install(window.Vue) 515 | } 516 | 517 | var index = { 518 | Store: Store, 519 | install: install, 520 | mapState: mapState, 521 | mapMutations: mapMutations, 522 | mapGetters: mapGetters, 523 | mapActions: mapActions 524 | } 525 | 526 | return index; 527 | 528 | }))); -------------------------------------------------------------------------------- /47-Vuex-修改共享数据/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 47-Vuex-修改共享数据 6 | 7 | 8 | 9 | 10 |
    11 | 12 |
    13 | 14 | 21 | 22 | 30 | 38 | 39 | 103 | 104 | 130 | -------------------------------------------------------------------------------- /47-Vuex-修改共享数据/js/vuex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * vuex v2.0.0 3 | * (c) 2016 Evan You 4 | * @license MIT 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 | typeof define === 'function' && define.amd ? define(factory) : 9 | (global.Vuex = factory()); 10 | }(this, (function () { 'use strict'; 11 | 12 | var devtoolHook = 13 | typeof window !== 'undefined' && 14 | window.__VUE_DEVTOOLS_GLOBAL_HOOK__ 15 | 16 | function devtoolPlugin (store) { 17 | if (!devtoolHook) { return } 18 | 19 | store._devtoolHook = devtoolHook 20 | 21 | devtoolHook.emit('vuex:init', store) 22 | 23 | devtoolHook.on('vuex:travel-to-state', function (targetState) { 24 | store.replaceState(targetState) 25 | }) 26 | 27 | store.subscribe(function (mutation, state) { 28 | devtoolHook.emit('vuex:mutation', mutation, state) 29 | }) 30 | } 31 | 32 | function applyMixin (Vue) { 33 | var version = Number(Vue.version.split('.')[0]) 34 | 35 | if (version >= 2) { 36 | var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1 37 | Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit }) 38 | } else { 39 | // override init and inject vuex init procedure 40 | // for 1.x backwards compatibility. 41 | var _init = Vue.prototype._init 42 | Vue.prototype._init = function (options) { 43 | if ( options === void 0 ) options = {}; 44 | 45 | options.init = options.init 46 | ? [vuexInit].concat(options.init) 47 | : vuexInit 48 | _init.call(this, options) 49 | } 50 | } 51 | 52 | /** 53 | * Vuex init hook, injected into each instances init hooks list. 54 | */ 55 | 56 | function vuexInit () { 57 | var options = this.$options 58 | // store injection 59 | if (options.store) { 60 | this.$store = options.store 61 | } else if (options.parent && options.parent.$store) { 62 | this.$store = options.parent.$store 63 | } 64 | } 65 | } 66 | 67 | function mapState (states) { 68 | var res = {} 69 | normalizeMap(states).forEach(function (ref) { 70 | var key = ref.key; 71 | var val = ref.val; 72 | 73 | res[key] = function mappedState () { 74 | return typeof val === 'function' 75 | ? val.call(this, this.$store.state, this.$store.getters) 76 | : this.$store.state[val] 77 | } 78 | }) 79 | return res 80 | } 81 | 82 | function mapMutations (mutations) { 83 | var res = {} 84 | normalizeMap(mutations).forEach(function (ref) { 85 | var key = ref.key; 86 | var val = ref.val; 87 | 88 | res[key] = function mappedMutation () { 89 | var args = [], len = arguments.length; 90 | while ( len-- ) args[ len ] = arguments[ len ]; 91 | 92 | return this.$store.commit.apply(this.$store, [val].concat(args)) 93 | } 94 | }) 95 | return res 96 | } 97 | 98 | function mapGetters (getters) { 99 | var res = {} 100 | normalizeMap(getters).forEach(function (ref) { 101 | var key = ref.key; 102 | var val = ref.val; 103 | 104 | res[key] = function mappedGetter () { 105 | if (!(val in this.$store.getters)) { 106 | console.error(("[vuex] unknown getter: " + val)) 107 | } 108 | return this.$store.getters[val] 109 | } 110 | }) 111 | return res 112 | } 113 | 114 | function mapActions (actions) { 115 | var res = {} 116 | normalizeMap(actions).forEach(function (ref) { 117 | var key = ref.key; 118 | var val = ref.val; 119 | 120 | res[key] = function mappedAction () { 121 | var args = [], len = arguments.length; 122 | while ( len-- ) args[ len ] = arguments[ len ]; 123 | 124 | return this.$store.dispatch.apply(this.$store, [val].concat(args)) 125 | } 126 | }) 127 | return res 128 | } 129 | 130 | function normalizeMap (map) { 131 | return Array.isArray(map) 132 | ? map.map(function (key) { return ({ key: key, val: key }); }) 133 | : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); }) 134 | } 135 | 136 | function isObject (obj) { 137 | return obj !== null && typeof obj === 'object' 138 | } 139 | 140 | function isPromise (val) { 141 | return val && typeof val.then === 'function' 142 | } 143 | 144 | function assert (condition, msg) { 145 | if (!condition) { throw new Error(("[vuex] " + msg)) } 146 | } 147 | 148 | var Vue // bind on install 149 | 150 | var Store = function Store (options) { 151 | var this$1 = this; 152 | if ( options === void 0 ) options = {}; 153 | 154 | assert(Vue, "must call Vue.use(Vuex) before creating a store instance.") 155 | assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.") 156 | 157 | var state = options.state; if ( state === void 0 ) state = {}; 158 | var plugins = options.plugins; if ( plugins === void 0 ) plugins = []; 159 | var strict = options.strict; if ( strict === void 0 ) strict = false; 160 | 161 | // store internal state 162 | this._options = options 163 | this._committing = false 164 | this._actions = Object.create(null) 165 | this._mutations = Object.create(null) 166 | this._wrappedGetters = Object.create(null) 167 | this._runtimeModules = Object.create(null) 168 | this._subscribers = [] 169 | this._watcherVM = new Vue() 170 | 171 | // bind commit and dispatch to self 172 | var store = this 173 | var ref = this; 174 | var dispatch = ref.dispatch; 175 | var commit = ref.commit; 176 | this.dispatch = function boundDispatch (type, payload) { 177 | return dispatch.call(store, type, payload) 178 | } 179 | this.commit = function boundCommit (type, payload, options) { 180 | return commit.call(store, type, payload, options) 181 | } 182 | 183 | // strict mode 184 | this.strict = strict 185 | 186 | // init root module. 187 | // this also recursively registers all sub-modules 188 | // and collects all module getters inside this._wrappedGetters 189 | installModule(this, state, [], options) 190 | 191 | // initialize the store vm, which is responsible for the reactivity 192 | // (also registers _wrappedGetters as computed properties) 193 | resetStoreVM(this, state) 194 | 195 | // apply plugins 196 | plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); }) 197 | }; 198 | 199 | var prototypeAccessors = { state: {} }; 200 | 201 | prototypeAccessors.state.get = function () { 202 | return this._vm.state 203 | }; 204 | 205 | prototypeAccessors.state.set = function (v) { 206 | assert(false, "Use store.replaceState() to explicit replace store state.") 207 | }; 208 | 209 | Store.prototype.commit = function commit (type, payload, options) { 210 | var this$1 = this; 211 | 212 | // check object-style commit 213 | if (isObject(type) && type.type) { 214 | options = payload 215 | payload = type 216 | type = type.type 217 | } 218 | var mutation = { type: type, payload: payload } 219 | var entry = this._mutations[type] 220 | if (!entry) { 221 | console.error(("[vuex] unknown mutation type: " + type)) 222 | return 223 | } 224 | this._withCommit(function () { 225 | entry.forEach(function commitIterator (handler) { 226 | handler(payload) 227 | }) 228 | }) 229 | if (!options || !options.silent) { 230 | this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); }) 231 | } 232 | }; 233 | 234 | Store.prototype.dispatch = function dispatch (type, payload) { 235 | // check object-style dispatch 236 | if (isObject(type) && type.type) { 237 | payload = type 238 | type = type.type 239 | } 240 | var entry = this._actions[type] 241 | if (!entry) { 242 | console.error(("[vuex] unknown action type: " + type)) 243 | return 244 | } 245 | return entry.length > 1 246 | ? Promise.all(entry.map(function (handler) { return handler(payload); })) 247 | : entry[0](payload) 248 | }; 249 | 250 | Store.prototype.subscribe = function subscribe (fn) { 251 | var subs = this._subscribers 252 | if (subs.indexOf(fn) < 0) { 253 | subs.push(fn) 254 | } 255 | return function () { 256 | var i = subs.indexOf(fn) 257 | if (i > -1) { 258 | subs.splice(i, 1) 259 | } 260 | } 261 | }; 262 | 263 | Store.prototype.watch = function watch (getter, cb, options) { 264 | var this$1 = this; 265 | 266 | assert(typeof getter === 'function', "store.watch only accepts a function.") 267 | return this._watcherVM.$watch(function () { return getter(this$1.state); }, cb, options) 268 | }; 269 | 270 | Store.prototype.replaceState = function replaceState (state) { 271 | var this$1 = this; 272 | 273 | this._withCommit(function () { 274 | this$1._vm.state = state 275 | }) 276 | }; 277 | 278 | Store.prototype.registerModule = function registerModule (path, module) { 279 | if (typeof path === 'string') { path = [path] } 280 | assert(Array.isArray(path), "module path must be a string or an Array.") 281 | this._runtimeModules[path.join('.')] = module 282 | installModule(this, this.state, path, module) 283 | // reset store to update getters... 284 | resetStoreVM(this, this.state) 285 | }; 286 | 287 | Store.prototype.unregisterModule = function unregisterModule (path) { 288 | var this$1 = this; 289 | 290 | if (typeof path === 'string') { path = [path] } 291 | assert(Array.isArray(path), "module path must be a string or an Array.") 292 | delete this._runtimeModules[path.join('.')] 293 | this._withCommit(function () { 294 | var parentState = getNestedState(this$1.state, path.slice(0, -1)) 295 | Vue.delete(parentState, path[path.length - 1]) 296 | }) 297 | resetStore(this) 298 | }; 299 | 300 | Store.prototype.hotUpdate = function hotUpdate (newOptions) { 301 | updateModule(this._options, newOptions) 302 | resetStore(this) 303 | }; 304 | 305 | Store.prototype._withCommit = function _withCommit (fn) { 306 | var committing = this._committing 307 | this._committing = true 308 | fn() 309 | this._committing = committing 310 | }; 311 | 312 | Object.defineProperties( Store.prototype, prototypeAccessors ); 313 | 314 | function updateModule (targetModule, newModule) { 315 | if (newModule.actions) { 316 | targetModule.actions = newModule.actions 317 | } 318 | if (newModule.mutations) { 319 | targetModule.mutations = newModule.mutations 320 | } 321 | if (newModule.getters) { 322 | targetModule.getters = newModule.getters 323 | } 324 | if (newModule.modules) { 325 | for (var key in newModule.modules) { 326 | if (!(targetModule.modules && targetModule.modules[key])) { 327 | console.warn( 328 | "[vuex] trying to add a new module '" + key + "' on hot reloading, " + 329 | 'manual reload is needed' 330 | ) 331 | return 332 | } 333 | updateModule(targetModule.modules[key], newModule.modules[key]) 334 | } 335 | } 336 | } 337 | 338 | function resetStore (store) { 339 | store._actions = Object.create(null) 340 | store._mutations = Object.create(null) 341 | store._wrappedGetters = Object.create(null) 342 | var state = store.state 343 | // init root module 344 | installModule(store, state, [], store._options, true) 345 | // init all runtime modules 346 | Object.keys(store._runtimeModules).forEach(function (key) { 347 | installModule(store, state, key.split('.'), store._runtimeModules[key], true) 348 | }) 349 | // reset vm 350 | resetStoreVM(store, state) 351 | } 352 | 353 | function resetStoreVM (store, state) { 354 | var oldVm = store._vm 355 | 356 | // bind store public getters 357 | store.getters = {} 358 | var wrappedGetters = store._wrappedGetters 359 | var computed = {} 360 | Object.keys(wrappedGetters).forEach(function (key) { 361 | var fn = wrappedGetters[key] 362 | // use computed to leverage its lazy-caching mechanism 363 | computed[key] = function () { return fn(store); } 364 | Object.defineProperty(store.getters, key, { 365 | get: function () { return store._vm[key]; } 366 | }) 367 | }) 368 | 369 | // use a Vue instance to store the state tree 370 | // suppress warnings just in case the user has added 371 | // some funky global mixins 372 | var silent = Vue.config.silent 373 | Vue.config.silent = true 374 | store._vm = new Vue({ 375 | data: { state: state }, 376 | computed: computed 377 | }) 378 | Vue.config.silent = silent 379 | 380 | // enable strict mode for new vm 381 | if (store.strict) { 382 | enableStrictMode(store) 383 | } 384 | 385 | if (oldVm) { 386 | // dispatch changes in all subscribed watchers 387 | // to force getter re-evaluation. 388 | store._withCommit(function () { 389 | oldVm.state = null 390 | }) 391 | Vue.nextTick(function () { return oldVm.$destroy(); }) 392 | } 393 | } 394 | 395 | function installModule (store, rootState, path, module, hot) { 396 | var isRoot = !path.length 397 | var state = module.state; 398 | var actions = module.actions; 399 | var mutations = module.mutations; 400 | var getters = module.getters; 401 | var modules = module.modules; 402 | 403 | // set state 404 | if (!isRoot && !hot) { 405 | var parentState = getNestedState(rootState, path.slice(0, -1)) 406 | var moduleName = path[path.length - 1] 407 | store._withCommit(function () { 408 | Vue.set(parentState, moduleName, state || {}) 409 | }) 410 | } 411 | 412 | if (mutations) { 413 | Object.keys(mutations).forEach(function (key) { 414 | registerMutation(store, key, mutations[key], path) 415 | }) 416 | } 417 | 418 | if (actions) { 419 | Object.keys(actions).forEach(function (key) { 420 | registerAction(store, key, actions[key], path) 421 | }) 422 | } 423 | 424 | if (getters) { 425 | wrapGetters(store, getters, path) 426 | } 427 | 428 | if (modules) { 429 | Object.keys(modules).forEach(function (key) { 430 | installModule(store, rootState, path.concat(key), modules[key], hot) 431 | }) 432 | } 433 | } 434 | 435 | function registerMutation (store, type, handler, path) { 436 | if ( path === void 0 ) path = []; 437 | 438 | var entry = store._mutations[type] || (store._mutations[type] = []) 439 | entry.push(function wrappedMutationHandler (payload) { 440 | handler(getNestedState(store.state, path), payload) 441 | }) 442 | } 443 | 444 | function registerAction (store, type, handler, path) { 445 | if ( path === void 0 ) path = []; 446 | 447 | var entry = store._actions[type] || (store._actions[type] = []) 448 | var dispatch = store.dispatch; 449 | var commit = store.commit; 450 | entry.push(function wrappedActionHandler (payload, cb) { 451 | var res = handler({ 452 | dispatch: dispatch, 453 | commit: commit, 454 | getters: store.getters, 455 | state: getNestedState(store.state, path), 456 | rootState: store.state 457 | }, payload, cb) 458 | if (!isPromise(res)) { 459 | res = Promise.resolve(res) 460 | } 461 | if (store._devtoolHook) { 462 | return res.catch(function (err) { 463 | store._devtoolHook.emit('vuex:error', err) 464 | throw err 465 | }) 466 | } else { 467 | return res 468 | } 469 | }) 470 | } 471 | 472 | function wrapGetters (store, moduleGetters, modulePath) { 473 | Object.keys(moduleGetters).forEach(function (getterKey) { 474 | var rawGetter = moduleGetters[getterKey] 475 | if (store._wrappedGetters[getterKey]) { 476 | console.error(("[vuex] duplicate getter key: " + getterKey)) 477 | return 478 | } 479 | store._wrappedGetters[getterKey] = function wrappedGetter (store) { 480 | return rawGetter( 481 | getNestedState(store.state, modulePath), // local state 482 | store.getters, // getters 483 | store.state // root state 484 | ) 485 | } 486 | }) 487 | } 488 | 489 | function enableStrictMode (store) { 490 | store._vm.$watch('state', function () { 491 | assert(store._committing, "Do not mutate vuex store state outside mutation handlers.") 492 | }, { deep: true, sync: true }) 493 | } 494 | 495 | function getNestedState (state, path) { 496 | return path.length 497 | ? path.reduce(function (state, key) { return state[key]; }, state) 498 | : state 499 | } 500 | 501 | function install (_Vue) { 502 | if (Vue) { 503 | console.error( 504 | '[vuex] already installed. Vue.use(Vuex) should be called only once.' 505 | ) 506 | return 507 | } 508 | Vue = _Vue 509 | applyMixin(Vue) 510 | } 511 | 512 | // auto install in dist mode 513 | if (typeof window !== 'undefined' && window.Vue) { 514 | install(window.Vue) 515 | } 516 | 517 | var index = { 518 | Store: Store, 519 | install: install, 520 | mapState: mapState, 521 | mapMutations: mapMutations, 522 | mapGetters: mapGetters, 523 | mapActions: mapActions 524 | } 525 | 526 | return index; 527 | 528 | }))); -------------------------------------------------------------------------------- /48-Vuex-getters/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 48-Vuex-getters 6 | 7 | 8 | 9 | 10 |
    11 | 12 |
    13 | 14 | 27 | 28 | 72 | 73 | 80 | -------------------------------------------------------------------------------- /48-Vuex-getters/js/vuex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * vuex v2.0.0 3 | * (c) 2016 Evan You 4 | * @license MIT 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 | typeof define === 'function' && define.amd ? define(factory) : 9 | (global.Vuex = factory()); 10 | }(this, (function () { 'use strict'; 11 | 12 | var devtoolHook = 13 | typeof window !== 'undefined' && 14 | window.__VUE_DEVTOOLS_GLOBAL_HOOK__ 15 | 16 | function devtoolPlugin (store) { 17 | if (!devtoolHook) { return } 18 | 19 | store._devtoolHook = devtoolHook 20 | 21 | devtoolHook.emit('vuex:init', store) 22 | 23 | devtoolHook.on('vuex:travel-to-state', function (targetState) { 24 | store.replaceState(targetState) 25 | }) 26 | 27 | store.subscribe(function (mutation, state) { 28 | devtoolHook.emit('vuex:mutation', mutation, state) 29 | }) 30 | } 31 | 32 | function applyMixin (Vue) { 33 | var version = Number(Vue.version.split('.')[0]) 34 | 35 | if (version >= 2) { 36 | var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1 37 | Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit }) 38 | } else { 39 | // override init and inject vuex init procedure 40 | // for 1.x backwards compatibility. 41 | var _init = Vue.prototype._init 42 | Vue.prototype._init = function (options) { 43 | if ( options === void 0 ) options = {}; 44 | 45 | options.init = options.init 46 | ? [vuexInit].concat(options.init) 47 | : vuexInit 48 | _init.call(this, options) 49 | } 50 | } 51 | 52 | /** 53 | * Vuex init hook, injected into each instances init hooks list. 54 | */ 55 | 56 | function vuexInit () { 57 | var options = this.$options 58 | // store injection 59 | if (options.store) { 60 | this.$store = options.store 61 | } else if (options.parent && options.parent.$store) { 62 | this.$store = options.parent.$store 63 | } 64 | } 65 | } 66 | 67 | function mapState (states) { 68 | var res = {} 69 | normalizeMap(states).forEach(function (ref) { 70 | var key = ref.key; 71 | var val = ref.val; 72 | 73 | res[key] = function mappedState () { 74 | return typeof val === 'function' 75 | ? val.call(this, this.$store.state, this.$store.getters) 76 | : this.$store.state[val] 77 | } 78 | }) 79 | return res 80 | } 81 | 82 | function mapMutations (mutations) { 83 | var res = {} 84 | normalizeMap(mutations).forEach(function (ref) { 85 | var key = ref.key; 86 | var val = ref.val; 87 | 88 | res[key] = function mappedMutation () { 89 | var args = [], len = arguments.length; 90 | while ( len-- ) args[ len ] = arguments[ len ]; 91 | 92 | return this.$store.commit.apply(this.$store, [val].concat(args)) 93 | } 94 | }) 95 | return res 96 | } 97 | 98 | function mapGetters (getters) { 99 | var res = {} 100 | normalizeMap(getters).forEach(function (ref) { 101 | var key = ref.key; 102 | var val = ref.val; 103 | 104 | res[key] = function mappedGetter () { 105 | if (!(val in this.$store.getters)) { 106 | console.error(("[vuex] unknown getter: " + val)) 107 | } 108 | return this.$store.getters[val] 109 | } 110 | }) 111 | return res 112 | } 113 | 114 | function mapActions (actions) { 115 | var res = {} 116 | normalizeMap(actions).forEach(function (ref) { 117 | var key = ref.key; 118 | var val = ref.val; 119 | 120 | res[key] = function mappedAction () { 121 | var args = [], len = arguments.length; 122 | while ( len-- ) args[ len ] = arguments[ len ]; 123 | 124 | return this.$store.dispatch.apply(this.$store, [val].concat(args)) 125 | } 126 | }) 127 | return res 128 | } 129 | 130 | function normalizeMap (map) { 131 | return Array.isArray(map) 132 | ? map.map(function (key) { return ({ key: key, val: key }); }) 133 | : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); }) 134 | } 135 | 136 | function isObject (obj) { 137 | return obj !== null && typeof obj === 'object' 138 | } 139 | 140 | function isPromise (val) { 141 | return val && typeof val.then === 'function' 142 | } 143 | 144 | function assert (condition, msg) { 145 | if (!condition) { throw new Error(("[vuex] " + msg)) } 146 | } 147 | 148 | var Vue // bind on install 149 | 150 | var Store = function Store (options) { 151 | var this$1 = this; 152 | if ( options === void 0 ) options = {}; 153 | 154 | assert(Vue, "must call Vue.use(Vuex) before creating a store instance.") 155 | assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.") 156 | 157 | var state = options.state; if ( state === void 0 ) state = {}; 158 | var plugins = options.plugins; if ( plugins === void 0 ) plugins = []; 159 | var strict = options.strict; if ( strict === void 0 ) strict = false; 160 | 161 | // store internal state 162 | this._options = options 163 | this._committing = false 164 | this._actions = Object.create(null) 165 | this._mutations = Object.create(null) 166 | this._wrappedGetters = Object.create(null) 167 | this._runtimeModules = Object.create(null) 168 | this._subscribers = [] 169 | this._watcherVM = new Vue() 170 | 171 | // bind commit and dispatch to self 172 | var store = this 173 | var ref = this; 174 | var dispatch = ref.dispatch; 175 | var commit = ref.commit; 176 | this.dispatch = function boundDispatch (type, payload) { 177 | return dispatch.call(store, type, payload) 178 | } 179 | this.commit = function boundCommit (type, payload, options) { 180 | return commit.call(store, type, payload, options) 181 | } 182 | 183 | // strict mode 184 | this.strict = strict 185 | 186 | // init root module. 187 | // this also recursively registers all sub-modules 188 | // and collects all module getters inside this._wrappedGetters 189 | installModule(this, state, [], options) 190 | 191 | // initialize the store vm, which is responsible for the reactivity 192 | // (also registers _wrappedGetters as computed properties) 193 | resetStoreVM(this, state) 194 | 195 | // apply plugins 196 | plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); }) 197 | }; 198 | 199 | var prototypeAccessors = { state: {} }; 200 | 201 | prototypeAccessors.state.get = function () { 202 | return this._vm.state 203 | }; 204 | 205 | prototypeAccessors.state.set = function (v) { 206 | assert(false, "Use store.replaceState() to explicit replace store state.") 207 | }; 208 | 209 | Store.prototype.commit = function commit (type, payload, options) { 210 | var this$1 = this; 211 | 212 | // check object-style commit 213 | if (isObject(type) && type.type) { 214 | options = payload 215 | payload = type 216 | type = type.type 217 | } 218 | var mutation = { type: type, payload: payload } 219 | var entry = this._mutations[type] 220 | if (!entry) { 221 | console.error(("[vuex] unknown mutation type: " + type)) 222 | return 223 | } 224 | this._withCommit(function () { 225 | entry.forEach(function commitIterator (handler) { 226 | handler(payload) 227 | }) 228 | }) 229 | if (!options || !options.silent) { 230 | this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); }) 231 | } 232 | }; 233 | 234 | Store.prototype.dispatch = function dispatch (type, payload) { 235 | // check object-style dispatch 236 | if (isObject(type) && type.type) { 237 | payload = type 238 | type = type.type 239 | } 240 | var entry = this._actions[type] 241 | if (!entry) { 242 | console.error(("[vuex] unknown action type: " + type)) 243 | return 244 | } 245 | return entry.length > 1 246 | ? Promise.all(entry.map(function (handler) { return handler(payload); })) 247 | : entry[0](payload) 248 | }; 249 | 250 | Store.prototype.subscribe = function subscribe (fn) { 251 | var subs = this._subscribers 252 | if (subs.indexOf(fn) < 0) { 253 | subs.push(fn) 254 | } 255 | return function () { 256 | var i = subs.indexOf(fn) 257 | if (i > -1) { 258 | subs.splice(i, 1) 259 | } 260 | } 261 | }; 262 | 263 | Store.prototype.watch = function watch (getter, cb, options) { 264 | var this$1 = this; 265 | 266 | assert(typeof getter === 'function', "store.watch only accepts a function.") 267 | return this._watcherVM.$watch(function () { return getter(this$1.state); }, cb, options) 268 | }; 269 | 270 | Store.prototype.replaceState = function replaceState (state) { 271 | var this$1 = this; 272 | 273 | this._withCommit(function () { 274 | this$1._vm.state = state 275 | }) 276 | }; 277 | 278 | Store.prototype.registerModule = function registerModule (path, module) { 279 | if (typeof path === 'string') { path = [path] } 280 | assert(Array.isArray(path), "module path must be a string or an Array.") 281 | this._runtimeModules[path.join('.')] = module 282 | installModule(this, this.state, path, module) 283 | // reset store to update getters... 284 | resetStoreVM(this, this.state) 285 | }; 286 | 287 | Store.prototype.unregisterModule = function unregisterModule (path) { 288 | var this$1 = this; 289 | 290 | if (typeof path === 'string') { path = [path] } 291 | assert(Array.isArray(path), "module path must be a string or an Array.") 292 | delete this._runtimeModules[path.join('.')] 293 | this._withCommit(function () { 294 | var parentState = getNestedState(this$1.state, path.slice(0, -1)) 295 | Vue.delete(parentState, path[path.length - 1]) 296 | }) 297 | resetStore(this) 298 | }; 299 | 300 | Store.prototype.hotUpdate = function hotUpdate (newOptions) { 301 | updateModule(this._options, newOptions) 302 | resetStore(this) 303 | }; 304 | 305 | Store.prototype._withCommit = function _withCommit (fn) { 306 | var committing = this._committing 307 | this._committing = true 308 | fn() 309 | this._committing = committing 310 | }; 311 | 312 | Object.defineProperties( Store.prototype, prototypeAccessors ); 313 | 314 | function updateModule (targetModule, newModule) { 315 | if (newModule.actions) { 316 | targetModule.actions = newModule.actions 317 | } 318 | if (newModule.mutations) { 319 | targetModule.mutations = newModule.mutations 320 | } 321 | if (newModule.getters) { 322 | targetModule.getters = newModule.getters 323 | } 324 | if (newModule.modules) { 325 | for (var key in newModule.modules) { 326 | if (!(targetModule.modules && targetModule.modules[key])) { 327 | console.warn( 328 | "[vuex] trying to add a new module '" + key + "' on hot reloading, " + 329 | 'manual reload is needed' 330 | ) 331 | return 332 | } 333 | updateModule(targetModule.modules[key], newModule.modules[key]) 334 | } 335 | } 336 | } 337 | 338 | function resetStore (store) { 339 | store._actions = Object.create(null) 340 | store._mutations = Object.create(null) 341 | store._wrappedGetters = Object.create(null) 342 | var state = store.state 343 | // init root module 344 | installModule(store, state, [], store._options, true) 345 | // init all runtime modules 346 | Object.keys(store._runtimeModules).forEach(function (key) { 347 | installModule(store, state, key.split('.'), store._runtimeModules[key], true) 348 | }) 349 | // reset vm 350 | resetStoreVM(store, state) 351 | } 352 | 353 | function resetStoreVM (store, state) { 354 | var oldVm = store._vm 355 | 356 | // bind store public getters 357 | store.getters = {} 358 | var wrappedGetters = store._wrappedGetters 359 | var computed = {} 360 | Object.keys(wrappedGetters).forEach(function (key) { 361 | var fn = wrappedGetters[key] 362 | // use computed to leverage its lazy-caching mechanism 363 | computed[key] = function () { return fn(store); } 364 | Object.defineProperty(store.getters, key, { 365 | get: function () { return store._vm[key]; } 366 | }) 367 | }) 368 | 369 | // use a Vue instance to store the state tree 370 | // suppress warnings just in case the user has added 371 | // some funky global mixins 372 | var silent = Vue.config.silent 373 | Vue.config.silent = true 374 | store._vm = new Vue({ 375 | data: { state: state }, 376 | computed: computed 377 | }) 378 | Vue.config.silent = silent 379 | 380 | // enable strict mode for new vm 381 | if (store.strict) { 382 | enableStrictMode(store) 383 | } 384 | 385 | if (oldVm) { 386 | // dispatch changes in all subscribed watchers 387 | // to force getter re-evaluation. 388 | store._withCommit(function () { 389 | oldVm.state = null 390 | }) 391 | Vue.nextTick(function () { return oldVm.$destroy(); }) 392 | } 393 | } 394 | 395 | function installModule (store, rootState, path, module, hot) { 396 | var isRoot = !path.length 397 | var state = module.state; 398 | var actions = module.actions; 399 | var mutations = module.mutations; 400 | var getters = module.getters; 401 | var modules = module.modules; 402 | 403 | // set state 404 | if (!isRoot && !hot) { 405 | var parentState = getNestedState(rootState, path.slice(0, -1)) 406 | var moduleName = path[path.length - 1] 407 | store._withCommit(function () { 408 | Vue.set(parentState, moduleName, state || {}) 409 | }) 410 | } 411 | 412 | if (mutations) { 413 | Object.keys(mutations).forEach(function (key) { 414 | registerMutation(store, key, mutations[key], path) 415 | }) 416 | } 417 | 418 | if (actions) { 419 | Object.keys(actions).forEach(function (key) { 420 | registerAction(store, key, actions[key], path) 421 | }) 422 | } 423 | 424 | if (getters) { 425 | wrapGetters(store, getters, path) 426 | } 427 | 428 | if (modules) { 429 | Object.keys(modules).forEach(function (key) { 430 | installModule(store, rootState, path.concat(key), modules[key], hot) 431 | }) 432 | } 433 | } 434 | 435 | function registerMutation (store, type, handler, path) { 436 | if ( path === void 0 ) path = []; 437 | 438 | var entry = store._mutations[type] || (store._mutations[type] = []) 439 | entry.push(function wrappedMutationHandler (payload) { 440 | handler(getNestedState(store.state, path), payload) 441 | }) 442 | } 443 | 444 | function registerAction (store, type, handler, path) { 445 | if ( path === void 0 ) path = []; 446 | 447 | var entry = store._actions[type] || (store._actions[type] = []) 448 | var dispatch = store.dispatch; 449 | var commit = store.commit; 450 | entry.push(function wrappedActionHandler (payload, cb) { 451 | var res = handler({ 452 | dispatch: dispatch, 453 | commit: commit, 454 | getters: store.getters, 455 | state: getNestedState(store.state, path), 456 | rootState: store.state 457 | }, payload, cb) 458 | if (!isPromise(res)) { 459 | res = Promise.resolve(res) 460 | } 461 | if (store._devtoolHook) { 462 | return res.catch(function (err) { 463 | store._devtoolHook.emit('vuex:error', err) 464 | throw err 465 | }) 466 | } else { 467 | return res 468 | } 469 | }) 470 | } 471 | 472 | function wrapGetters (store, moduleGetters, modulePath) { 473 | Object.keys(moduleGetters).forEach(function (getterKey) { 474 | var rawGetter = moduleGetters[getterKey] 475 | if (store._wrappedGetters[getterKey]) { 476 | console.error(("[vuex] duplicate getter key: " + getterKey)) 477 | return 478 | } 479 | store._wrappedGetters[getterKey] = function wrappedGetter (store) { 480 | return rawGetter( 481 | getNestedState(store.state, modulePath), // local state 482 | store.getters, // getters 483 | store.state // root state 484 | ) 485 | } 486 | }) 487 | } 488 | 489 | function enableStrictMode (store) { 490 | store._vm.$watch('state', function () { 491 | assert(store._committing, "Do not mutate vuex store state outside mutation handlers.") 492 | }, { deep: true, sync: true }) 493 | } 494 | 495 | function getNestedState (state, path) { 496 | return path.length 497 | ? path.reduce(function (state, key) { return state[key]; }, state) 498 | : state 499 | } 500 | 501 | function install (_Vue) { 502 | if (Vue) { 503 | console.error( 504 | '[vuex] already installed. Vue.use(Vuex) should be called only once.' 505 | ) 506 | return 507 | } 508 | Vue = _Vue 509 | applyMixin(Vue) 510 | } 511 | 512 | // auto install in dist mode 513 | if (typeof window !== 'undefined' && window.Vue) { 514 | install(window.Vue) 515 | } 516 | 517 | var index = { 518 | Store: Store, 519 | install: install, 520 | mapState: mapState, 521 | mapMutations: mapMutations, 522 | mapGetters: mapGetters, 523 | mapActions: mapActions 524 | } 525 | 526 | return index; 527 | 528 | }))); -------------------------------------------------------------------------------- /49-VueRouter-基本介绍/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 49-VueRouter-基本介绍 6 | 7 | 8 | 13 | 14 | 15 |
    16 | 切换到第一个界面 17 | 切换到第二个界面 18 | 19 | 20 | 21 |
    22 | 27 | 32 | 33 | 69 | 70 | 95 | -------------------------------------------------------------------------------- /50-VueRouter-传递参数/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 50-VueRouter-传递参数 6 | 7 | 8 | 13 | 14 | 15 |
    16 | 切换到第一个界面 17 | 切换到第二个界面 18 | 19 | 20 | 21 |
    22 | 27 | 32 | 33 | 79 | 80 | 90 | -------------------------------------------------------------------------------- /51-VueRouter-嵌套路由/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 51-VueRouter-嵌套路由 6 | 7 | 8 | 13 | 14 | 15 |
    16 | 切换到第一个界面 17 | 切换到第二个界面 18 | 19 | 20 | 21 |
    22 | 31 | 36 | 41 | 46 | 47 | 95 | 96 | 119 | -------------------------------------------------------------------------------- /52-VueRouter-命名视图/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 52-VueRouter-命名视图 6 | 7 | 8 | 13 | 14 | 15 |
    16 | 17 | 18 | 19 |
    20 | 25 | 30 | 31 | 78 | 79 | 100 | -------------------------------------------------------------------------------- /53-VueRouter-watch属性/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 53-VueRouter-watch属性 6 | 7 | 8 | 13 | 14 | 15 |
    16 |

    使用监听键盘抬起方法实现加法

    17 | 18 | + 19 | 20 | = 21 | 22 | 23 |
    24 |

    使用watch属性实现加法

    25 | 26 | + 27 | 28 | = 29 | 30 | 31 |
    32 |

    使用watch属性实现监听路由变化

    33 | 切换到第一个界面 34 | 切换到第二个界面 35 | 36 | 37 | 38 |
    39 | 44 | 49 | 50 | 112 | 113 | 123 | -------------------------------------------------------------------------------- /54-Vue生命周期方法/images/lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsy0216/vue-learnning/82c2902639c1a0bfc623fab6247c195593eb8cae/54-Vue生命周期方法/images/lifecycle.png -------------------------------------------------------------------------------- /54-Vue生命周期方法/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 54-Vue-生命周期方法 6 | 7 | 8 | 9 |
    10 | 11 | 12 |

    {{msg}}

    13 | 14 | 生命周期图示 15 |
    16 | 19 | 20 | 69 | 70 | 91 | -------------------------------------------------------------------------------- /55-Vue特殊特性/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 55-Vue特殊特性 6 | 7 | 8 | 9 |
    10 | 11 | 12 |

    这是p元素标签渲染的内容

    13 | 14 |
    15 | 20 | 21 | 52 | 53 | 69 | -------------------------------------------------------------------------------- /56-Vue-组件渲染方式/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 56-Vue-组件渲染方式 6 | 7 | 8 | 9 |
    10 | 11 |
    12 | 17 | 18 | 36 | 37 | 59 | --------------------------------------------------------------------------------