vue.js之个人总结
1、MVVM模式
MVVM模式(Model-View-ViewModel)的运作如下图:
1)上图解析:ViewModel是Vue.js的核心,它是一个Vue实例。Vue实例是作用于某一个HTML元素上的,这个元素可以是HTML的body元素,也可以是指定了id的某个元素。
当创建了ViewModel后,双向绑定是如何达成的呢?
首先,我们将上图中的DOM Listeners和Data Bindings看作两个工具,它们是实现双向绑定的关键。
从View侧看,ViewModel中的DOM Listeners工具会帮我们监测页面上DOM元素的变化,如果有变化,则更改Model中的数据;
从Model侧看,当我们更新Model中的数据时,Data Bindings工具会帮我们更新页面中的DOM元素。
2)可以通过hello word例子进一步解析:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <!--这是我们的View--> <div id="app"> {{ message }} </div> </body> <script src="js/vue.js"></script> <script> // 这是我们的Model var exampleData = { message: 'Hello World!' } // 创建一个 Vue 实例也就是 "ViewModel" // 它连接 View 与 Model new Vue({ el: '#app', data: exampleData }) </script> </html>
根据上例中,可以看出使用Vue的过程就是定义MVVM各个组成部分的过程的过程。
- 定义View
- 定义Model
- 创建一个Vue实例或"ViewModel",它用于连接View和Model
在创建Vue实例时,需要传入一个选项对象,选项对象可以包含数据、挂载元素、方法、模生命周期钩子等等。
在这个示例中,选项对象的el属性指向View,el: '#app'
表示该Vue实例将挂载到<div id="app">...</div>
这个元素;
data属性指向Model,data: exampleData
表示我们的Model是exampleData对象。
Vue.js有多种数据绑定的语法,最基础的形式是文本插值,使用一对大括号语法,在运行时{{ message }}
会被数据对象的message属性替换,所以页面上会输出"Hello World!"。
3)、双向绑定
在Vue.js中可以使用v-model
指令在表单元素上创建双向数据绑定。
可以将上例中的view部分改为
<!--这是我们的View--> <div id="app"> <p>{{ message }}</p>
<!--将message绑定到文本框-->
<input type="text" v-model="message"/>
</div>
效果如下图:当更改文本框的值时,<p>{{ message }}</p>
中的内容也会被更新。
当然,反过来,如果改变message的值,文本框的值也会被更新,我们可以在Chrome控制台进行尝试。
通过该例子可以总结如下:
Vue实例的data属性指向exampleData,它是一个引用类型,改变了exampleData对象的属性,同时也会影响Vue实例的data属性。
2、Vue.js的常用指令
上面用到的v-model
是Vue.js常用的一个指令
1)v-text
HTML: <span id="app2" v-text="msg"></span>
<!-- 和下面的一样 -->
<!-- <span>{{msg}}</span>-->
js: //v-text var example={ msg:'hello word!' } new Vue({ el:'#app2', data:example })
2)v-html
更新元素的 innerHTML
。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译 。如果试图使用 v-html
组合模板,可以重新考虑通过是否通过使用组件来替代。
<div v-html="html"></div>
3)v-show
根据表达式之真假值,切换元素的 display
CSS 属性。
当条件变化时该指令触发过渡效果。
HTML: <p id="app4" v-show="local">这是一个v-show命令指令</p> js: var local=new Vue({ el:'#app4‘, data:{ local:true } }) //结果:在页面上显示这段话:这是一个v-show命令指令
//如果设置data:{local:false}则不显示
4)v-if
在字符串模板中,如 Handlebars ,我们得像这样写一个条件块:
<!-- Handlebars 模板 --> {{#if ok}} <h1>Yes</h1> {{/if}}
在 Vue.js ,我们使用 v-if
指令实现同样的功能:
<h1 v-if="ok">Yes</h1>
也可以用 v-else
添加一个 “else” 块:
<h1 v-if="ok">Yes</h1> <h1 v-else>No</h1>
<template>
中 v-if
条件组
因为 v-if
是一个指令,需要将它添加到一个元素上。但是如果我们想切换多个元素呢?此时我们可以把一个 <template>
元素当做包装元素,并在上面使用 v-if
,最终的渲染结果不会包含它。
<template v-if="ok"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>
5)v-else
v-else
元素必须紧跟在 v-if
元素或者 v-else-if
的后面——否则它不能被识别。
<div v-if="Math.random() > 0.5"> Sorry </div> <div v-else> Not sorry </div>
6)v-else-if
v-if
的 else-if
块。可以链式的多次使用:
<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>
7)v-for
基于源数据多次渲染元素或模板块。此指令之值,必须使用特定语法 alias in expression
,为当前遍历的元素提供别名
基本用法:
HTML: <ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul> js: var example1 = new Vue({ el: '#example-1', data: { items: [ {message: 'Foo' }, {message: 'Bar' } ] } }) 结果: Foo Bar
在 v-for
块中,我们拥有对父作用域属性的完全访问权限。 v-for
还支持一个可选的第二个参数为当前项的索引。
HTML: <ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul> js: var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) 结果: Parent - 0 - Foo Parent - 1 - Bar
也可以用 of
替代 in
作为分隔符,因为它是最接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
Template v-for
如同 v-if
模板,你也可以用带有 v-for
的 <template>
标签来渲染多个元素块。例如:
<ul> <template v-for="item in items"> <li>{{ item.msg }}</li> <li class="divider"></li> </template> </ul>
对象迭代 v-for
你也可以用 v-for
通过一个对象的属性来迭代。
HTML: <ul id="repeat-object" class="demo"> <li v-for="value in object"> {{ value }} </li> </ul> js: new Vue({ el: '#repeat-object', data: { object: { FirstName: 'John', LastName: 'Doe', Age: 30 } } }) 结果: John Doe 30 你也可以提供第二个的参数为键名: <div v-for="(value, key) in object"> {{ key }} : {{ value }} </div> 第三个参数为索引: <div v-for="(value, key, index) in object"> {{ index }}. {{ key }} : {{ value }} </div>
整数迭代 v-for
v-for
也可以取整数。在这种情况下,它将重复多次模板。
<div> <span v-for="n in 10">{{ n }}</span> </div> 结果: 1 2 3 4 5 6 7 8 9 10
7)v-on
.stop
- 调用event.stopPropagation()
。.prevent
- 调用event.preventDefault()
。.capture
- 添加事件侦听器时使用 capture 模式。.self
- 只当事件是从侦听器绑定的元素本身触发时才触发回调。.{keyCode | keyAlias}
- 只当事件是从侦听器绑定的元素本身触发时才触发回调。.native
- 监听组件根元素的原生事件。
用法:
绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
用在普通元素上时,只能监听 原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event
属性: v-on:click="handle('ok', $event)"
。
<!-- 方法处理器 --> <button v-on:click="doThis"></button> <!-- 内联语句 --> <button v-on:click="doThat('hello', $event)"></button> <!-- 缩写 --> <button @click="doThis"></button> <!-- 停止冒泡 --> <button @click.stop="doThis"></button> <!-- 阻止默认行为 --> <button @click.prevent="doThis"></button> <!-- 阻止默认行为,没有表达式 --> <form @submit.prevent></form> <!-- 串联修饰符 --> <button @click.stop.prevent="doThis"></button> <!-- 键修饰符,键别名 --> <input @keyup.enter="onEnter"> <!-- 键修饰符,键代码 --> <input @keyup.13="onEnter">
在子组件上监听自定义事件(当子组件触发 “my-event” 时将调用事件处理器):
<my-component @my-event="handleThis"></my-component> <!-- 内联语句 --> <my-component @my-event="handleThis(123, $event)"></my-component> <!-- 组件中的原生事件 --> <my-component @click.native="onClick"></my-component>
9)v-bind
修饰符:
.prop
- 被用于绑定 DOM 属性。(what’s the difference?).camel
- transform the kebab-case attribute name into camelCase. (supported since 2.1.0)
用法:
动态地绑定一个或多个特性,或一个组件 prop 到表达式。
在绑定 class 或 style 特性时,支持其它类型的值,如数组或对象。可以通过下面的教程链接查看详情。
在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。
没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。
<!-- 绑定一个属性 --> <img v-bind:src="imageSrc"> <!-- 缩写 --> <img :src="imageSrc"> <!-- with inline string concatenation --> <img :src="'/path/to/images/' + fileName"> <!-- class 绑定 --> <div :class="{ red: isRed }"></div> <div :class="[classA, classB]"></div> <div :class="[classA, { classB: isB, classC: isC }]"> <!-- style 绑定 --> <div :style="{ fontSize: size + 'px' }"></div> <div :style="[styleObjectA, styleObjectB]"></div> <!-- 绑定一个有属性的对象 --> <div v-bind="{ id: someProp, 'other-attr': otherProp }"></div> <!-- 通过 prop 修饰符绑定 DOM 属性 --> <div v-bind:text-content.prop="text"></div> <!-- prop 绑定. “prop” 必须在 my-component 中声明。 --> <my-component :prop="someThing"></my-component> <!-- XLink --> <svg><a :xlink:special="foo"></a></svg>
10)v-model :表单控件绑定
v-model
并不关心表单控件初始化所生成的值。因为它会选择 Vue 实例数据来作为具体的值
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
具体表单控制的例子可参考官网:http://cn.vuejs.org/v2/guide/forms.html