zoukankan      html  css  js  c++  java
  • 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>
    父子组件数据传递
    
    
  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/xuechengeng/p/10376513.html
Copyright © 2011-2022 走看看