资讯专栏INFORMATION COLUMN

从零开始学习vue

flyer_dev / 2276人阅读

摘要:二起步在学习之前,需要有扎实的基础。三核心实例每个应用都是通过构造函数创建的一个新的实例开始的选项对象在这其中的简称通常都表示实例的变量名。

重要说明:本文会在我有空闲时间时持续更新,相当于是将官网的示例给完全呈现,是为了帮助初学者,也是为了巩固我自己的技术,我决定将官网给过滤一道消化,敬请期待。

一.介绍

vue是一种渐进式框架,被设计为自底向上逐层应用。所谓渐进式框架,我的理解就是vue是循序渐进的,一步一步的用。
举个简单的例子,就算我们不会webpack,不会node,但也能很快的入门。更多详情参阅渐进式。

二.起步 1.hello,world

在学习vue之前,需要有扎实的HTML,CSS,JavaScript基础。任何一个入门语言都离不开hello,world!例子,我们来写这样一个例子:
新建一个html文件,helloworld.html,如下:



  
    
    
    
    hello,world
  
  
    
{{ message }}

js代码如下:

var app = new Vue({
  el:"#app",
  data:{
    message:"hello,world!"
  }
})

现在我们已经成功创建了第一个vue应用,数据和DOM已经被关联,所有的东西都是响应式的,我们要如何确定呢,打开浏览器控制台,修改app.message的值。

在这其中data对象的写法,我们还可以写成函数形式,如下:

var app = new Vue({
  el:"#app",
  //这里是重点
  data(){
     return{
        message:"hello,world!"
     }
  }
})
2.文本插值

当然除了文本插值,我们还可以绑定元素属性,如下:

   
    
      
        
        
        
        v-bind
      
      
        
鼠标悬浮上去可以看到

js代码如下:

 var app = new Vue({
  el:"#app",
  data:{
    message:"页面加载于:" + new Date().toLocaleString()
  }
})
   

查看效果,前往此处查看效果:
同样的我们也可以修改message的值,这样的话,鼠标悬浮上去,悬浮的内容就会改变了。在这个例子中v-bind(或者也可以写成":")其实就是一个指令,指令通常前缀都带有v-,用于表示vue指定的特殊特性,在渲染DOM的时候,它会应用特殊的响应式行为。这个指令所表达的意思就是:将这个title属性的值与vue实例的message值保持一致。

3.元素的显隐

当然,我们也可以控制一个元素的显隐,那也是非常的简单,只需要使用v-show指令即可:

     
        
          
            
            
            
            v-if
          
          
            
默认你是看不到我的哦

js代码如下:

  var app = new Vue({
       el:"#app",
       data:{
          seen:false
       }
   })   

尝试在控制台中修改seen的值,也就是app.seen = true,然后你就可以看到页面中的span元素了,具体示例

4.列表渲染

还有v-for指令,用于渲染一个列表,如下:

     
        
          
            
            
            
            v-for
          
          
            
{{ item.name }}

{{ item.content }}

js代码如下:

   var app = new Vue({
       el:"#app",
       data:{
          list:[
            { name:"项目一",content:"HTML项目"},
            { name:"项目二",content:"CSS项目"},
            { name:"项目三",content:"JavaScript项目"},
          ]
       }
   })             
        
        

当然你也可以自己在控制台改变list的值,具体示例

5.事件

vue通过v-on + 事件属性名(也可以写成"@" + 事件属性名)指令添加事件,例如v-on:click@click如下一个示例:

       
        
          
            
            
            
            v-on
          
          
            
{{ message }}

js代码如下:

    var app = new Vue({
       el:"#app",
       data:{
          message:"hello,vue.js!"
       },
       methods:{
         reverseMessage:function(){
             //在这里this指向构造函数构造的vue实例
            this.message = this.message.split("").reverse().join("");
         }
       }
   }) 

反转信息的思路就是使用split()方法将字符串转成数组,,然后使用数组的reverse()方法将数组倒序,然后再使用join()方法将倒序后的数组转成字符串。

你也可以尝试在这里查看示例

6.组件

组件是vue中的一个核心功能,它是一个抽象的概念,它把所有应用抽象成一个组件树,一个组件树就是一个预定义的vue实例,在vue中使用Vue.component()注册一个组件,它有两个参数,第一个参数为组件名(尤其要注意组件名的命名),第二个参数为组件属性配置对象,如:

//定义一个简单的组件
Vue.component("todo-item",{
   template:`
  • 待办事项一
  • ` })

    现在我们来看一个完整的例子:

           
            
              
                
                
                
                component
              
              
                

    js代码如下:

     Vue.component("todo-item",{
        props:["todo"],
        template:`
  • {{ todo.number }}.{{ todo.text }}
  • ` }) var app = new Vue({ el:"#app", data:{ todoList:[ { number:1,text:"html"}, { number:2,text:"css"}, { number:3,text:"javascript"} ] }, methods:{ } })

    这样,一个简单的组件就完成了,在这里,我们知道了,父组件app可以通过props属性将数据传递给子组件todo-item,这是vue父子组件之间的一种通信方式。
    你可以尝试在此处具体示例。

    三.核心 1.vue实例

    每个vue应用都是通过Vue构造函数创建的一个新的实例开始的:

    var vm = new Vue({
       //选项对象
    })
    

    在这其中vm(viewModel的简称)通常都表示vue实例的变量名。当创建一个vue实例,你都可以传入一个选项对象作为参数,完整的选项对象,你可能需要查看API文档。

    一个vue应用应该由一个通过new Vue构造的根实例和许多可嵌套可复用的组件构成,这也就是说所有的组件都是vue实例。

    2.数据与方法

    当一个vue实例被创建完成之后,就会向它的vue响应系统中加入了data对象中能找到的所有属性,当这些属性的值发生改变之后,视图就会发生响应,也就是更新相应的值。我们来看一个例子:

    //源数据对象
    var obj = { name:"eveningwater" };
    //构建实例
    var vm = new Vue({
       data:obj
    })
    
    //这两者是等价的
    vm.name === obj.name;
    //这也就意味着
    //修改data对象里的属性也会影响到源数据对象的属性
    vm.name = "waterXi";
    obj.name;//"waterXi"
    //同样的,修改源数据对象的属性也会影响到data对象里的属性
    obj.name = "stranger";
    vm.name;//"stranger"
    

    可能需要注意的就是,只有data对象中存在的属性才是响应式的,换句话说,你为源数据对象添加一个属性,根本不会影响到data对象。如:

    obj.sex = "男";
    vm.sex;//undefined
    obj.sex;//"男"
    obj.sex = "哈哈哈";
    vm.sex;//undefined
    

    这也就意味着你对sex的修改并不会让视图更新,如此一来,你可能需要在data对象中初始化一些值,如下:

    data:{
       str:"",
       bool:false,
       arr:[],
       obj:{},
       err:null,
       num:0
    }
    

    查看此处具体示例。

    只是还有一个例外Object.freeze(),这个方法就相当于锁定(冻结)一个对象,使得我们无法修改现有属性的特性和值,并且也无法添加新属性。因此这会让vue响应系统无法追踪变化:

    
    
      
        
        
        
        freeze
      
      
        
    {{ message }}

    js代码如下:

          var obj = {
              message: "hello,vue.js!"
          }
          //阻止对象
          Object.freeze(obj);
          var app = new Vue({
            el: "#app",
            data:obj,
            methods: {
              reverseMessage: function() {
                this.message = this.message.split("").reverse().join("");
              }
            }
          });  
    

    如此一来,无论我们怎么点击按钮,都不会将信息反转,甚至页面还会报错。
    可前往此处具体示例自行查看效果。

    当然除了数据属性以外,vue还暴露了一些有用的实例属性和方法,它们通常都带有$前缀,这样做的方式是以便与用户区分开来。来看一个示例:

    
    
      
        
        
        
        property
      
      
        

    js代码:

      var obj = {
         name:"eveningwater"
      }
      var vm = new Vue({
        data:obj,
      });
      //这行代码表示将vue实例挂载到id为app的DOM根节点上,相当于在实例的选项对象中的el选项,即
      //el:"#app"
     vm.$mount(document.querySelector("#app")) 
     //数据是相等的
     vm.$data === obj;//true
     //挂载的根节点
     vm.$el === document.querySelector("#app");//true
     //以上两个属性都是实例上的属性,接下来还有一个watch即监听方法是实例上的方法
     vm.$watch("name",function(oldValue,newValue){
       //数据原来的值
       console.log(oldValue);
       //数据最新的值
        console.log(newValue);
     })
    
    

    接下来,可以尝试在浏览器控制台修改name的值,你就会发现watch()方法的作用了。
    这个示例可前往具体示例。

    3.实例生命周期

    每个vue实例在被创建的时候都会经历一些初始化的过程,这其中提供了一些生命周期钩子函数,这些钩子函数代表不同的生命周期阶段,这些钩子函数的this就代表调用它的那个实例。对于生命周期,有一张图:

    你不需要立即这张图所代表的含义,我们来看一个示例:

    
    
      
        
        
        
        vue life cycle
      
      
        
    vue生命周期

    js代码:

      var obj = {
         name:"eveningwater"
      }
      var app = new Vue({
        data:obj,
        beforeCreate:function(){
            //此时this指向app这个vue实例,但并不能得到data属性,因此this.name的值是undefined
            console.log("实例被创建之前,此时并不能访问实例内的任何属性" + this.name)
        }
      });
      

    关于生命周期的全部理解,我们需要理解后续的组件知识,再来补充,此处跳过。这个示例可前往具体示例

    4.模板语法

    vue使用基于HTML的模板语法,在vue的底层是将绑定数据的模板渲染成虚拟DOM,并结合vue的响应式系统,从而减少操作DOM的次数,vue会计算出至少需要渲染多少个组件。

    最简单的模板语法莫过于插值了,vue使用的是Mustache语法(也就是双大括号"{{}}")。这个只能对文本进行插值,也就是说无论是字符串还是标签都会被当作字符串渲染。如:

    
    
      
        
        
        
        Mustache
      
      
        
    {{ greeting }}World!

    js代码:

     var obj = { greeting:"Hello,"};
     var vm = new Vue({
        data:obj
     });
     vm.$mount(document.getElementById("app"));
     

    如此以来Mustache标签就会被data对象上的数据greeting给替代,而且我们无论怎么修改greeting的值,视图都会响应,具体示例。

    我们还可以使用v-once指令对文本进行一次性插值,换句话说,就是这个指令让插值无法被更新:

    
    
      
        
        
        
        Mustache
      
      
        
    {{ greeting }}World!

    js代码:

     var obj = { greeting:"Hello,"};
     var vm = new Vue({
        data:obj
     });
     vm.$mount(document.getElementById("app"));
    

    在浏览器控制台中我们输入vm.greeting="stranger!"可以看到视图并没有被更新,这就是这个指令的作用,我们需要注意这个指令对数据造成的影响。具体实例

    既然双大括号只能让我插入文本,那要是我们要插入HTML代码,我们应该怎么办呢?v-html这个指令就可以让我们插入真正的HTML代码。

    
    
      
        
        
        
        v-html
      
      
        

    {{ message }}

    js代码:

     var obj = { message:"hello,world!"};
     var vm = new Vue({
        data:obj
     });
     vm.$mount(document.getElementById("app"));
     

    页面效果如图所示;

    可前往具体示例。

    关于HTML特性,也就是属性,我们需要用到v-bind指令,例如:

    
    
      
        
        
        
        v-bind
      
      
        
    使用v-bind指令给该元素添加id属性

    js代码:

     var obj = { propId:"myDiv"};
     var vm = new Vue({
        data:obj
     });
     vm.$mount(document.getElementById("app"));
     

    打开浏览器控制台,定位到该元素,我们就能看到div元素的id属性为"myDiv",如下图所示:

    具体示例。

    在绑定与元素实际作用相关的属性,比如disabled,这个指令就被暗示为true,在默认值是false,null,undefined,""等转换成false的数据类型时,这个指令甚至不会表现出来。如下例:

    
    
      
        
        
        
        v-bind
      
      
        

    js代码:

     var obj = { isDisabled:123};
     var vm = new Vue({
        data:obj
     });
     vm.$mount(document.getElementById("app"));
     

    这样一来,无论我们怎么点击按钮都没用,因为123被转换成了布尔值true,也就表示按钮已经被禁用了,我们可以打开控制台看到:

    你可以尝试这个示例具体示例。

    在使用模板插值的时候,我们可以使用一些JavaScript表达式。如下例:

    
    
      
        
        
        
        expression
      
      
        

    {{ number + 1 }}

    {{ ok ? "确认" : "取消" }}

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

    元素的id为myDiv

    js代码:

     var obj = {
        number: 123,
        ok: true,
        message: "hello,vue.js!",
        elementId: "Div",
        color: "red"
      };
      var vm = new Vue({
        data: obj
      });
      vm.$mount(document.getElementById("app"));
      

    这些JavaScript表达式都会被vue实例作为JavaScript代码解析,具体示例。

    值得注意的就是有个限制,只能绑定单个表达式,像语句是无法生效的。如下例:

    
    
      
        
        
        
        sentence
      
      
        

    {{ var number = 1 }}

    {{ if(ok){ return "确认"} }}

    js代码:

      var obj = {
        number: 123,
        ok: true
      };
      var vm = new Vue({
        data: obj
      });
      vm.$mount(document.getElementById("app")); 
      

    像这样直接使用语句是不行的,浏览器控制台报错,如下图:

    不信可以自己试试具体示例。

    指令(Directives)是带有v-前缀的特殊特性,通常指令的预期值就是单个JavaScript表达式(v-for除外),例如v-ifv-show指令,前者表示DOM节点的插入和删除,后者则是元素的显隐。所以,指令的职责就是根据表达式值的改变,响应式的作用于DOM。现在我们来看两个示例:

    
    
      
        
        
        
        v-if
      
      
        

    {{ value }}

    {{ value }}

    {{ value }}

    js代码:

      var obj = {
        value: 1
      };
      var vm = new Vue({
        el: "#app",
        data() {
          return obj;
        }
      });
      

    运行在浏览器效果如图:

    现在你可以尝试在浏览器控制台更改vm.value = 2vm.value = 3我们就可以看到页面的变化。你也可以狠狠点击此处具体示例查看和编辑。

    我们再看v-show的示例:

    
    
      
        
        
        
        v-show
      
      
        

    {{ value }}

    {{ value }}

    {{ value }}

    js代码:

    var obj = {
       value:1
    } 
    var vm = new Vue({
        data:obj
    });
    vm.$mount(document.querySelector("#app"))
    

    然后查看效果如图:


    尝试在控制台修改vm.value = 2vm.value = 3我们就可以看到页面的变化。你也可以狠狠点击具体示例查看。

    从上面两个示例的对比,我们就可以看出来v-showv-if指令的区别了,从切换效果来看v-if显然不如v-show,这说明v-if有很大的切换开销,因为每一次切换都要不停的执行删除和插入DOM元素操作,而从渲染效果来看v-if又比v-show要好,v-show只是单纯的改变元素的display属性,而如果我们只想页面存在一个元素之间的切换,那么v-if就比v-show要好,这也说明v-show有很大的渲染开销。

    而且v-if还可以结合v-else-ifv-else指令使用,而v-show不能,需要注意的就是v-else必须紧跟v-if或者v-else-if之后。当需要切换多个元素时,我们还可以使用template元素来包含,比如:

    
    
      
        
        
        
        template
      
      
        

    js代码:

      var obj = {
        value: 1
      };
      var vm = new Vue({
        el: "#app",
        data() {
          return obj;
        }
      });
      

    此时template相当于一个不可见元素,如下图所示:


    尝试在控制台修改vm.value = 2就可以看到效果了,你也可以狠狠的点击此处具体示例。

    对于可复用的元素,我们还可以添加一个key属性,比如:

    
    
      
        
        
        
        key
      
      
        

    js代码:

          var obj = {
            loginType: "username",
            count:1
          };
          var vm = new Vue({
            el: "#app",
            data() {
              return obj;
            },
            methods: {
              changeType() {
                this.count++;
                if (this.count % 3 === 0) {
                  this.loginType = "username";
                } else if (this.count % 3 === 1) {
                  this.loginType = "email";
                } else {
                  this.loginType = "mobile";
                }
              }
            }
          });
    

    效果如图:


    你可以狠狠的点击具体示例查看。

    从这几个示例我们也可以看出v-if就是惰性,只有当条件为真时,v-if才会开始渲染。值得注意的就是v-ifv-for不建议合在一起使用。来看一个示例:

    
    
      
        
        
        
        v-if与v-for
      
      
        
    • {{ item.value }}

    js代码:

      var obj = {
        list:[
            {
                value:"html",
                active:false
            },
            {
                value:"css",
                active:false
            },
            {
                value:"javascript",
                active:true
            }
        ]
      };
      var vm = new Vue({
        el: "#app",
        data() {
          return obj;
        }
      });
      

    虽然以上代码不会报错,但这会造成很大的渲染开销,因为v-for优先级高于v-if,这就造成每次执行v-if指令时总要先执行v-for遍历一遍数据。你可以点击此处具体示例查看。

    遇到这种情况,我们可以使用计算属性。如:

    
    
      
        
        
        
        v-if和v-for
      
      
        
    • {{ item.value }}

    js代码:

    var obj = {
        list: [
          {
            value: "html",
            active: false
          },
          {
            value: "css",
            active: false
          },
          {
            value: "javascript",
            active: true
          }
        ]
      };
      var vm = new Vue({
        el: "#app",
        //先过滤一次数组
        computed: {
          newList: function() {
           return this.list.filter(function(item) {
              return item.active;
            });
          }
        },
        data() {
          return obj;
        }
      });      
    

    如此一来,就减少了渲染开销,你可以狠狠点击这里具体示例查看。

    指令的用法还远不止如此,一些指令是可以带参数的,比如v-bind:title,在这里title其实就是被作为参数。基本上HTML5属性都可以被用作参数。比如图片路径的src属性,再比如超链接的href属性,甚至事件的添加也属于参数,如v-on:click中的click其实就是参数。来看一个示例:

    
    
      
        
        
        
        param
      
      
        
        
      
    
    
    

    js代码:

      var obj = {
        url: "https://segmentfault.com/",
        src:"http://eveningwater.com/project/imggallary/img/15.jpg"
      };
      var vm = new Vue({
        el: "#app",
        data() {
          return obj;
        }
      }); 
      

    效果如图所示:


    你可以点击此处具体示例查看。

    v-on指令还可以添加修饰符,v-bindv-on指令还可以缩写成:@。缩写对于我们在繁琐的使用指令的项目当中是一个很不错的帮助。

    5.计算属性

    模板表达式提供给我们处理简单的逻辑,对于更复杂的逻辑,我们应该使用计算属性。来看两个示例的对比:

    
    
      
        
        
        
        mustache
      
      
        
    {{ message.split("").reverse().join("") }}

    js代码:

     var obj = {
       message:"hello,vue.js!"
     }
     var vm = new Vue({
         data:obj
     })
     vm.$mount(document.querySelector("#app"))
    

    第二个示例:

    
    
      
        
        
        
        mustache
      
      
        
    {{ reverseMessage }}

    js代码:

    var obj = {
       message:"hello,vue.js!"
     }
     var vm = new Vue({
         data:obj,
         computed:{
             reverseMessage:function(){
                return this.message.split("").reverse().join("");
             }
         }
     })
     vm.$mount(document.querySelector("#app")) 
     
     

    与第一个示例有所不同的就是在这个示例当中,我们申明了一个计算属性reverseMessage,并且提供了一个getter函数将这个计算属性同数据属性message绑定在一起,也许有人会有疑问getter函数到底在哪里呢?
    如果我们将以上示例修改一下:

    var obj = {
       message:"hello,vue.js!"
     }
     var vm = new Vue({
         data:obj,
         computed:{
             reverseMessage:{
                get:function(){
                   return this.message.split("").reverse().join("");
                }
             }
         }
     })
     vm.$mount(document.querySelector("#app"))
     

    相信如此一来,就能明白了。你可以狠狠点击此处具体示例。你可以通过控制台修改message的值,只要message的值发生改变,那么绑定的计算属性就会发生改变。事实上,在使用reverseMessage绑定的时候,我们还可以写成调用方法一样的方式,如:

    
    
      
        
        
        
        mustache
      
      
        
    {{ reverseMessage() }}

    js代码:

     var obj = {
       message:"hello,vue.js!"
     }
     var vm = new Vue({
         data:obj,
         computed:{
             reverseMessage:function(){
                return this.message.split("").reverse().join("");
             }
         }
     })
     vm.$mount(document.querySelector("#app"))
     

    那么这两者有何区别呢?虽然两者的结果都一样,但计算属性是根据依赖进行缓存的,只有相关依赖发生改变时它们才会重新求值。比如这里计算属性绑定的依赖就是message属性,一旦message属性发生改变时,那么计算属性就会重新求值,如果没有改变,那么计算属性将会缓存上一次的求值。这也意味着,如果计算属性绑定的是方法,那么计算属性不是响应式的。如下:

    
    
      
        
        
        
        mustache
      
      
        
    {{ date }}

    js代码:

     var vm = new Vue({
         data:obj,
         computed:{
             reverseMessage:function(){
                return Date.now();
             }
         }
     })
     vm.$mount(document.querySelector("#app"))
    

    与调用方法相比,调用方法总会在页面重新渲染之后再次调用方法。我们为什么需要缓存,假设你要计算一个性能开销比较大的数组,而且如果其它页面也会依赖于这个计算属性,如果没有缓存,那么无论是读取还是修改都会去多次修改它的getter函数,这并不是我们想要的。

    计算属性默认只有getter函数,让我们来尝试使用一下setter函数,如下:

    
    
      
        
        
        
        computed
      
      
        

    js代码:

       var vm = new Vue({
        el: "#app",
        data: {
          first_name: "li",
          last_name: "qiang"
        },
        computed: {
          name: {
            get: function() {
              return this.first_name + " " + this.last_name;
            },
            set: function(newValue) {
              var names = newValue.split(" ");
              this.first_name = names[0];
              this.last_name = names[names.length - 1];
            }
          }
        }
      }); 
      

    现在,我们只需要修改vm.name的值就可以看到first_namelast_name的值相应的也改变了。你可以狠狠点击此处具体示例。

    6.侦听器

    虽然计算属性在大多数情况下更合适,但有时候也可以使用侦听器。vue通过watch选项提供一个方法来响应数据的变化。如:

    
    
      
        
        
        
        
        watch
        
      
      
        

    可以给我提出一个问题,然后我来回答?

    {{ answer }}

    js代码:

        var vm = new Vue({
            el:"#app",
            data(){
                return{
                    answer:"我不能回答你除非你提出一个问题!",
                    question:"",
                    answerImg:""
                }
            },
            created:function(){
               // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
               // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
               // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
               // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
               // 请参考:https://lodash.com/docs#debounce
               this.debounceGetAnswer = _.debounce(this.getAnswer,500);
            },
            //如果question值发生改变
            watch:{
               question:function(oldValue,newValue){
                  this.answer="正在等待你停止输入!";
                  this.debounceGetAnswer();
               }
            },
            methods:{
                getAnswer:function(){
                   //如果问题没有以问号结束,则返回
                   if(this.question.indexOf("?") === -1){
                     this.answer = "提出的问题需要用问号结束!";
                     return;
                   }
                   this.answer = "请稍等";
                   var self = this;
                   fetch("https://yesno.wtf/api").then(function(response){
                       //fetch发送请求,json()就是返回数据
                       response.json().then(function(data) {
                          self.answer = _.capitalize(data.answer);
                          self.answerImg = _.capitalize(data.image);
                       });
                   }).catch(function(error){
                      self.answer = "回答失败,请重新提问!";
                      console.log(error);
                   })
                }
            }
        })
        

    现在咱们来看一下效果:


    你可以狠狠点击此处具体示例查看。

    7.计算属性vs侦听器

    当在页面中有一些数据需要根据其它数据的变动而改变时,就很容易滥用侦听器watch。这时候命令式的侦听还不如计算属性,请看:

    
    
      
        
        
        
        watch
      
      
        

    {{ fullName }}

    js代码:

     var vm = new Vue({
          el:"#app",
          data:{
             firstName:"li",
             lastName:"qiang",
             fullName:"li qiang"
          },
          watch:{
             firstName:function(val){
                this.fullName = val + " " + this.lastName;
             },
             lastName:function(val){
                this.fullName = this.firstName + " " + val;
             }
          }
     })
     

    再看通过计算属性实现的:

     
    
    
      
        
        
        
        computed
      
      
        

    {{ fullName }}

    js代码:

     var vm = new Vue({
          el:"#app",
          data:{
             firstName:"li",
             lastName:"qiang"
          },
          computed:{
             fullName:function(){
               return this.firstNmae + " " + this.lastName;
             }
          }
     })
    

    通过计算属性实现的功能看起来更好,不是吗?你可以自行尝试具体示例(watch)与具体示例(computed)进行对比。

    8.class与style绑定

    操作元素的classstyle是构建一个页面所常见的需求,因为它们都是属性,所以利用v-bind指令就可以操作元素的classstyle样式。如;

    
    
    
        
        
        
         
         
        class
        
    
    
        
    添加一个class类,改变字体颜色为红色。

    js代码如下;

    var vm = new Vue({
        el:"#app",
        data:{
            className:"font-red"
        }
    })
    

    你可以狠狠点击此处具体示例 查看。

    再来看一个简单绑定style的示例。

    
    
    
        
        
        
         
         
        style
    
    
        
    改变元素的字体颜色为红色。

    js代码:

    var vm = new Vue({
        el:"#app",
        data:{
            styleProp:"color:#f00;"
        }
    })
    

    你可以狠狠点击此处具体示例查看。

    这只是classstyle的简单用法,vue.js专门在这方面做了增强,使得绑定classstyle 的值可以是对象,也可以是数组,如:

    
    
    
        
        
        
        
        class
        
    
    
        
    改变字体的颜色

    js代码:

      var vm = new Vue({
          el:"#app",
          data:{
              isRed:true,
              isBlue:false
          }
      })
      

    我们可以看到页面效果如图:

    你还可以通过控制台修改vm.isBluevm.isRed的值,这充分说明这两个值是响应式的。如:


    你可以狠狠的点击此处具体示例查看。

    同样的,style一样也可以使用对象语法,如:

    
    
      
        
        
        
        
        style
      
      
        
    字体大小为18px,字体颜色为红色,并且加粗的字体。

    js代码:

      var vm = new Vue({
        el: "#app",
        data: {
          fontColor: "#f00",
          font18: "18px",
          fontBold:"bold"
        }
      });
      

    效果如图:


    我们一样可以修改其中的值,这些值也是响应式的,比如修改vm.fontColor="#0f0"就表示将字体颜色改变为蓝色。从上例我们也可以看出,我们可以使用驼峰式 (camelCase) 短横线分隔 (kebab-case,需要用单引号括起来)来定义css属性名。
    你可以狠狠点击此处具体示例查看。

    当然在更多时候,我们直接绑定一个对象更有利于让模板变得清晰,也方便我们理解。

    
    
      
        
        
        
        
        style
      
      
        
    字体大小为18px,字体颜色为红色,并且加粗的字体。

    js代码:

      var vm = new Vue({
        el: "#app",
        data: {
            styleObject:{
               fontSize:"18px",
               color:"#f00",
               "font-weight":"bold"
            }
        }
      });  
      

    这也是一样的效果,你可以点击此处具体示例查看。

    除了对象语法,数组语法也同样适用于classstyle,如:

    
    
      
        
        
        
        
        class
        
      
      
        
    颜色为红色大小为18px的字体

    js代码:

      var vm = new Vue({
        el: "#app",
        data: {
          fontColor: "font-red",
          fontSize: "font-18"
        }
      });
      

    运行效果如图:

    你同样可以修改class的名字,诸如vm.fontColor="font-blue",这样页面就会将font-red更改为font-blue,这毕竟是响应式的。你可以狠狠点击此处具体示例查看。

    同样的,style也能如此做,如:

    
    
      
        
        
        
        
        style
      
      
        
    颜色为红色大小为18px的字体

    js代码:

     var vm = new Vue({
        el: "#app",
        data: {
            colorF: {
                color:"#f00"
            },
            sizeF: {
                fontSize:"18px"
            }
        }
      });
    

    这里尤其注意如下的写法是错误的,vue.js并不能渲染出样式:

      //这说明style绑定的数组项只能是一个对象,而不能是字符串
     var vm = new Vue({
        el: "#app",
        data: {
            colorF: "color:#f00;",
            sizeF: "font-size:18px;"
        }
      });
    

    同样,我们注意修改值的时候也应该修改成一个对象,如:

    vm.sizeF = {
       "font-size":"20px"
    }
    

    这点是需要注意的,另外在遇到带有前缀的css属性,如transition时,我们不必写前缀,因为vue会自动帮我们添加前缀。你可以狠狠点击此处具体示例查看。

    style的用法还不止如此,我们还可以绑定多重值。如下:

    
    
      
        
        
        
        
        style
      
      
        
    颜色为红色大小为18px的字体

    js代码:

     var vm = new Vue({
        el: "#app",
        data: {
            webkitD:"-webkit-flex",
            nomarD:"flex"
        }
      });
      

    这样一来,浏览器会根据支持-webkit-flexflex而采用支持的写法,这个是在vue2.3.0+版本中增加的功能。你可以点击此处具体示例查看。

    9.条件渲染

    v-if指令用于条件性的渲染一块内容,这个指令只在它绑定的值为truthy的时候才会渲染内容。例如:

    
    
      
        
        
        
        v-if
      
      
        

    正常显示

    不显示
    也是正常显示
    也是不显示

    你可以狠狠点击此处具体示例查看效果。

    v-if指令也可以与v-else指令结合使用,注意v-else必须紧跟v-if或者v-else-if之后。比如:

    
    
      
        
        
        
        v-if
      
      
        

    正常显示

    不显示
    也是正常显示
    也是不显示

    你可以狠狠点击此处具体示例查看效果。

    v-if也可以直接在标签上使用,这种情况下,我们通常是为了切换多个元素,因为v-if必须添加到一个元素上,而且会把template当作不可见元素来渲染,也就是说最终渲染不会包含template元素。比如:

    
    
      
        
        
        
        v-if
      
      
        

    你可以狠狠点击此处具体示例查看效果。

    vue2.1.0新增了v-else-if,顾名思义,也就是紧跟v-if之后,v-else之前的指令,可以使用多个v-else-if指令。比如:

    
    
      
        
        
        
        v-if
      
      
        

    哈哈哈

    嘿嘿嘿
    嘻嘻嘻

    呵呵呵

    你可以狠狠点击此处具体示例查看效果。在这些示例中,只要绑定的是在vue实例data选项中的数据,那么值就是响应式的,我们可以直接在控制台中修改,比如以上的vm.type = 1,我们就可以看到页面的的元素以及内容被改变,并重新渲染。

    由于vue是简单的复用元素,而不是重新渲染元素,因此,这会让vue非常的高效,但这不可避免出现了一个问题,如下:

    
    
    
    
        
        
        
        v-if
    
    
    
        

    你可以狠狠点击此处具体示例查看效果。在输入框中输入值,然后再点击切换按钮,你会发现input的内容并没有被清空,这也说明vue并不是重新渲染元素,而是高效的复用元素而已。再实际开发中,这样肯定是不符合需求的,那么我们应该如何解决这个问题呢?

    还好,vue提供了一个key属性,我们只需要给每个复用的元素绑定一个key属性,用于区分它们是不同的元素。如下:

    
    
    
    
        
        
        
        v-if
    
    
    
        

    现在你再尝试在输入框中输入值,然后点击切换按钮,就会发现值会被清空了。请点击具体示例查看效果。

    需要注意的是label元素其实也是被复用了,因为它们没有添加key属性。

    v-show的指令用法跟v-if差不多,唯一需要注意的区别就是v-show仅仅只是改变了元素的display属性而已,其DOM元素仍然存在于文档中,

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/114266.html

    相关文章

    • 前方来报,八月最新资讯--关于vue2&3的最佳文章推荐

      摘要:哪吒别人的看法都是狗屁,你是谁只有你自己说了才算,这是爹教我的道理。哪吒去他个鸟命我命由我,不由天是魔是仙,我自己决定哪吒白白搭上一条人命,你傻不傻敖丙不傻谁和你做朋友太乙真人人是否能够改变命运,我不晓得。我只晓得,不认命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出处 查看github最新的Vue...

      izhuhaodev 评论0 收藏0
    • 一步步从零开始学习vue-router

      摘要:前言一个包含的简单,从第一个开始,依次深入学习,即可快速上手强大的。 前言 一个包含 vue-router的简单demos,从第一个demo开始,依次深入学习,即可快速上手强大的vue-router。 如何使用 安装模块pure 或 http-server来启动服务器npm install -g puer or npm install -g http-server 克隆仓库 启动服...

      Cobub 评论0 收藏0
    • 第一集: 从零开始实现一套pc端vue的ui组件库(环境的搭建)

      摘要:第一集从零开始实现环境的搭建工程定位本套工程定位在端针对的组件库名字的由来是我从年养到现在的一直大金毛是我的吉祥物原因本人上一份工作参与了大型的保险公司后台管理系统的搭建对的端框架有过一定的了解感受到了他们真的很强大同时也存在少许的不足其实 第一集: 从零开始实现(环境的搭建) 工程定位: 本套工程, 定位在pc端针对vue的ui组件库 名字的由来 cc是我从2015年养到现在的...

      Ashin 评论0 收藏0
    • 后端开发者从零做一个移动应用(一)

      摘要:最近终于痛定思痛,做了一个应用,目前的产品确实很一般,但决定以此为起步,逐步完善逐步提高。是以提供游戏下载游戏礼包发放为核心的移动端应用。可以简单理解成一个游戏的应用市场。在写后端的时候,产出了一个基于的授权的。 移动互联网时代,我不想只当一个后端工程师,是时候学习一些新的东西了! 一直以来想要学习一些前端的知识,扩宽自己的技术栈,但是一直以来对前端都是进行了解,没有用一个产品把这些东...

      galaxy_robot 评论0 收藏0
    • 第八集: 从零开始实现一套pc端vue的ui组件库(input, textarea组件)

      摘要:第八集从零开始实现输入框组件本集定位组件是交互的一大利器他与用户的交流最为密切所以奠定了他在组件界的重要地位也算是一种如果可以的话本集也会一起说完毕竟是一个类型的一起学完收获会很大古人云组件不封输入框,一到面试就发慌一简介大家如果对这个 第八集: 从零开始实现(输入框input,textarea组件) 本集定位: input组件是交互的一大利器, 他与用户的交流最为密切, 所以奠...

      binaryTree 评论0 收藏0

    发表评论

    0条评论

    flyer_dev

    |高级讲师

    TA的文章

    阅读更多
    最新活动
    阅读需要支付1元查看
    <