Vue框架

一.导读:

1.什么是Vue

Vue.js是一个渐进式JavaScript框架
渐进式:vue从小到控制页面中的一个变量到页面一块内容到整个页面,最终大到整个项目,都可以用vue框架来实现

2.vue可以做哪些事

将数据渲染到指定区域(数据可以是后台获取,也可以由前台自己产生)
可以与页面完成基于数据的交互方式

3.为什么学习Vue

  1.整合了Angular React框架的优点(第一手API文档是中文的)
  2.单页面应用(得益于vue的组件化开发 => 前台代码的复用),减少IO,提高效率
  3.虚拟DOM(提高操作DOM的效应)
  4.数据的双向绑定(如:两个输入框同步数据)

二.如何使用Vue:

 1 <body>
 2     <div id="box1">
 3         <!--{{ }} 会被vue解析为数据的渲染的指定语法-->
 4         {{ }}
 5     </div>
 6     <hr>
 7     <div class="box2">
 8         {{ }}
 9     </div>
10 </body>
11 <script src="js/vue.js"></script>
12 <script>
13     // 如何使用jq框架 <= 拿到jq框架的对象 $ | jQuery
14     // 类比:如何使用vue框架 <= 拿到vue框架的对象 new Vue()
15 
16     // vue对象需要手动创建, 原因:一个vue对象可以只控制页面中的某一部分, 如果一个页面有多个部分都需要被控制,那么就需要创建多个vue对象
17     // vue对象如何与控制的页面进行关联(绑定),采用的是vue对象中的挂载点(挂载点可以唯一标识页面中的某一个区域)
18     new Vue({
19         el: "#box1"
20         // 挂在在id为box1的div上,那么该div下的所有内容都由该vue对象来控制
21     })
22 
23     new Vue({
24         el: '.box2'
25         // 挂在在class为box2的div上,那么该div下的所有内容都由该vue对象来控制(尽量使用id,唯一标识)
26     })
27 </script>

三.Vue实例成员:

1.挂载点

new Vue({
    el: '#app'
})
// 实例与页面挂载点一一对应
// 一个页面中可以出现多个实例对应多个挂载点
// 实例只操作挂载点内部内容

2.数据data

 1 <body>
 2     <div id="app">
 3         {{ msg }}
 4     </div>
 5 </body>
 6 <script src="js/vue.js"></script>
 7 <script>
 8     // Vue实例会根据数据产生虚拟DOM,最终替换掉挂载点的真实DOM(不要挂在到body上)
 9     var app = new Vue({
10         el: '#app',
11         data: {
12             msg: "今晚嘿嘿"
13         }
14     });
15 
16     // 如果需要使用vue对象(实例), 那么久可以接受Vue创建的结果, 反之就不需要接收
17     console.log(app);
18     console.log(app.$attrs); // vue实例的变量都是以$开头
19     console.log(app.$el);
20     console.log(app.$data.msg);
21     console.log(app.msg);
22     // app对象 = new Vue()实例 = 标签div #app组件
23 
24 </script>

3.方法methods

 1 <style>
 2     .box { background-color: orange }
 3 </style>
 4 <div id='app'>
 5     <p class="box" v-on:click="pClick">测试</p>
 6     <p class="box" v-on:mouseover="pOver">测试</p>
 7 </div>
 8 <script>
 9     var app = new Vue({
10         el: '#app',
11         methods: {
12             pClick () {
13                 // 点击测试
14             },
15             pOver () {
16                 // 悬浮测试
17             }
18         }
19     })
20 </script>
21 <!-- 了解v-on:为事件绑定的指令 -->
22 <!-- methods为事件提供实现体-->

4.计算computed

 1 <body>
 2     <div id="app">
 3         姓<input type="text" v-model="first_name">
 4         <hr>
 5         名<input type="text" v-model="last_name">
 6         <hr>
 7         <p>{{ first_name + " " + last_name }}</p>
 8         <p>{{ full_name_fn() }}</p>
 9         <!-- 一个变量的值依赖于多个变量的值 -->
10         <p>{{ full_name }}</p>
11     </div>
12 </body>
13 <script src="js/vue.js"></script>
14 <script>
15     new Vue({
16         el: "#app",
17         data: {
18             first_name: "",
19             last_name: "",
20         },
21         methods: {
22             // 声明的是函数, 该函数必须手动调用
23             full_name_fn: function () {
24                 return this.first_name + " " + this.last_name
25             }
26         },
27         computed: {
28             // 声明变量full_name, 该变量的值等于后方函数的返回值
29             // 函数中包含的所有vue变量值只要有发生变化的系统就会调用该函数
30             full_name: function () {
31                 return this.first_name + " " + this.last_name
32             }
33         }
34     })
35 </script>

5.监听watch

 1 <body>
 2     <div id="app">
 3         姓名<input type="text" v-model="full_name">
 4         <hr>
 5         <p>{{ first_name }}</p>
 6         <hr>
 7         <p>{{ last_name }}</p>
 8     </div>
 9 </body>
10 <script src="js/vue.js"></script>
11 <script>
12     new Vue({
13         el: "#app",
14         data: {
15             full_name: "",
16             first_name: "",
17             last_name: "",
18         },
19         watch: {
20             // wacth只是对已有的变量进行值变化的监听, 一旦发现值变化,系统自动回调监听变量后的函数
21             // 后方函数和前方变量只有数据变化的监听绑定关系, 没有值相关的联系
22             full_name: function () {
23                 arr = this.full_name.split(" ");
24                 this.first_name = arr[0];
25                 this.last_name = arr[1];
26             }
27         }
28     })
29 </script>

四.基础指令

1.文本指令(v-text/v-html)

 1 <body>
 2     <div id="app">
 3         <p>{{ info }}</p>
 4         <!-- v-text 为vue的文本指令 ="info" , info为vue实例data中的一个变量 -->
 5         <p v-text="info"></p>
 6         <p v-text="msg"></p>
 7         <p v-html="res"></p>
 8     </div>
 9 </body>
10 <script src="js/vue.js"></script>
11 <script>
12     new Vue({
13         el: "#app",
14         data: {
15             info: "插值表达式",
16             msg: "文本指令",
17             res: "<b>加粗的文本</b>"
18         }
19     })
20 </script>

2.属性指令(v-bind/:)

 1 <body>
 2     <div id="app">
 3         <!-- v-bind:属性 = "变量" -->
 4         <!-- 如果abc自定义属性被v-bind:指令绑定了,后面的值也会成为vue变量, 如果就想是普通字符串, 再用''包裹 -->
 5         <!-- : 就是 v-bind: 的简写方式 (1.常用 2.一定且只操作属性)-->
        #abc不是变量名 6 <p v-bind:abc="'abc'" v-bind:title="h_info" :def="hehe">abc</p> 7 8 <!--最常用的两个属性 class | style--> 9 10 <!--class--> 11 <p :class="a"></p> <!-- 单类名 --> 12 <p :class="[a, b]"></p> <!-- 多类名 --> 13 <p :class="{c: d}"></p> <!-- 了解: c为类名,是否起作用取决于d值为true|false 开关类名 --> 14 <!--style--> 15 <p :style="s1"></p> <!-- s1为一套样式 --> 16 <p :style="[s1, s2, {textAlign: ta}]">12345</p><!-- 了解: s1,s2均为一套样式, ta是一个变量,专门赋值给textAlign("text-align") --> 17 18 </div> 19 </body> 20 <script src="js/vue.js"></script> 21 <script> 22 new Vue({ 23 el: "#app", 24 data: { 25 h_info: "悬浮提示", 26 hehe: "呵呵", 27 a: 'active', 28 b: 'rule', 29 d: false, 30 s1: { // 样式1: 值1, ..., 样式n: 值n 31 '200px', 32 height: '200px', 33 background: 'red' 34 }, 35 s2: { 36 borderRadius: '50%' 37 }, 38 ta: 'center' 39 } 40 }) 41 </script>

3.事件指令(v-on:click/@click)

 1 <body>
 2     <div id="app">
 3         <!-- v-on:事件 = "变量 简写 @ -->
 4         <!-- 事件绑定的变量可以在data中赋值,但建议在methods中赋值 -->
 5         <p v-on:click="fn1">11111111111111</p>
 6         <p @click="fn2">22222222222222</p>
 7         <!--vue事件的绑定可以传自定义参数-->
 8         <p @click="fn3(333)">3333333333333333</p>
 9         <!--vue事件的绑定不传自定义参数, 默认将事件对象传过去了-->
10         <p @click="fn4">4444444444444444</p>
11         <!--vue事件的绑定传自定义参数, 还要将事件对象传过去了, 要明确传$event-->
12         <p @click="fn5(555, $event)">5555555555555555</p>
13 
14     </div>
15 </body>
16 <script src="js/vue.js"></script>
17 <script>
18     new Vue({
19         el: "#app",
20         data: {
21             // 事件在data中提供一个函数地址,可以实现事件
22             fn1: function () {
23                 console.log("11111111111111")
24             }
25         },
26         // 事件尽量(要求)都放在vue实例的methods中
27         methods: {
28             fn2: function () {
29                 console.log("22222222222222")
30             },
31             fn3 (arg) {  // ES6语法
32                 console.log(arg)
33             },
34             fn4: function (ev) {
35                 console.log(ev)
36             },
37             fn5: function (arg, ev) {
38                 console.log(arg)
39                 console.log(ev)
40             },
41         }
42     })
43 </script>

4.表单指令(v-model)

 1 <body>
 2     <div id="app">
 3         <!-- v-model = "变量" 本质操作的就是表单元素的value -->
 4         <!--v-model就是完成数据的双向绑定-->
 5         <form action="">
 6             <input type="text" v-model="info"> <!-- info变量就是代表输入框的value -->
 7             <input type="text" v-model="info">
 8 
 9         </form>
10         <p> {{ info }} </p>
11         <!--v-once只会被赋值一次,就不再改变,并且要结合插值表达式使用-->
12         <p v-once="info">{{ info }}</p>
13     </div>
14 </body>
15 <script src="js/vue.js"></script>
16 <script>
17     new Vue({
18         el: "#app",
19         data: {
20 //            info: "初始value",
21             info: ""
22         },
23     })
24 </script>

5.条件指令(v-if/v-show)

 1 <style>
 2     .wrap {
 3          300px;
 4     }
 5     .box {
 6          100px;
 7         height: 100px;
 8     }
 9     .red {
10         background-color: red;
11         float: left;
12     }
13     .orange {
14         background-color: orange;
15         float: right;
16     }
17 </style>
18 <body>
19     <div id="app">
20         <button @click="rAction">red切换</button>
21         <button @click="oAction">orange切换</button>
22         <div class="wrap">
23             <!-- v-if 值为false时, 不会被渲染   -->
24             <!-- 了解 :key由vue控制的属性key值需要唯一标识,因为key的值就是vue对该组件在内存中建立缓存的key -->
25             <div class="box red" v-if="r_show" :key="key" ></div>
26             <!-- v-show 值为false时, 以display:none被渲染 -->
27             <div class="box orange" v-show="o_show"></div>
28         </div>
29     </div>
30 </body>
31 <script src="js/vue.js"></script>
32 <script>
33     new Vue({
34         el: "#app",
35         data: {
36             r_show: true,
37             o_show: true
38         },
39         methods: {
40             rAction: function () {
41                 this.r_show = !this.r_show;
42             },
43             oAction: function () {
44                 this.o_show = !this.o_show;
45             }
46         }
47     })
48 </script>
  • 条件案例:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>条件指令案例</title>
 6     <style>
 7         .box {
 8             height: 100px;
 9         }
10         .r { background-color: red }
11         .y { background-color: yellow }
12         .b { background-color: blue }
13     </style>
14 </head>
15 <body>
16     <div id="app">
17         <ul>
18             <li @click="rfn">红</li>
19             <li @click="yfn">黄</li>
20             <li @click="bfn">蓝</li>
21         </ul>
22         <div class="box r" v-if="tag == 0"></div>
23         <div class="box y" v-else-if="tag == 1"></div>
24         <div class="box b" v-else></div>
25     </div>
26 </body>
27 <script src="js/vue.js"></script>
28 <script>
29     new Vue({
30         el: '#app',
31         data: {
32             tag: 0
33         },
34         methods: {
35             rfn: function () {
36                 this.tag = 0
37             },
38             yfn: function () {
39                 this.tag = 1
40             },
41             bfn: function () {
42                 this.tag = 2
43             },
44         }
45     })
46 </script>
47 </html>
红黄蓝

6.循环指令(v-for)

 1 <body>
 2     <div id="app">
 3         <ul>
 4             <li>{{ ls[0] }}</li>
 5             <li>{{ ls[1] }}</li>
 6             <li>{{ ls[2] }}</li>
 7             <li>{{ ls[3] }}</li>
 8         </ul>
 9         <ul>
10             <li v-for="(ele, index) in ls">{{ ele }} {{ index }}</li>
11         </ul>
12         <ul>
13             <li v-for="(value, key, index) in dic">{{ key }} {{ value }} {{ index }}</li>
14         </ul>
15     </div>
16 </body>
17 <script src="js/vue.js"></script>
18 <script>
19     new Vue({
20         el: "#app",
21         data: {
22             ls: ['张三', '李四', '王五', '赵六', '钱七'],
23             dic: {
24                 name: 'Bob',
25                 age: 88,
26                 gender: ''
27             }
28         },
29 
30     })
31 </script>
  • 循环案例:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>条件案例</title>
 6     <style>
 7         li {
 8             cursor: pointer;
 9         }
10     </style>
11 </head>
12 <body>
13 <div id="app">
14     <form action="">
15         <input type="text" v-model="msg">
16         <button type="button" @click="fn">留言</button>
17     </form>
18     <ul>
19         <li v-for="(m, i) in msgs" @click="deleteAction(i)">{{ m }}</li>
20     </ul>
21 </div>
22 </body>
23 <script src="js/vue.js"></script>
24 <script>
25     new Vue({
26         el: "#app",
27         data: {
28             msg: "",
29             msgs: ["初始留言"]
30         },
31         methods: {
32             fn: function () {
33                 if (this.msg) {
34 //                    this.msgs.push(this.msg)  // 在后添加
35                     this.msgs.unshift(this.msg);  // 在前添加
36                     //将输入框内文本置空
37                     this.msg = "";
38                 }
39             },
40             deleteAction: function (index) {
41                 console.log(index);
42                 // 从什么索引开始 操作多少位 操作是什么,不写就替换为空
43                 this.msgs.splice(index, 1)
44             }
45         }
46     })
47 </script>
48 </html>
添加留言和删除留言

五.组件

  • 组件初识:

  •   每个组件均具有自身的模板template,根组件的模板就是挂载点
 1 <body>
 2     <div id="app">
 3         {{ msg }}
 4     </div>
 5 </body>
 6 <script src="js/vue.js"></script>
 7 <script>
 8     // 每个组件均具有自身的模板template,根组件的模板就是挂载点
 9     new Vue({
10         // 根组件一定需要挂载点(否则无法渲染到页面中), 一般情况下, 根组件的template就取挂载点,不需要自定义
11         el: "#app",
12         data: {
13             msg: "信息"
14         },
15         // template就是组件的html架构
16         // 每个组件模板只能拥有一个根标签
17         template: "<div><p>锻炼</p></div>"
18     })
19 </script>

1.根组件(new Vue)

 1 <div id="app">
 2     <h1>{{ msg }}</h1>
 3 </div>
 4 <script type="text/javascript">
 5     // 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件)
 6     // 每个组件组件均拥有模板,template
 7     var app = new Vue({
 8         // 根组件的模板就是挂载点
 9         el: "#app",
10         data : {
11             msg: "根组件"
12         },
13         // 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量
14         // 显式书写模块,就会替换挂载点,但根组件必须拥有挂载点
15         template: "<div>显式模板</div>"
16     })
17     // app.$template
18 </script>

2.局部组件(var localTag)

  • 点击次数案例

 1 <body>
 2     <div id="app">
 3         <abc></abc>
 4         <abc></abc>
 5         <abc></abc>
 6     </div>
 7     <hr>
 8     <div id="main">
 9         <local-tag></local-tag>
10         <local-tag></local-tag>
11     </div>
12 </body>
13 <script src="js/vue.js"></script>
14 <script>
15     // 局部组件
16     var localTag = {
17         // 子组件的数据具有作用域,以达到组件的复用, 每一个复用的组件具有自身独立的一套数据
18         data: function () {
19             return {  // 返回值是一个数据字典(一套数据)
20                 count: 0
21             }
22         },
23         template: "<div @click='fn'>点击{{ count }}次</div>",
24         methods: {
25             fn: function () {
26                 this.count += 1;
27             }
28         }
29     }
30 
31     // app根组件
32     new Vue({
33         el: "#app",
34         // 注册
35         components: {
36             'abc': localTag
37         }
38     })
39     // main根组件
40     new Vue({
41         el: "#main",
42         components: {
43             // localTag
44             'local-tag': localTag
45         }
46     })
47 </script>

3.全局组件(Vue.component)

 1 <body>
 2     <!-- 两个全局vue实例可以不用注册全局组件,就可以使用 -->
 3     <div id="app">
 4         <global-tag></global-tag>
 5     </div>
 6     <div id="main">
 7         <global-tag></global-tag>
 8     </div>
 9 </body>
10 <script src="js/vue.js"></script>
11 <script>
12     // 创建全局组件 组件名 {}
13     Vue.component('global-tag', {
14         template: "<div @click='fn'>全局组件点击了 {{ count }} 次</div>",
15         data: function () {
16             return {
17                 count: 0
18             }
19         },
20         methods: {
21             fn: function () {
22                 this.count++;
23             }
24         }
25     });
26     // 两个挂载点
27     new Vue({
28         el: "#app",
29     });
30     new Vue({
31         el: "#main",
32     });
33 </script>

六.信息传递

1.父组件传递信息给子组件

采用属性绑定的方式
  1.父级提供数据
  2.绑定给子组件的自定义属性
  3.子组件通过props的数组拿到自定义属性从而拿到数据
 1 <body>
 2     <div id="app">
 3         <input type="text" v-model="sup_data">
 4         <!-- 步骤2 -->子组件的自定义属性
 5         <global-tag :abcde="sup_msg" :sup_data="sup_data"></global-tag>
 6     </div>
 7 </body>
 8 <script src="js/vue.js"></script>
 9 <script>
10     // 创建全局组件,子组件
11     Vue.component('global-tag', {
12         // 步骤3
13         props: ['abcde', 'sup_data'],
14         template: "<div @click='fn'>{{ abcde }}</div>",
15            methods: {
16             fn: function () {
17                 alert(this.sup_data)
18             }
19         }
20     });
21     //父组件的信息传递给子组件
22     // 采用属性绑定的方式: 1,父级提供数据 2.绑定给子组件的自定义属性 3.子组件通过props的数组拿到自定义属性从而拿到数据
23     new Vue({
24         el: "#app",
25         data: {
26             // 步骤1
27             sup_msg: "父级的msg",
28             sup_data: ""
29         }
30     });
31 </script>

2.子组件传递信息给父组件

采用发生事件的方式:
  1.在子组件的内容系统事件中来定义一个自定义事件,采用$emit绑定到自定义组件名上(可以携带子组件内容数据)
  2.在父组件复用子组件时, 实现子组件自定义数据的功能, 在父组件中的methods中为功能绑定函数(函数的参数就是携带出来的数据)
  3.当子组件内部激活系统事件,就会激活自定义事件,$emit发生给父级,激活父级绑定的函数,该函数被执行,同时拿到数据
 1 <body>
 2     <div id="app">
 3         <!-- abc为子组件的自定义事件,该事件的含义要在子组件内容声明规定 -->
 4         <!-- 2 -->
 5         <global-tag @abc="action"></global-tag>
 6         <global-tag @abc="action"></global-tag>
 7         {{ sup_info }}
 8     </div>
 9 
10 </body>
11 <script src="js/vue.js"></script>
12 <script>
13     // 创建全局组件,子组件
14     Vue.component('global-tag', {
15         template: "<div><input v-model='info'><p @click='sendMsg'>子组件</p></div>",
16         data: function () {
17             return {
18                 info: "",
19                 msg: "子组件的信息"
20             }
21         },
22         methods: {
23             // 1
24             sendMsg: function () {
25 //                alert(123)
26                 // 激活自定义事件 abc
27                 this.$emit('abc', this.msg, this.info)
28             },
29 
30         }
31     });37     new Vue({
38         el: "#app",
39         data: {
40             sup_info: ""
41         },
42         methods: {
43             // 3
44             action: function (msg, info) {
45                 alert(msg)
46                 this.sup_info = info
47             }
48         }
49     });
50 </script>

-----组件完成留言板-----

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>留言板</title>
 6     <style>
 7         ul {
 8             margin: 0;
 9             padding: 0;
10         }
11         a {
12             color: black;
13             text-decoration: none;
14             display: block;
15             height: 21px;
16         }
17         p {
18             margin: 0;
19             color: orange;
20             float: left;
21         }
22         span {
23             color: red;
24             float: right;
25         }
26     </style>
27 </head>
28 <body>
29 <div id="app">
30     <input type="text" v-model="msg">
31     <button @click="btnClick">留言</button>
32     <hr>
33     <ul>
34         <!-- 如果每一个渲染的列表项是一个相对复杂的结构, 该复杂的结构可以封装成组件 -->
35         <li v-for="(v, i) in list">
36             <global-tag :value="v" :index="i" @delete="delAction"></global-tag>
37         </li>
38     </ul>
39 </div>
40 </body>
41 <script src="js/vue.js"></script>
42 <script>
43     new Vue({
44         el: "#app",
45         data: {
46             msg: "",
47             list: [],
48             list2: []
49         },
50         methods: {
51             btnClick: function () {
52                 if (this.msg) {
53                     this.list.push(this.msg);
54                     this.msg = "";
55                 }
56             },
57             delAction: function (index) {
58                 this.list.splice(index, 1)
59             }
60         }
61     });
62 
63     Vue.component('global-tag', {
64         props: ['value', 'index'],
65         template: "<a href='javascript:void(0)'><p>{{ value }}</p><span @click='sendDel'>x</span></a>",
66         methods: {
67             sendDel: function () {
68                 this.$emit('delete', this.index)
69             }
70         }
71     });
72 </script>
73 </html>
父子组件数据传递

原文地址:https://www.cnblogs.com/xuechengeng/p/10376513.html