zoukankan      html  css  js  c++  java
  • 关于Vue.js的认识(第一部分)[转载]

    一、关于v-bind

    1.初识v-bind

    (1).加冒号的是 vue 的 v-bind 语法糖(指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用),绑定vue的一个数据;不加冒号的就是HTML的属性,和 onclick="doSth()"是一个意思。它是一个 vue 指令,用于绑定 html 属性,如下:

    <div id="app">
      <p v-bind:title="title">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>
    </div>
    ......
    var vm = new Vue({
      el: '#app',
      data: {
        title: 'title content'
      }
    });

    这里的 html 最后会渲染成:

    <div id="app">
      <p title="title content">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>
    </div>

    2.指令预期值

    a.执行运算

    上面这种 v-bind 这也是我们对于 vue 指令最初的理解,但实际上,vue 指令的预期值(如 v-bind:class="classProperty" 中,v-bind 是指令,: 后面的 class 是参数,而 classProperty 则在官方文档中被称为“预期值”),除了像上面那样绑定一个字符串类型变量,其实它是支持一个单一 JavaScript 表达式 (v-for 除外)。
    所以在这里,我们就可以有更多的选择,例如:

    <div id="app">
      <p v-bind:title="t1 + ' ' + t2">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>
    </div>
    ......
    var vm = new Vue({
      el: '#app',
      data: {
        t1: 'title1',
        t2: 'title2'
      }
    });

    最后渲染的结果:

    <div id="app">
      <p title="title1 title2">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>
    </div>

    b.执行函数等

    <div id="app">
      <p v-bind:title="getTitle()">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>
    </div>
    ......
    var vm = new Vue({
      el: '#app',
      data: {
        getTitle: function () {
          return 'title content';
        }
      }
    });

    最后渲染的结果:

    <div id="app">
      <p title="title content">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>
    </div>

    3.支持的数据类型

    上面的内容,指令预期值得到的都是字符串类型的数据,但实际上,我们知道 js 有很多数据类型,它如果放入其中呢?

    a.对象类型

    <div id="app">
      <p v-bind:title="obj">content</p>
    </div>
    ......
    var obj = {};
    var vm = new Vue({
      el: '#app',
      data: {
        obj: obj
      }
    });

    渲染结果如下:

    <div id="app">
      <p title="[object Object]">content</p>
    </div>

    诶,这个怎么有点眼熟?有点像...没错!对象的 toString 方法的返回值!为了验证我们的猜想,我们进行进一步的测试:

    <div id="app">
      <p v-bind:title="obj">content</p>
    </div>
    ......
    var obj = {};
     
    obj.toString = function () {
      return 'edited in toString!';
    };
     
    var vm = new Vue({
      el: '#app',
      data: {
        obj: obj
      }
    });

    上面这里修改了 obj 的  toString 方法(但准确的说,这里不是修改,而是添加。一开始的 obj 对象上自身是没有 toString 方法的,它继承了 Object.prototype.toString,但这里我们执行 obj.toString  = function..... 实际上是为它添加了一个 toString 方法,使得它执行的时候,不用再去调用继承自 Object 的方法),渲染结果如下:

    <div id="app">
      <p title="edited in toString!">content</p>
    </div>

    b.数组类型

    数组类型的 toString 方法和对象类型的有所不同,它将返回和执行 arr.join(',') 相同的结果。如 [1, 2, 3].toString() 将返回 “1,2,3”。下面进行测试:

    <div id="app">
      <p v-bind:title="arr">content</p>
    </div>
    ......
    var vm = new Vue({
      el: '#app',
      data: {
        arr: [1, 2, 3]
      }
    });

    渲染结果如下:

    <div id="app">
      <p title="1,2,3">content</p>
    </div>

    c.其它类型

    1. number 类型,正常执行 toString,包括数字0,结果都正常渲染成对应的字符串;
    2. boolean 类型,true 正常渲染成字符串 "true",但 false 虽然执行 toString 方法将返回 "false" 字符串,但是却没有渲染出来
      <div id="app">
          <p v-bind:title="aaa">content</p>
      </div>
      </body>
      <script type="text/javascript">
          var obj={
                  a:null,//a:undefined,a:false
          };
      /*     obj.toString=function(){
              return false;
          }(); */
          var vm = new Vue({
              el:'#app',
              data:{
                  aaa:obj.a
              }
          });
      </script>

      渲染结果:

      <div id="app">
          <p >aaaaa</p>
      </div>

      结果确实没有渲染出来。

    3. null / undefined 类型,二者没有 toString 方法,也没有渲染出来。

    显然,在执行 toString 方法之前,vue 内部应该先做了类型校验,满足条件才输出。而且这里不是简单的真 / 假值校验,因为 、0 虽为假值,但最终却像真值一样渲染了出来。具体如何实现,可能需要参考 vue 的源码了,这里不再深究。

    4、多 html 属性值绑定

    一个的 html 属性值,可能包含许多内容,需要我们进行一些操作,将多个数据绑定到一个属性上,这里我们可以考虑像前面一样,通过如 “+” 等运算符号等实现字符串的连接操作。但是事实上,字符串连接麻烦又易错,不易于维护。于是我们可以考虑像前面一样向指令预期值中存入一个对象或数组,来实现多个数据绑定到一个属性上的作用。

    (1)对象类型

    <div id="app">
      <p v-bind:title="obj">content</p>
    </div>
    ......
    var obj = {
      name: 'Dale',
      age: 22
    };
     
    // 利用 for-in 循环遍历对象属性,拼接成字符串
    obj.toString = function () {
      var str = '';
      for(var i in this) {
        str += i + ': ' + this[i] + '; ';
      }
      return str;
    };
     
    // 防止 toString 方法自身被遍历出来
    Object.defineProperty(obj, 'toString', {'enumerable': false});
     
    var vm = new Vue({
      el: '#app',
      data: {
        obj: obj
      }
    });

    渲染结果:

    <div id="app">
      <p title="name: Dale; age: 22; ">content</p>
    </div>

    上面通过 for-in 循环在 toString 方法中得到所有可遍历的属性以及对应的属性值,然后将其拼接成字符串再进行输出,可以实现多属性值绑定,至于如何拼接,可以自己在 toString 方法中进行不同的实现 。

    2.数组类型

    <div id="app">
      <p v-bind:title="arr">content</p>
    </div>
    ......
    var arr = [1, 2, 3];
     
    arr.toString = function () {
      return this.join(' ');
    };
     
    var vm = new Vue({
      el: '#app',
      data: {
        arr: arr
      }
    });

    渲染结果:

    <div id="app">
      <p title="1 2 3">content</p>
    </div>

    相比于对象字符串拼接,数组的拼接操作则显得简单得多,可以直接在 toString 方法返回 join 方法的返回值,默认的 toString 方法的返回值其实就和 join(',') 的返回值相同。

    二、关于v-if

    1.v-if

    v-if,里面这个show是个变量,如果是true就是显示,如果是false就不显示,这里是移除了dom

    <div id='root'>
      <div v-if='show'>helle world</div>
      <button @click='handleClick'>toggle</button>
    </div>
    <script>
      new Vue({
        el:'#root',
        data:{
          show:true
        },
        methods:{
          handleClick:function(){
            this.show = !this.show;
          }
        }
      })
    </script>

    2.v-else

    这里v-if,v-else要紧贴着使用,不然会报错,v-if显示,v-else就会隐藏。v-if隐藏,v-else就会显示

    <div id='root'>
      <div v-if='show'>helle world</div>
      <div v-else>bye world</div>
    </div>
    
    <script>
      var vm = new Vue({
        el:'#root',
        data:{
          show:true
        }
      })
    </script>

    3.v-else-if

    这里可以根据show的值进行不同的处理,这三个也要紧贴着写,中间不能被其他所分隔

    <div id='root'>
      <div v-if='show==="a"'>this is a</div>
      <div v-else-if='show==="b"'>this is b</div>
      <div v-else>this is others</div>
    </div>
    
    
    <script>
      var vm = new Vue({
        el:'#root',
        data:{
          show:'b'
        }
      })
    </script>

    4.v-if使用的时候key值的用法

    <div id='root'>
      <div v-if='show'>
        用户名:<input type="text" />
      </div>
      <div v-else>
        邮箱名:<input type="text" />
      </div>
    </div>
    
    
    <script>
      var vm = new Vue({
        el:'#root',
        data:{
          show:false
        }
      })
    </script>

    这个例子,在我们使用的时候,show的值变为true,发现邮箱名已经变成了用户名,但是input框里面的值却没变空,这是因为vuejs有一种尝试复用dom的机制,如果已经在的dom,会复用之前的dom,但是这并不是我们想要的效果,这个时候就可以给他加一个key值,告诉vue.js,这是唯一的,是不能复用的input

    <div id='root'>
      <div v-if='show'>
        用户名:<input type="text" key='userName'/>
      </div>
      <div v-else>
        邮箱名:<input type="text" key='password' />
      </div>
    </div>
    
    
    <script>
      var vm = new Vue({
        el:'#root',
        data:{
          show:false
        }
      })
    </script>

     三、关于v-for

    1.在 v-for 指令的表达式中, news 是 data 内定义的数据, n 是当前数组元素的别名。

    <div id="app">
        <ul>
            <li v-for="n in news">{{n.title}}</li>
        </ul>
    </div>
    ...
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                news: [
                    {title: '跑步'},
                    {title: '绘画'},
                    {title: '读书'}
                ]
            }
        });
    </script>

    结果:

    2.列表渲染指令的表达式也支持使用 of 作为分隔符。(同时支持当前项索引参数,索引从 0 开始,它是可选的

    <div id="app">
        <ul>
           <li v-for="(n,index) of news">{{index}} - {{n.title}}</li>
        </ul>
    </div>
    ...
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                news: [
                    {title: '跑步'},
                    {title: '绘画'},
                    {title: '读书'}
                ]
            }
        });
    </script>

    结果:

    3.可以使用<template>标签,渲染多个元素

    <div id="app">
                <dl>
                    <template v-for="n in news">
                        <dt>{{n.title}}</dt>
                        <dd>{{n.content}}</dd>
                    </template>
                </dl>
    </div>
    ...
    <script>
            var app = new Vue({
                el: '#app',
                data: {
                    news: [
                        {title: '跑步',content:"runrunrunrn"},
                        {title: '绘画',content:"drawdrawdraw"},
                        {title: '读书',content:"readreadread"}
                    ]
                }
            });
    </script>

    结果:

    4.遍历对象属性

    <div id="app">
        <li v-for="val in account">{{val}}</li>
    </div>
    ...
    <script>
           var app = new Vue({
               el: '#app',
               data: {
                   account: {
                       name: 'xusp',
                       messageCount: 100
                   }
               }
           });
    </script>

    结果:

    4.1 遍历对象属性,可以带上两个可选参数,它们就是对象的属性名和索引:

    <div id="app">
        <li v-for="(val,name,index) in account">{{index}} - {{name}} : {{val}}</li>
    </div>
    ...
    <script>
           var app = new Vue({
               el: '#app',
               data: {
                   account: {
                       name: 'xusp',
                       messageCount: 100
                   }
               }
           });
    </script>

    结果:

    5.迭代函数

    <div id="app">
        <ul>
            <li v-for="i in 5">{{i}}</li>
        </ul>
    </div>
    ...
    <script>
          var app = new Vue({
              el: '#app'
          });
    </script>

    结果:

    6.更新数组

    Vue.js 的核心是数据与视图的双向绑定。因此当我们修改数组时, Vue.js 就会检测到数据了变化,所以用 v-for 渲染的视图也会更新 。使用以下方法修改数组时,就会触发视图更新:

    • push()
    • shift()
    • unshift()
    • splice()
    • sort()
    • reverse()

    这些方法会改变原数组,所以又称为变异方法。

    我们使用 push() 为 app 对象新增一个标题:

     app.news.push({
             title:'羽毛球'
    });

    结果:

    也有一些非变异方法,它们不会改变原数组,只会返回新数组:

    • filter()
    • concat()
    • slice()

    我们在使用这些方法时,可以通过设置新数组的方式来更新视图。

        //非变异方法更新数组
        app.news = app.news.filter(function (item) {
            return item.title.match(/读/);
        });

    结果:

    这个示例中,我们使用 filter 函数,把新闻标题中含有“读”字样的标题过滤出来。

    Vue.js 在检测数组变化时,会最大化地复用 DOM 元素。 替换的数组,如果含有相同元素的项并不会被重新渲染,所以不用担心性能问题。

    注意:通过以下方法来改变数组, Vue.js 是无法检测的,所以不会更新视图:

    1. 通过索引来设置项,比如 app.new[1]={...}
    2. 修改数组长度,比如 app.new.length=1

    我们可以使用 Vue.js 内置的 set 方法(可指定索引)来更新数组:

    <div id="app">
                <ul>
                    <li v-for="n in news">{{n.title}}</li>
                </ul>
    </div>
    ...
    <script>
         var app = new Vue({
             el:'#app',
             data:{
                news:[
                    {title:'跑步'},
                    {title:'绘画'},
                    {title:'读书'}
                ]
            }
         });
         //通过 set 的设置索引方式来更新数组
         Vue.set(app.news,1,{
             title: '游泳'
         });
    </script>

    结果:

    也可以使用 splice 指定索引来更新数组:

        //通过 splice 的设置索引方式来更新数组
        app.news.splice(1, 0, {
            title: '羽毛球'
        });

    结果:

    至于第二个问题,同样可以通过 splice 来实现:

    //通过 splice 来删除数组元素
    app.news.splice(1);

     以下三张结果图,分别是括号中的值为1,2,3的时候的结果:

     7.过滤或排序

    <div id="app">
                <h5>过滤出带“美元”的标题</h5>
                <ul>
                    <li v-for="(n,index) in filterNews">{{index}} - {{n.title}}</li>
                </ul>
                <h5>按照标题长度,由短到长排序</h5>
                <ul>
                    <li v-for="(n,index) in sortNews">{{index}} - {{n.title}}</li>
                </ul>
    </div>
    ...
    <script>
            var app = new Vue({
                el: '#app',
                data: {
                    news: [
                        {title: '被智能手机绑架的i世代 爱熬夜、拒绝恋爱、不考驾照'},
                        {title: '黑莓宣布14亿美元收购网络安全公司Cylance'},
                        {title: '如何看待XXX开酒店赚美元这件事?'}
                    ]
                },
                computed: {
                    //过滤出带“美元”的标题
                    filterNews: function () {
                        return this.news.filter(function (item) {
                            return item.title.match(/美元/);
                        })
                    },
                    //按照标题长度,由短到长排序
                    sortNews: function () {
                        return this.news.sort(function (val1, val2) {
                            if(val1.title.length < val2.title.length){
                                return -1;
                            }
                        })
                    }
                }
            });
    </script>

    结果:

    四、关于v-on

    1.基础语法

    v-on 指令绑定事件后,就会监听相应的事件。(注意: @click 是 v-on:click 的简写形式, @ 即表示 v-on:

    <div id="app">
        <h3>已点击 {{count}} 次</h3>
        <button @click="count++">点我</button>
    </div>
    ...
    <script>
            var app = new Vue({
                el: '#app',
                data: {
                    count:0
                }
            });
    </script>

    结果:

    1.1 :    @click 表达式即可以直接使用 js 语句,也可以是一个定义在 vue 实例中 methods 内的函数名。(注意: @click 调用的方法名如果不需要参数,那么可以不写括号。

    <div id="app">
                <h3>已点击 {{count}} 次</h3>
               <button @click="quickAdd(3)">快速增长</button>
    </div>
    ...
    <script>
            var app = new Vue({
                el: '#app',
                data: {
                    count:0
                },
                methods: {
                    quickAdd: function (i) {
                        i = i || 1;//为避免参数为 null 或 undefined 值,这里设定了默认值 1
                        this.count += i;
                    }
                }
            });
    </script>

    结果:

    2.调用DOM事件

    Vue.js 还提供了一个 $event 变量,使用它可以访问原生 DOM 事件。$event 变量可以通过方法传入。

    <div id="app2">
        <a href="www.baidu.com" @click="openUrl('被禁用咯',$event)">被禁用咯</a>
    </div>
    ...
    <script>
           var app2 = new Vue({
               el: '#app2',
               data: {
                   count: 0
               },
               methods: {
                   openUrl: function (param, event) {
                       event.preventDefault();
                       console.log("param:" + param);
                   }
               }
           });
    </script>

    结果:

    这个示例利用传入的 event 参数,禁用了原有的链接跳转逻辑。

    3.事件修饰符

    Vue.js 支持以下事件修饰符:

    事件修饰符示例示例说明
    .stop @click.stop 阻止单击事件冒泡。
    .prevent @submit.prevent 提交页面不再重载页面。
    .capture @click.capture 添加事件监听器时使用事件捕获模式。
    .self @click.self 只有当单击事件是元素的自身事件时,才会触发。
    .once @click.once 只触发一次。

    4.按键修饰符

    可以使用按键修饰符,来监听表单元素上的键盘事件。

    <div id="app3">
                <input @keyup.13="enterClick">
    </div>
    ...
    <script>
          var app3 = new Vue({
              el: '#app3',
              data: {},
              methods: {
                  enterClick: function () {
                      console.log("enterClick");
                  }
              }
          });
    </script>

    console控制台输出结果:

    enterClick

    这个示例演示了如何通过回车按键修饰符来绑定事件函数的过程。

    除了使用 keycode 来指定按键之外,我们还可以使用以下这些按键别名:

    • .enter
    • .tab
    • .delete
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right

    用法示例:

    <input @keyup.enter="enterClick">

    还有一些按键修饰符可以组合使用,或者和鼠标一起使用:

    • .ctrl
    • .alt
    • .shift
    • .metaMac 下为 Command 键,Windows 下为窗口键。

    用法示例:

    <input @keyup.alt.83="enterClick">

     五、关于v-model(双向绑定)

    1.lazy

    v-model 指令默认会在 input 事件中加载输入框中的数据(中文输入法中输入拼音的过程除外)。我们可以使用 .lazy 懒加载修饰符,让其只在 change 事件中再加载输入框中的数据。

    使用 .lazy 懒加载修饰符之后,只有在输入框失去焦点或者按回车键时才会更新 content 值。

    <div id="app">
                <input type="text" v-model.lazy="content" placeholder="请输入" value="初始值">
                <p>输入框:{{content}}</p>
    </div>
    ...
    <script>
         var app = new Vue({
             el: '#app',
             data: {
                 content: ''
             }
         });
    </script>

    结果:

    2.number

    输入框输入的内容,即使是数字,默认也是 string 类型

    在此,我们可以使用 .number 修饰符让其转换为 number 类型

    <div id="app2">
        <input type="number" v-model.number="content" placeholder="请输入" >
        <p>输入值:{{content}},输入类型:{{typeof content}}</p>
    </div>
    ...
    <script>
        var app2 = new Vue({
            el: '#app2',
            data: {
                content: 1
            }
        });
    </script>

    结果:

    3.trim

    使用 .trim 修饰符可以自动过滤掉输入框的首尾空格。

    <div id="app3">
                <input type="text" v-model.trim="content" placeholder="请输入" value="初始值">
                <p>输入框:{{content}}</p>
    </div>
    ...
    <script>
        var app3 = new Vue({
            el: '#app3',
            data: {
                content: ''
            }
        });
    </script>

    结果:

  • 相关阅读:
    【字符串题目】poj 3096 Surprising Strings
    【转载】:【博弈论】博弈的学习和总结
    【博弈论】hihocoder
    转载:SPFA算法学习
    马克思所言:
    【NOIP2013】火柴排队
    【NOIP2013】【P1441】花匠
    【JZOI2002】【BZOJ1477】【P1371】青蛙的约会
    【P1373】奶牛的卧室
    2016.9.16 の 測試
  • 原文地址:https://www.cnblogs.com/xusp/p/11608888.html
Copyright © 2011-2022 走看看