在字符串模板中,如 Handlebars ,咱们得像这样写一个条件块:javascript
<!-- Handlebars 模板 --> {{#if ok}} <h1>Yes</h1> {{/if}}
在 Vue.js ,咱们使用 v-if
指令实现一样的功能:html
<h1 v-if="ok">Yes</h1>
也能够用 v-else
添加一个 “else” 块:前端
<h1 v-if="ok">Yes</h1> <h1 v-else>No</h1>
由于 v-if
是一个指令,须要将它添加到一个元素上。可是若是咱们想切换多个元素呢?此时咱们能够把一个 <template>
元素当作包装元素,并在上面使用 v-if
,最终的渲染结果不会包含它。vue
<template v-if="ok"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>
示例:java
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>条件渲染</title> </head> <body> <div id="app1"> <p> <button type="button" @click="isShow=!isShow">Toggle isShow</button> </p> <h1 v-if="isShow">Yes</h1> <h1 v-else>No</h1> <template v-if="!isShow"> <p>item1</p><p>item2</p><p>item3</p> </template> <template v-else> <p>item4</p><p>item5</p><p>item6</p> </template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { isShow: true } }); </script> </body> </html>
结果:webpack
切换git
能够用 v-else
指令给 v-if
添加一个 “else” 块:github
<div v-if="Math.random() > 0.5"> Sorry </div> <div v-else> Not sorry </div>
v-else
元素必须紧跟在 v-if
元素的后面——不然它不能被识别。web
1.1.三、v-else-if
2.1.0 新增v-else-if
,顾名思义,充当 v-if
的“else-if 块”,能够连续使用:api
<div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div>
相似于 v-else
,v-else-if
也必须紧跟在带 v-if
或者 v-else-if
的元素以后。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>条件渲染</title> </head> <body> <div id="app1"> <div v-if="Math.random() > 0.5"> Sorry </div> <div v-else> Not sorry </div> <div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { type:"C" } }); </script> </body> </html>
结果:
key
管理可复用的元素Vue 会尽量高效地渲染元素,一般会复用已有元素而不是从头开始渲染。这么作除了使 Vue 变得很是快以外,还有其它一些好处。例如,若是你容许用户在不一样的登陆方式之间切换:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template>
本身动手试一试,在输入框中输入一些文本,而后按下切换按钮:那么在上面的代码中切换 loginType
将不会清除用户已经输入的内容。由于两个模板使用了相同的元素,<input>
不会被替换掉——仅仅是替换了它的 placeholder
。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>条件渲染</title> </head> <body> <div id="app1"> <template v-if="type==='username'"> <label>账号:</label> <input placeholder="请输入您的账号" /> </template> <template v-else> <label>邮箱:</label> <input placeholder="请输入您的电子邮箱" /> </template> <p> <a href="" @click.prevent="type='username'">用户名登陆</a> | <a href="" @click.prevent="type='email'">邮箱登陆</a> </p> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { isShow: true, type: "username" } }); </script> </body> </html>
结果:
点击邮箱登陆
这样也不老是符合实际需求,因此 Vue 为你提供了一种方式来表达“这两个元素是彻底独立的,不要复用它们”。只需添加一个具备惟一值的 key
属性便可:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template>
如今,每次切换时,输入框都将被从新渲染。
<div id="app1"> <template v-if="type==='username'"> <label>账号:</label> <input placeholder="请输入您的账号" key="username"/> </template> <template v-else> <label>邮箱:</label> <input placeholder="请输入您的电子邮箱" key="email"/> </template> <p> <a href="" @click.prevent="type='username'">用户名登陆</a> | <a href="" @click.prevent="type='email'">邮箱登陆</a> </p> </div>
注意,<label>
元素仍然会被高效地复用,由于它们没有添加 key
属性。
另外一个根据条件展现元素的选项是 v-show
指令。用法大致上同样:
<h1 v-show="ok">Hello!</h1>
不一样的是有 v-show
的元素会始终渲染并保持在 DOM 中。v-show
是简单的切换元素的 CSS 属性 display
。
注意 v-show
不支持 <template>
语法。
v-if
是真实的条件渲染,由于它会确保条件块在切换当中适当地销毁与重建条件块内的事件监听器和子组件。
v-if
也是惰性的:若是在初始渲染时条件为假,则什么也不作——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。
相比之下, v-show
简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。
通常来讲, v-if
有更高的切换消耗而 v-show
有更高的初始渲染消耗。所以,若是须要频繁切换使用 v-show
较好,若是在运行时条件不大可能改变则使用 v-if
较好。
官方文档: http://vuejs.org/guide/conditional.html
2.一、v-for
咱们用 v-for
指令根据一组数组的选项列表进行渲染。 v-for
指令须要以item in items
形式的特殊语法, items
是源数据数组而且 item
是数组元素迭代的别名。
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul>
var example1 = new Vue({ el: '#example-1', data: { items: [ {message: 'foo' }, {message: 'Bar' } ] } })
结果:
在 v-for
块中,咱们拥有对父做用域属性的彻底访问权限。 v-for
还支持一个可选的第二个参数为当前项的索引。
<ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul>
var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
结果:
你也能够用 of
替代 in
做为分隔符,由于它是最接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
如同 v-if
模板,你也能够用带有 v-for
的 <template>
标签来渲染多个元素块。例如:
<ul> <template v-for="item in items"> <li>{{ item.msg }}</li> <li class="divider"></li> </template> </ul>
你也能够用 v-for
经过一个对象的属性来迭代。
<ul id="repeat-object" class="demo"> <li v-for="value in object"> {{ value }} </li> </ul>
new Vue({ el: '#repeat-object', data: { object: { FirstName: 'John', LastName: 'Doe', Age: 30 } } })
结果:
你也能够提供第二个的参数为键名:
<div v-for="(value, key) in object"> {{ key }} : {{ value }} </div>
第三个参数为索引:
<div v-for="(value, key, index) in object"> {{ index }}. {{ key }} : {{ value }} </div>
在遍历对象时,是按 Object.keys() 的结果遍历,可是不能保证它的结果在不一样的 JavaScript 引擎下是一致的。
v-for
也能够取整数。在这种状况下,它将重复屡次模板。
<div> <span v-for="n in 10">{{ n }}</span> </div>
结果:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app1"> <ul> <template v-for="(user,index) in users"> <li>{{index+1}} - {{user.name}}</li> <li> <hr/> </li> </template> </ul> <h3>遍历对象中的全部属性value</h3> <p v-for="value in product"> {{value}} </p> <h3>遍历对象中的全部属性value - key</h3> <p v-for="(value,key) in product"> {{key}} - {{value}} </p> <h3>遍历对象中的全部属性value - key - index</h3> <p v-for="(value,key,index) in product"> {{index}} - {{key}} - {{value}} </p> <h3>整数迭代 v-for</h3> <span v-for="n in 20"> {{n}} - </span> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { users: [{ name: "tom", age: 18 }, { name: "rose", age: 87 }, { name: "mark", age: 16 } ], product: { name: "苹果", price: 5.8, unit: '千克' } } }); </script> </body> </html>
了解组件相关知识,查看 组件 。Feel free to skip it and come back later.
在自定义组件里,你能够像任何普通元素同样用 v-for
。
<my-component v-for="item in items"></my-component>
然而他不能自动传递数据到组件里,由于组件有本身独立的做用域。为了传递迭代数据到组件里,咱们要用 props
:
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index"> </my-component>
不自动注入 item
到组件里的缘由是,由于这使得组件会紧密耦合到 v-for
如何运做。在一些状况下,明确数据的来源可使组件可重用。
下面是一个简单的 todo list 完整的例子:
<div id="todo-list-example"> <input v-model="newTodoText" v-on:keyup.enter="addNewTodo" placeholder="Add a todo" > <ul> <li is="todo-item" v-for="(todo, index) in todos" v-bind:title="todo" v-on:remove="todos.splice(index, 1)" ></li> </ul> </div>
Vue.component('todo-item', { template: ' <li> {{ title }} <button v-on:click="$emit(\'remove\')">X</button> </li>', props: ['title'] }) new Vue({ el: '#todo-list-example', data: { newTodoText: '', todos: [ 'Do the dishes', 'Take out the trash', 'Mow the lawn' ] }, methods: { addNewTodo: function () { this.todos.push(this.newTodoText) this.newTodoText = '' } } })
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app1"> 任务:<input v-model="newTask" @keyup.enter="addNew" placeholder="请输入您要完成的任务" /> <ul> <li is="todoitem" v-for="(task,index) in tasks" :title="task" @remove="removeItem(index)"></li> </ul> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component("todoitem", { template: "<li>{{title}} <button @click='$emit(\"remove\")'>X</button></li>", props: ['title'] }); var app1 = new Vue({ el: "#app1", data: { newTask: '', tasks: ["买一本书", "给爸妈打电话", "整理本身的硬盘"] }, methods: { addNew: function() { this.tasks.unshift(this.newTask); this.newTask = ''; }, removeItem: function(index) { if(confirm('肯定要移除吗?')) { this.tasks.splice(index, 1); } } } }); </script> </body> </html>
结果:
当 Vue.js 用 v-for
正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。若是数据项的顺序被改变,而不是移动 DOM 元素来匹配数据项的顺序, Vue 将简单复用此处每一个元素,而且确保它在特定索引下显示已被渲染过的每一个元素。这个相似 Vue 1.x 的track-by="$index"
。
这个默认的模式是有效的,可是只适用于不依赖子组件状态或临时 DOM 状态(例如:表单输入值)的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每一个节点的身份,从而重用和从新排序现有元素,你须要为每项提供一个惟一 key
属性。理想的 key
值是每项都有惟一 id。这个特殊的属性至关于 Vue 1.x 的 track-by
,但它的工做方式相似于一个属性,因此你须要用v-bind
来绑定动态值(在这里使用简写):
<div v-for="item in items" :key="item.id"> <!-- 内容 --> </div>
建议尽量使用 v-for
来提供 key
,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来得到性能提高。
由于它是 Vue 识别节点的一个通用机制, key
并不特别与 v-for
关联,key 还具备其余用途,咱们将在后面的指南中看到其余用途。
Vue 包含一组观察数组的变异方法,因此它们也将会触发视图更新。这些方法以下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
你打开控制台,而后用前面例子的 items
数组调用突变方法:example1.items.push({ message: 'Baz' })
。
变异方法(mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异(non-mutating method)方法,例如: filter()
, concat()
, slice()
。这些不会改变原始数组,但老是返回一个新数组。当使用非变异方法时,能够用新数组替换旧数组:
example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) })
你可能认为这将致使 Vue 丢弃现有 DOM 并从新渲染整个列表。幸运的是,事实并不是如此。 Vue 实现了一些智能启发式方法来最大化 DOM 元素重用,因此用一个含有相同元素的数组去替换原来的数组是很是高效的操做。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app1"> <ul> <li v-for="n in items"> <h2>{{n}}</h2> </li> </ul> <button @click="items.splice(0,3)">修改数组(变异)</button> <button @click="items.slice(0,3)">修改数组(不变异)</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { items:[1,3,5,7,9,2,4,6,8,0] } }); </script> </body> </html>
结果:
若是原数组发生了变化则View也会从新渲染,若是原数组未发生变化只是读取后返回了新的数组对象则不会渲染。
因为 JavaScript 的限制, Vue 不能检测如下变更的数组:
vm.items[indexOfItem] = newValue
vm.items.length = newLength
为了不第一种状况,如下两种方式将达到像 vm.items[indexOfItem] = newValue
的效果, 同时也将触发状态更新:
// Vue.set Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice` example1.items.splice(indexOfItem, 1, newValue)
避免第二种状况,使用 splice
:
example1.items.splice(newLength)
splice数组详解:
splice() 方法向/从数组中添加/删除项目,而后返回被删除的项目。 注释:该方法会改变原始数组。 语法 arrayObject.splice(index,howmany,item1,.....,itemX) index //规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 howmany //要删除的项目数量。若是设置为 0,则不会删除项目。 item1, ..., itemX //向数组添加的新项目。 返回值 Array 包含被删除项目的新数组,若是有的话。 说明 //splice() 方法可删除从 index 处开始的零个或多个元素,而且用参数列表中声明的一个或多个值来替换那些被删除的元素。 //若是从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app1"> <ul> <li v-for="n in items"> <h2>{{n}}</h2> </li> </ul> <button @click="items[2]=55">修改第3个元素的值为55(无效)</button> <button @click="setValue">Vue.set修改第3个元素的值为55</button> <button @click="items.splice(2,1,55)">Vue.set修改第3个元素的值为55</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { items: [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] }, methods: { setValue: function() { Vue.set(this.items, 2, 55); } } }); </script> </body> </html>
结果:
仍是因为 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 如今是响应式的 vm.b = 2 // `vm.b` 不是响应式的
对于已经建立的实例,Vue 不能动态添加根级别的响应式属性。可是,可使用 Vue.set(object, key, value)
方法向嵌套对象添加响应式属性。例如,对于:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } } })
你能够添加一个新的 age
属性到嵌套的 userProfile
对象:
Vue.set(vm.userProfile, 'age', 27)
你还可使用 vm.$set
实例方法,它只是全局 Vue.set
的别名:
vm.$set(this.userProfile, 'age', 27)
有时你可能须要为已有对象赋予多个新属性,好比使用 Object.assign()
或 _.extend()
。在这种状况下,你应该用两个对象的属性建立一个新的对象。因此,若是你想添加新的响应式属性,不要像这样:
Object.assign(this.userProfile, { age: 27, favoriteColor: 'Vue Green' })
你应该这样作:
this.userProfile = Object.assign({}, this.userProfile, { age: 27, favoriteColor: 'Vue Green' })
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>对象更改检测注意事项</title> </head> <body> <div id="app1"> <h2>对象更改检测注意事项</h2> {{stu.name}} - {{stu.age}} <p> <button @click="setAge">在stu对象中添加age属性并设置值为100</button> </p> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { stu:{ name:"tom" } }, methods:{ setAge:function(){ Vue.set(this.stu,'age',100); } }, beforeUpdate:function(){ console.log("更新前"+this.name); }, updated:function(){ console.log("更新后"+this.name); } }); </script> </body> </html>
结果:
注意:
若是data中数据没有被绑定到DOM中,则修改后DOM不会更新,updated与beforeUpdate事件也不会执行(Hook function)
data 的根元素后加入无效,可使用Vue.set添加元素中的属性,这样会变成响应式的成员
有时,咱们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种状况下,能够建立返回过滤或排序数组的计算属性。
例如:
<li v-for="n in evenNumbers">{{ n }}</li>
data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
或者,您也可使用在计算属性是不可行的 method 方法 (例如,在嵌套 v-for
循环中):
<li v-for="n in even(numbers)">{{ n }}</li>
data: { numbers: [ 1, 2, 3, 4, 5 ] }, methods: { even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } }
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app1"> <p> <span v-for="n in items"> {{n}} </span> </p> <p> <span v-for="n in even"> {{n}} </span></p> <p> <span v-for="n in odd()"> {{n}} </span></p> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { items: [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] }, computed: { even: function() { return this.items.filter(function(n) { return n % 2 === 0; }); } }, methods: { odd: function() { return this.items.filter(function(n) { return n % 2 === 1; }); } } }); </script> </body> </html>
结果:
官方原文: http://vuejs.org/guide/list.html
能够用 v-on
指令监听 DOM 事件来触发一些 JavaScript 代码。
示例:
<div id="example-1"> <button v-on:click="counter += 1">增长 1</button> <p>这个按钮被点击了 {{ counter }} 次。</p> </div>
var example1 = new Vue({ el: '#example-1', data: { counter: 0 } })
结果:
这个按钮被点击了 0 次。
许多事件处理的逻辑都很复杂,因此直接把 JavaScript 代码写在 v-on
指令中是不可行的。所以 v-on
能够接收一个定义的方法来调用。
示例:
<div id="example-2"> <!-- `greet` 是在下面定义的方法名 --> <button v-on:click="greet">Greet</button> </div>
var example2 = new Vue({ el: '#example-2', data: { name: 'Vue.js' }, // 在 `methods` 对象中定义方法 methods: { greet: function (event) { // `this` 在方法里指当前 Vue 实例 alert('Hello ' + this.name + '!') // `event` 是原生 DOM 事件 alert(event.target.tagName) } } }) // 也能够用 JavaScript 直接调用方法 example2.greet() // -> 'Hello Vue.js!'
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>事件</title> </head> <body> <div id="app1"> <button v-on:click="greet">问好</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { name:"tom" }, methods: { greet:function(event){ console.log('Hello '+ this.name); console.log('事件对象: '+ event.target.tagName); //从事件对象中得到标签名 console.log(event); //在原生的事件中this指向的是当前事件对象,这里是实例 event.target.innerHTML="问好了!"; } } }); </script> </body> </html>
结果:
除了直接绑定到一个方法,也能够用内联 JavaScript 语句:
<div id="example-3"> <button v-on:click="say('hi')">Say hi</button> <button v-on:click="say('what')">Say what</button> </div>
new Vue({ el: '#example-3', methods: { say: function (message) { alert(message) } } })
结果:
有时也须要在内联语句处理器中访问原生 DOM 事件。能够用特殊变量 $event
把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
// ... methods: { warn: function (message, event) { // 如今咱们能够访问原生事件对象 if (event) event.preventDefault() alert(message) } }
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是很是常见的需求。尽管咱们能够在 methods 中轻松实现这点,但更好的方式是:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题, Vue.js 为 v-on
提供了 事件修饰符。经过由点(.)表示的指令后缀来调用修饰符。
.stop
.prevent
.capture
.self
<!-- 阻止单击事件冒泡 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件再也不重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符能够串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件侦听器时使用事件捕获模式 --> <div v-on:click.capture="doThis">...</div> <!-- 只当事件在该元素自己(而不是子元素)触发时触发回调 --> <div v-on:click.self="doThat">...</div>
在监听键盘事件时,咱们常常须要监测常见的键值。 Vue 容许为 v-on
在监听键盘事件时添加按键修饰符:
<!-- 只有在 keyCode 是 13 时调用 vm.submit() --> <input v-on:keyup.13="submit">
记住全部的 keyCode 比较困难,因此 Vue 为最经常使用的按键提供了别名:
<!-- 同上 --> <input v-on:keyup.enter="submit"> <!-- 缩写语法 --> <input @keyup.enter="submit">
所有的按键别名:
能够经过全局 config.keyCodes
对象 自定义按键修饰符别名:
// 可使用 v-on:keyup.f1 Vue.config.keyCodes.f1 = 112
你可能注意到这种事件监听的方式违背了关注点分离(separation of concern)传统理念。没必要担忧,由于全部的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会致使任何维护上的困难。实际上,使用 v-on
有几个好处:
扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
由于你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码能够是很是纯粹的逻辑,和 DOM 彻底解耦,更易于测试。
当一个 ViewModel 被销毁时,全部的事件处理器都会自动被删除。你无须担忧如何本身清理它们。
原文: http://vuejs.org/guide/events.html
ECMAScript2015中新增了9个方法,分别是:
indexOf()方法返回在该数组中第一个找到的元素位置,若是它不存在则返回-1。
不使用indexOf时:
var arr = ['apple','orange','pear'], found = false; for(var i= 0, l = arr.length; i< l; i++){ if(arr[i] === 'orange'){ found = true; } } console.log("found:",found);
使用后:
var arr = ['apple','orange','pear']; console.log("found:", arr.indexOf("orange") != -1);
该filter()方法建立一个新的匹配过滤条件的数组。
不用 filter() 时
var arr = [ {"name":"apple", "count": 2}, {"name":"orange", "count": 5}, {"name":"pear", "count": 3}, {"name":"orange", "count": 16}, ]; var newArr = []; for(var i= 0, l = arr.length; i< l; i++){ if(arr[i].name === "orange" ){ newArr.push(arr[i]); } } console.log("Filter results:",newArr);
用了 filter():
var arr = [ {"name":"apple", "count": 2}, {"name":"orange", "count": 5}, {"name":"pear", "count": 3}, {"name":"orange", "count": 16}, ]; var newArr = arr.filter(function(item){ return item.name === "orange"; }); console.log("Filter results:",newArr);
forEach为每一个元素执行对应的方法
var arr = [1,2,3,4,5,6,7,8]; // Uses the usual "for" loop to iterate for(var i= 0, l = arr.length; i< l; i++){ console.log(arr[i]); } console.log("========================"); //Uses forEach to iterate arr.forEach(function(item,index){ console.log(item); });
forEach是用来替换for循环的
map()对数组的每一个元素进行必定操做(映射)后,会返回一个新的数组
不使用map:
var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}]; function getNewArr(){ var newArr = []; for(var i= 0, l = oldArr.length; i< l; i++){ var item = oldArr[i]; item.full_name = [item.first_name,item.last_name].join(" "); newArr[i] = item; } return newArr; } console.log(getNewArr());
使用map后:
var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}]; function getNewArr(){ return oldArr.map(function(item,index){ item.full_name = [item.first_name,item.last_name].join(" "); return item; }); } console.log(getNewArr());
map()是处理服务器返回数据时是一个很是实用的函数。
reduce()能够实现一个累加器的功能,将数组的每一个值(从左到右)将其下降到一个值。
说实话刚开始理解这句话有点难度,它太抽象了。
场景: 统计一个数组中有多少个不重复的单词
不使用reduce时:
var arr = ["apple","orange","apple","orange","pear","orange"]; function getWordCnt(){ var obj = {}; for(var i= 0, l = arr.length; i< l; i++){ var item = arr[i]; obj[item] = (obj[item] +1 ) || 1; } return obj; } console.log(getWordCnt());
使用reduce()后
var arr = ["apple","orange","apple","orange","pear","orange"]; function getWordCnt(){ return arr.reduce(function(prev,next){ prev[next] = (prev[next] + 1) || 1; return prev; },{}); } console.log(getWordCnt());
让我先解释一下我本身对reduce的理解。reduce(callback, initialValue)会传入两个变量。回调函数(callback)和初始值(initialValue)。假设函数它有个传入参数,prev和next,index和array。prev和next你是必需要了解的。
通常来说prev是从数组中第一个元素开始的,next是第二个元素。可是当你传入初始值(initialValue)后,第一个prev将是initivalValue,next将是数组中的第一个元素。
好比:
/* * 两者的区别,在console中运行一下便可知晓 */ var arr = ["apple","orange"]; function noPassValue(){ return arr.reduce(function(prev,next){ console.log("prev:",prev); console.log("next:",next); return prev + " " +next; }); } function passValue(){ return arr.reduce(function(prev,next){ console.log("prev:",prev); console.log("next:",next); prev[next] = 1; return prev; },{}); } console.log("No Additional parameter:",noPassValue()); console.log("----------------"); console.log("With {} as an additional parameter:",passValue());
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app1"> <span v-for="n in items"> {{n}} </span> <button @click="indexOfMethod">indexOf()找到的元素位置</button> <button @click="filterMethod">filter()过滤</button> <button @click="forEachMethod">forEach()迭代</button> <button @click="mapMethod">map()映射</button> <button @click="reduceMethod">reduce()累加器</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { items: [1, 3, 7, 9, 2, 4, 6, 8, 3], fruits: [{ "name": "apple", "count": 2 }, { "name": "orange", "count": 5 }, { "name": "pear", "count": 3 }, { "name": "orange", "count": 16 } ], words: ["apple", "orange", "apple", "orange", "pear", "orange"] }, methods: { indexOfMethod: function() { console.log("数字3第一次出现的位置是:" + this.items.indexOf(3)); console.log("数字5第一次出现的位置是:" + this.items.indexOf(5)); }, filterMethod: function() { //得到数量不小于5的水果 var arr1 = this.fruits.filter(function(f) { return f.count >= 5; }); console.log(JSON.stringify(arr1)); //得到名称中含有r的水果 var arr2 = this.fruits.filter(function(f) { return f.name.match(/r/igm); }); console.log(JSON.stringify(arr2)); }, forEachMethod: function() { this.fruits.forEach(function(obj, index) { console.log(index + "-" + obj.name + "-" + obj.count); }); }, mapMethod: function() { var arr3 = this.fruits.map(function(obj, index) { obj.showInfo = index + "->水果:" + obj.name + ",数量:" + obj.count; return obj; }); console.log(JSON.stringify(arr3)); }, reduceMethod: function() { var objs = {}; for(var i = 0, l = this.words.length; i < l; i++) { var item = this.words[i]; objs[item] = (objs[item] + 1) || 1; } console.log(JSON.stringify(objs)); var objs2 = this.words.reduce(function(prev, next) { console.log("prev:", JSON.stringify(prev)); console.log("next:", JSON.stringify(next)); prev[next] = (prev[next] + 1) || 1; return prev; }, {}); console.log(JSON.stringify(objs2)); } } }); </script> </body> </html>
结果:
结果
1. vonic 一个基于 vue.js 和 ionic 样式的 UI 框架,用于快速构建移动端单页应用,很简约,是我喜欢的风格 star 2.3k
2.vux 基于WeUI
和Vue
(2.x)开发的移动端UI组件库 star 10k
基于webpack
+vue-loader
+vux
能够快速开发移动端页面,配合vux-loader
方便你在WeUI
的基础上定制须要的样式。
3.Mint UI 由饿了么前端团队推出的 Mint UI 是一个基于 Vue.js 的移动端组件库 star 8.3k
4.MUI 最接近原生APP体验的高性能前端框架 star 7.5k
5.Muse-ui 基于 Vue 2.0 和 Material Design 的 UI 组件库 star 4.9k
6.Vant是有赞前端团队基于有赞统一的规范实现的 Vue 组件库,提供了一整套 UI 基础组件和业务组件。star 1k
7.Cube UI star 3k
滴滴 WebApp 团队 实现的 基于 Vue.js 实现的精致移动端组件库
特性
质量可靠
由滴滴内部组件库精简提炼而来,经历了业务一年多的考验,而且每一个组件都有充分单元测试,为后续集成提供保障。
体验极致
以迅速响应、动画流畅、接近原生为目标,在交互体验方面追求极致。
标准规范
遵循统一的设计交互标准,高度还原设计效果;接口标准化,统一规范使用方式,开发更加简单高效。
扩展性强
支持按需引入和后编译,轻量灵活;扩展性强,能够方便地基于现有组件实现二次开发
1)Element 饿了么 vue 2.0后台UI框架 (Star:18382)
https://github.com/ElemeFE/element
(2)iview组件库 (Star:10186)
iView 主要服务于 PC 界面的中后台业务,很优秀的组件库,惋惜不适合移动端
https://github.com/iview/iview
https://iviewui.com/
(3)vux 基于Vue和WeUI的移动UI组件 (Star:9762)
Vux是基于WeUI和Vue(2.x)开发的移动端UI组件库,主要服务于微信页面。
https://github.com/airyland/vux
https://vux.li/
(4)Mint-UI 饿了么移动端组件库 (Star:8062)
由饿了么前端团队推出的 Mint UI 是一个基于 Vue.js 的移动端组件库
https://github.com/ElemeFE/mint-ui
(5)vue-admin 管理面板UI框架 (Star:6289)
https://github.com/vue-bulma/vue-admin
(6)vue-material为 Vue.js 打造的 Material 风格的组件 (Star:4550)
https://github.com/vuematerial/vue-material
https://vuematerial.github.io/#/
(7)vue-strap基于 Vue.js 的 Bootstrap 组件 (Star:4400)
https://github.com/yuche/vue-strap
http://yuche.github.io/vue-strap/
(8)KeenUI 基于Material Design的UI (Star:3041)
https://josephuspaye.github.io/Keen-UI/
(9)vonic (Star:2276)
https://github.com/wangdahoo/vonic/
https://wangdahoo.github.io/vonic/docs/#/
(10)Radon-ui awe大神最近写的一套UI (Star:791)
https://github.com/luojilab/radon-ui
(11)N3-components 基于N3ui (Star:781)
https://github.com/N3-components/N3-components
(12)vue-carbon (Star:739)
https://github.com/myronliu347/vue-carbon
JS中,经过利用js方法,能够很方便的实现2,8,10,16进制之间的相互转换
一、2,8,16进制格式的数据转换到10进制数据
var num=parseInt(arg1,arg2);
第一个参数就是须要转换为10进制的数,arg2就是被转换数据的进制值,能够是2,8,16等。
如:将十六进制的数‘d9’转为十进制数:
var num=parseInt(d9,16);//num=217
二、将10进制格式的数据转为2,8,16进制格式数据
var num=parseInt(“217”);//若是这个数是字符串格式的,须要执行这一步 var oxNum=num.toString(16);//参数能够是2,8,16.设置转换10进制数据到对应进制格式,本例是将num转成16进制数据 oxNum=d9
三、2,8,10,16任意进制之间转化
经过10进制做为媒介,即可以实现任意进制之间相互转化了
https://git.coding.net/zhangguo5/vue2.git
小红书项目要求:
http://www.cnblogs.com/xsblog/p/8144290.html