Vue学习总结(一)
一、声明式渲染
(1)Vue.js 的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进 DOM
HTML
<div id="app"> {{ message }} </div>
JS
var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } })
(2)除了文本插值,我们还可以采用这样的方式绑定 DOM 元素属性
HTML
<div id="app-2"> <span v-bind:title="message"> 鼠标悬停几秒钟查看此处动态绑定的提示信息! </span> </div>
JS
var app2 = new Vue({ el: '#app-2', data: { message: '页面加载于 ' + new Date() } })
说明:v-bind 属性被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊属性。该指令的作用是:“将这个元素节点的 title 属性和 Vue 实例的 message 属性保持一致。如果message动态变化了,则title属性也会变化。
二、条件与循环
(1)条件
HTML
<div id="app-3"> <p v-if="seen">现在你看到我了</p> </div>
JS
var app3 = new Vue({ el: '#app-3', data: { seen: true } })
(2)循环
HTML
<div id="app-4"> <ol> <li v-for="todo in todos"> {{ todo.text }} </li> </ol> </div>
JS
var app4 = new Vue({ el: '#app-4', data: { todos: [ { text: '学习 JavaScript' }, { text: '学习 Vue' }, { text: '整个牛项目' } ] } })
三、处理用户输入
用 v-on 指令绑定一个事件监听器,通过它调用我们 Vue 实例中定义的方法
HTML
<div id="app-5"> <p>{{ message }}</p> <button v-on:click="reverseMessage">逆转消息</button> </div>
JS
var app5 = new Vue({ el: '#app-5', data: { message: 'Hello Vue.js!' }, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join('') } } })
说明:注意在 reverseMessage 方法中,我们更新了应用的状态,但没有触碰 DOM——所有的 DOM 操作都由 Vue 来处理,你编写的代码不需要关注底层逻辑
四、Vue实例
每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例 启动的。在实例化 Vue 时,需要传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项。
五、属性与方法
每个 Vue 实例都会代理其 data 对象里所有的属性
JS
var data = { a: 1 } var vm = new Vue({ data: data }) vm.a === data.a // -> true // 设置属性也会影响到原始数据 vm.a = 2 data.a // -> 2 // ... 反之亦然 data.a = 3 vm.a // -> 3
除了 data 属性, Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分
JS
var data = { a: 1 } var vm = new Vue({ el: '#example', data: data }) vm.$data === data // -> true vm.$el === document.getElementById('example') // -> true // $watch 是一个实例方法 vm.$watch('a', function (newVal, oldVal) { // 这个回调将在 `vm.a` 改变后调用 })
六、实例生命周期
每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如,实例需要配置数据观测(data observer)、编译模版、挂载实例到 DOM ,然后在数据变化时更新 DOM 。在这个过程中,实例也会调用一些 生命周期钩子 ,这就给我们提供了执行自定义逻辑的机会。例如,created 这个钩子在实例被创建之后被调用。
JS
var vm = new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 实例 console.log('a is: ' + this.a) } }) // -> "a is: 1"
也有一些其它的钩子,在实例生命周期的不同阶段调用,如mounted、updated、destroyed。钩子的 this 指向调用它的 Vue 实例。
七、插值
(1)文本
双大括号
HTML
<span>Message: {{ msg }}</span>
(2)纯HTML
双大括号会将数据解释为纯文本,而非 HTML 。为了输出真正的 HTML ,你需要使用 v-html 指令
HTML
<div v-html="rawHtml"></div>
说明:这个 div 的内容将会被替换成为属性值 rawHtml,直接作为 HTM。
(3)属性
不能在 HTML 属性中使用,应使用 v-bind 指令。
HTML
<div v-bind:id="dynamicId"></div> <button v-bind:disabled="isButtonDisabled">Button</button>
八、Computed
模板内的表达式是非常便利的,但是它们实际上只用于简单的运算。在模板中放入太多的逻辑会让模板过重且难以维护。
HTML
<div id="example"> {{ message.split('').reverse().join('') }} </div>
修改如下:
HTML
<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div>
JS
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // a computed getter reversedMessage: function () { // `this` points to the vm instance return this.message.split('').reverse().join('') } } })
这里通过computed字段,设置一个计算属性 reversedMessage 。我们提供的函数将用作属性 vm.reversedMessage 的 getter,在html中直接饮用这个计算属性即可。
九、Computed VS Methods
上述通过计算属性方式简单修改变量值也可以通过函数实现。
HTML
<p>Reversed message: "{{ reversedMessage() }}"</p>
JS
// in component methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。相比而言,只要发生重新渲染,method 调用总会执行该函数。这是methods与computed的主要区别。当然methods更偏重于方法,computed更偏重于属性。
十、Computed VS Watch
computed属性可以在data中没有,可以随便定义,computed相当于是可以定义新的属性,而且可以给属性定义定义一个函数,将属性在返回之前做简单处理;而watch只能监视已经在data中定义过的属性,相当于属性的getter,setter方法。
十一、计算属性的setter方法
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter
JS
// ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // ...
现在再运行 vm.fullName = ‘John Doe’ 时, setter 会被调用, vm.firstName 和 vm.lastName 也相应地会被更新。
十二、绑定HTML Class
(1)使用v-bind给DOM绑定class属性
HTML
<div v-bind:class="classObject"></div>
JS
data: { classObject: { active: true, 'text-danger': false } }
(2)数组语法
可以把一个数组传给 v-bind:class ,以应用一个 class 列表
HTML
<div v-bind:class="[activeClass, errorClass]">
JS
data: { activeClass: 'active', errorClass: 'text-danger' }
十三、绑定HTML Style
v-bind:style 的对象语法十分直观——看着非常像 CSS ,其实它是一个 JavaScript 对象。 CSS 属性名可以用驼峰式 (camelCase) 或 (配合引号的) 短横分隔命名 (kebab-case)
HTML
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
JS
data: { activeColor: 'red', fontSize: 30 }
十四、条件渲染之v-if
vue中可以使用v-if命令实现根据值动态的显示DOM
HTML
<h1 v-if="ok">Yes</h1> <h1 v-else>No</h1>
v-else 元素必须紧跟在 v-if 或者 v-else-if 元素的后面——否则它将不会被识别。
十五、条件渲染之v-show
与v-if不同的是,带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 是简单地切换元素的 CSS 属性 display
HTML
<h1 v-show="ok">Hello!</h1>
v-if与v-show区别
v-if是真正的条件渲染,当条件改变时,它会重新渲染DOM;而v-show只是简单的改变DOM的css样式,使之隐藏或者显示。
十六、列表渲染之v-for
用 v-for 指令根据一组数组的选项列表进行渲染。 v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名。
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' } ] } })
在 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' } ] } })
也可以用 of 替代 in 作为分隔符,因为它是最接近 JavaScript 迭代器的语法
HTML
<div v-for="item of items"></div>
也可以用 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 } } })
也可以提供第二个的参数为键名
HTML
<div v-for="(value, key) in object"> {{ key }} : {{ value }} </div>
第三个参数为索引
HTML
<div v-for="(value, key, index) in object"> {{ index }}. {{ key }} : {{ value }} </div>
v-for 也可以取整数。在这种情况下,它将重复多次模板
HTML
<div> <span v-for="n in 10">{{ n }} </span> </div>
结果
1 2 3 4 5 6 7 8 9 10
十七、事件处理器
可以用 v-on 指令监听 DOM 事件来触发一些 JavaScript 代码。
HTML
<div id="example-1"> <button v-on:click="counter += 1">增加 1</button> <p>这个按钮被点击了 {{ counter }} 次。</p> </div>
JS
var example1 = new Vue({ el: '#example-1', data: { counter: 0 } })
v-on后面可跟DOM事件,如click,dbclick等等。除了可以直接绑定这种简单的js语法,也可以直接绑定一个js方法,或者内敛的js语句。
HTML
<div id="example-3"> <button v-on:click="say('hi')">Say hi</button> <button v-on:click="say('what')">Say what</button> </div>
JS
new Vue({ el: '#example-3', methods: { say: function (message) { alert(message) } } })
有时也需要在内联语句处理器中访问原生 DOM 事件。可以用特殊变量 $event 把它传入方法
HTML
<button v-on:click="warn('Form cannot be submitted yet.', $event)"> Submit </button>
JS
// ... methods: { warn: function (message, event) { // 现在我们可以访问原生事件对象 if (event) event.preventDefault() alert(message) } }
十八、事件修饰符
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在 methods 中轻松实现这点,但更好的方式是:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。为了解决这个问题, Vue.js 为 v-on 提供了 事件修饰符。通过由点(.)表示的指令后缀来调用修饰符。
HTML
<!-- 阻止单击事件冒泡 --> <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> <!-- 点击事件将只会触发一次 --> <a v-on:click.once="doThis"></a>
十九、键值修饰符
在监听键盘事件时,我们经常需要监测常见的键值。 Vue 允许为 v-on 在监听键盘事件时添加关键修饰符
HTML
<!-- 只有在 keyCode 是 13 时调用 vm.submit() --> <input v-on:keyup.13="submit"> <!-- 同上 --> <input v-on:keyup.enter="submit"> <!-- 缩写语法 --> <input @keyup.enter="submit">
全部的按键别名:
.enter .tab .delete (捕获 “删除” 和 “退格” 键) .esc .space .up .down .left .right
可以通过全局 config.keyCodes 对象自定义键值修饰符别名
JS
// 可以使用 v-on:keyup.f1 Vue.config.keyCodes.f1 = 112
二十、表单控件绑定
用 v-model 指令在表单控件元素上创建双向数据绑定
HTML(单行文本)
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
HTML(多行文本)
<span>Multiline message is:</span> <p style="white-space: pre-line">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
HTML(单个勾选框)
<input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label>
HTML(多个勾选框,绑定到同一个数组)
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span>
JS
new Vue({ el: '...', data: { checkedNames: [] } })
HTML(单选按钮)
<div id="example-4"> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> </div>
JS
new Vue({ el: '#example-4', data: { picked: '' } })
HTML(单选列表)
<div id="example-5"> <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> </div>
HTML(多选列表(绑定到一个数组))
<div id="example-6"> <select v-model="selected" multiple style="width: 50px"> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected }}</span> </div>
JS
new Vue({ el: '#example-6', data: { selected: [] } })
HTML(动态选项,用 v-for 渲染)
<select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected }}</span>
JS
new Vue({ el: '...', data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] } })