前端mvvm框架vue.js(1)——初步学习

vue.js由Evan you大神开源的个人项目,借鉴于angular.js,但比angular.js更加简洁,易上手,同时提供了一个vue-cli命令行工具,几行命令快速搭建单页应用;

数据驱动组件,实现响应的数据绑定和组合的视图组件,分为3层model,view,viewmodel

mvvm分层

一,vue实例

vue.js通过构造函数Vue创建一个根实例,需要传递一个选项对象options

1,根实例

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

2,属性与方法

可以通过在data和methods中声明

var vm=new Vue({
   //在data中定义属性
   data:data,
  //在methods中定义方法
  methods:mehods
})

3,实例生命周期

 var vm=new Vue({
  data:{a:"实例周期"},
  methods:methods,
  created:function(){
   //this指向这个实例
   console.log(this.a);
},
//其他生命周期方法还有
  beforeCompile:function(){},
  compiled:function(){},
  ready:function(){},
  beforeDestory:function(){},
  destoryed:function(){}
})

二,数据绑定语法

1,插值

//文本插值
<span>{{message}}<span>
//html特性
<span id="{{message}}"></span>

2,绑定表达式

{{numbers+1}}
{{str,split("").reverse()}}

注意:只能绑定单个表达式,无法使用流程控制

//无效
{{if(ok){console.log("ok")}}}

3,过滤器

在表达式后添加“过滤器”,以管道符表示“|”

{{message|filter}}
//可以串联
{{message|filterA|filterB}}
//可以添加参数
{{message|filter "arg1" arg2}}
//arg1为参数,arg2为表达式,并作为第一个参数传递给过滤器函数

三,指令

vue,js中指令带有特殊的前缀v-,指令的值限定为绑定表达式,常用指令有:

  • v-if(根据表达式插入或移除DOM元素)
  • v-show(简单的改变DOM元素display)、
  • v-bind(绑定动态的特性)、
  • v-on(绑定事件)
//根据表达式show的bool值,插入或移除span元素
 <span v-if=“show”></span>

//根据表达式show的bool值,显示或隐藏span元素
<span v-show="show"></span>

//动态绑定href特性到表达式url的值,同样我们可以通过href={{url}}实现
<a v-bind:href="url"></a>

//绑定事件,事件处理函数为clickHandler
<span v-on:click="clickHandler"></span>

//同时v-bind和v-on支持缩写语法:bind和:on;

四,计算属性

通过在vue,js中绑定表达式限定为一个表达式,当表达式逻辑大于一个时,这时我们可以用到计算属性

<div id="vm>
    a={{a}},b={{b}}
</div>

var vm=new Vue({
    el:"#vm",
    data:{
       a:1
    },
    computed:{
     //默认为get
      b:{
            get:function(){
                return this.a+1}
            //同样我们可以定义set,
            set:function(value){
                  this.b=value;
              }
         }
    }
})

五,class和style绑定

1,class绑定对象语法

 <div v-bind:class={"classA":isA,"classB":"isB"}></div>

data:{
 isA:true;
 isB:false
}
//渲染后
<div class="classA"></div>

2,class绑定数组语法

<div v-bind:class="[class-a,class-b]"></div>
data:{
  class-a:"classA",
  class-b:"classB"
}
//渲染后
<div class="classA classB"></div>
//还可以在数组语法中使用对象,根据isB和isC的bool值确定classB和classC是否添加至class特性中
<div class="[classA,{classB:isB,classC:isC}]"></div>

3,对象绑定内联样式

<div v-bind:style="{color:color,fontSize:fontSize+"px"}"></div>
data:{
  color:#f30,
  fontSize:16
}
<div v-bind:style="styleObj"></div>
data:{
  styleObj:{
    color:"#f30",
    fontSize:"16px"
    }
}

4,数组绑定方法

//data选项中数据同上
<div v-bind:style="[styleObjA,styleObjB]"></div>

六,条件渲染

1,v-if和v-show
v-if根据条件插入和移除DOM元素,v-show根据条件显示和隐藏DOM元素;后面都用v-else指令添加一个"else"块,且必须立即跟在"v-if或v-show"后面

<h1 v-if="ok">ok</h1>
<h1 v-else></h1>

//v-show不支持<template>语法
<template v-if="show">
  <div>我是支持<template>语法的v-if</div>
</template>

对比:v-if有更高的切换消耗,在切换时需要重建和销毁事件监听器和子组件;v-show有更高的初始渲染消耗;对于频繁切换的情况,使用v-show比较好,对初始渲染有要求更高使用v-if比较好

七,列表渲染

vue.js中通过v-for实现列表渲染,形式为v-for="item in items",item为数据数组元素别名,items为数据数组

<div v-for="item in items">
       {{item.message}}
</div>
data:{
  items:[
     {message:"hello"},
     {message:"world"}
  ]
}
//渲染结果
- hello
- world

v-for可以完全访问父组件的属性,另外特殊变量$index,表示数组索引

<ul id="example">
 <li v-for="item in items">
   {{item.message}}-{{$index}}
</li>
</ul>
var vm=new Vue({
   el:"#example",
  data:{
       items:[
           {message:"hello"},
           {message:"world"}
        ]
  }
});
//渲染结果
- hello-0
- world-1

//v-for也支持<template>语法
<ul id="example">
   <template v-for="item in items">
       <li>{{item.message}}-{{$index}}</li>
    </template>
</ul>

变异方法:
vue.js封装了对数组操作的常用方法与原生js中功能类似:pop(),push(),shift(),unshift(),splice(),reverse(),sort()

非变异方法:
vue.js中有几种方法可以基于原数组得到新数组,如filter(),concat(),slice()

track-by
vue.js为复用已有的实例,给出了两种方法单纯的track-by和track-by $index,track-by $index不能同步临时状态(比如<input>的输入值)和组件的私有状态。

问题
vue.js中不能直接使用索引设置元素和修改数据长度,为此,vue.js中实现磊两种方法:$set()和$remove()
对象v-for
特殊变量$key,表示属性名

<ul id="repeat-object>
   <li v-for="value in object">
    {{$key}}-{{value}}
  </li>
</ul>
new Vue({
  el:"#repeat-object",
 data:{
    object:{
        firstName:"hello",
        lastName:"world",
        age:"30"
      }
  }
})
//渲染结果
firstName:hello
lastName:world
age:30
//此时遍历对象时,使用的方法为Object.keys(),返回对象属性组成的数组

显示过滤和排序
1,创建一个计算属性过滤和排序
2,使用内置的过滤器filterByorderBy

七,方法和事件处理器

1,方法处理器

使用v-on监听DOM事件

<div id="example>
   <button v-on:click="greet"></button>
</div>
new Vue({
    el:"#example",
    data:{name:"vue.js"},
    methods:{
         greet:function(event){
              alert("hello"+this.name);
              alert(event.target.tagname);
        }
      }
})

2,内联语句处理

<div id="example-2">
    <button v-on:click="say("hi",$event)">say hi</button>
    <button v-on:click="say("hello",$event)">say hello</button>
</div>
new Vue({
 el:"#example-2",
methods:{
        say:function(msg,event){
          alert(msg);
          alert(event.target.tagName);
      }
    }
})

3,事件修饰符

在事件处理器中经常需要调用event.preventDefault()event.stopPropagation()
vue.js中提供了两种修饰符.prevent和.stop
额外的修饰符:.capture和.self(事件在自身发生才触发)
按键修饰符
enter,tab,delete,esc,up,down,left,right
可以自定义按键Vue.directive("on").keyCodes.f1=112

八,表单控件绑定

可以使用v-model在表单控件上实现双向数据绑定

1,Text

 <span>Message is:{{message}}</span>
 <input type="text" v-model="message">

2,Textarea

<p>{{message}}</p>
<textarea placeholder="add multiple lines" v-model="message"></textarea>

3,checkbox

<input type="checkbox" v-model="checked" id="checkbox">
<label for="checkbox">{{checjed}}</label>
//多个复选框绑定到同一个数组
<input type="checkbox" value="jack" id="one" v-model="checknames">
<label for="one">jack</label>
<input type="checkbox" value="john" id="one" v-model="checknames">
<label for="two">john</label>
<input type="checkbox" value="mike" id="one" v-model="checknames">
<label for="three">mike</label>
<span>{{checknames|json}}</span>
new Vue({
  el:"...",
  data:{checknames:[]}
})

4,radio

<input type="radio"  id="one"  value="one" v-model="picked">
<label for="one">one</label>
<input type="radio" id="two" value="two" v-model="picked">
<label for="two">two</label>
<span>{{picked}}</spam>

5,select

<select v-model="selected">
  <option selected>A</option>
  <option>B</option>
  <option>C</option>
</select>
<span>{{selected}}</span>
//多选绑定到一个数组
<select v-model="selected" multiple>
  <option selected>A</option>
  <option>B</option>
  <option>C</option>
</select>
<span>{{selected|json}}</span>
//动态渲染,用v-for
<select v-model="selected">
   <option v-for="option in options" v-bind:value="option.value">
     {{option.text}}
   </option>
</select>
<span>{{selected|json}}</span>
new Vue({
    el:"..",
    data:{
     options:[
        {text:"one",value:"A"},
        {text:"two",value:"B"},
        {text:"three",value:"C"},
        ]
  }
})

6,绑定value

对于单选,复选框,下拉列表,v-model绑定的是value,复选框在无value的特性的情况下绑定的是true和false,有value的情况下绑定的是value值,同时checkbox可以绑定v-bind:true-value和v-bind:false-value

7,参数特性

lazy:在change事件中同步
number:自动将输入转为Number类型
debounce:延迟数据同步一段时间

八,过渡

利用vue.js的过渡机制可以在插入或移除时,应用过渡效果
transition与下面资源一起使用:
1,v-if
2,v-show
3,v-for(需要使用vue-animates-list插件)
4,动态组件
5,在组件根节点上,有实例的$appendto()方法触发

1,CSS过渡

<div v-if="show" transiton="expand"></div>
//同时定义过渡的类
.expand-transition{}
.expand-enter{}
.expand-leave{}
//动态绑定
<div v-if="show" :transiton="transitionName"></div>
new Vue({
  el:".."
  data:{
   show:false
   transitonName:"fade"
  }
})
//提供钩子
Vue.transition("fade",{
      beforeEnter:function(){},
      enter:function(){},
      afterEnter:function(){},
      enterCancelled:function(){},
      leaveCancelled:function(){},
      beforeLeave:function(){},
      leave:function(){},
     afterLeave:function(){}
})

2,过渡的css类名

类名的添加和切换取决于transition特性,如fade,会有三个类名:
.fade-transtion{}
.fade-enter{}
.fade-leave{}
如果transition特性没有值,类名默认为v-transition v-enter,v-leave

3,自定义过渡类名

可以使用自定义的过渡类名,通常与第三方的动画库animate.css结合使用

  <div v-if="show" class="animated" transition="bounce"></div>
  Vue.transiton("fade",{
    enterClass:bounceInLeft,
    leaveClass:bounceOutRight
  })

4,显式声明过渡类型

基于使用的css,事件要么为transitionend,要么为animationend;某些情况既需要animation,又需要transition;需要显式声明动画类型transition或者animation

Vue.transition("bounce",{
  type:animation
})

5,css动画

css动画和css过渡原理相似

<span v-show="show" transition="bounce"></span>
Vue.transtion("bounce",{
  .bounce-transition:{},
  .bounce-leave{animation:bounce-out 0.5s},
  .bounce-enter{animation:bounce-in:0.5s},
  @key-frames bounce-in{
    0%{transform:scale(0)}
    50%{transform:scale(1.5)}
    100%{transform:scale(1.0)}
  }
  @key-frames bounce-out{
    0%{transform:scale(1)}
    50%{transform:scale(1.5)}
    100%{transform:scale(0)}
  }
})

javascript过渡

使用javascript过渡时,enter和leave需要调用回调done,否则它们将被同步调用,过渡立即结束

//我们以jquery为例
 Vue.transition("fade",{
  css:false,
  enter:function(el,done){
   $(el).css("opacity",0).animate({opacity:1},1000,done)
  },
  enterCancelled:function(el){
   $(el).stop();
}
})

渐近过渡

transiton与v-for一起使用,可以实现渐近效果,各过渡元素添加一个特性:stagger,enterstagger或leavestagger;或者提供相应的钩子

<div v-for="item in items"  transition="stagger" stagegr="100"></div>
Vue.transition("stagger",{
  stagger:function(index){
   Math.min(300,index*50);
  }
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容