简介
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
指令
v-bind 动态的绑定数据
<div v-bind:color="color"></div>
// 简写形式
<div :color="color"></div>
v-text 更新元素的文本内容
<div v-text="content"></div>
v-html 更新元素的 innerHTML
<div v-html="content"></div>
v-cloak 隐藏未编译的 Mustache 标签直到实例准备完毕 配合样式使用
//样式
[v-cloak]{
display: none;
}
<div id="app" v-cloak>
{{content}}
</div>
v-once 只渲染一次
<div v-once>只渲染一次: {{content}}</div>
v-for 循环
//循环数组
<div id="app">
<ul>
<li v-for="book in books">{{book}}</li>
</ul>
<ul>
<li v-for="(book,index) in books">{{index}} - {{book}}</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
books: ['javascript','nodejs','vuejs']
}
})
//循环对象
<div id="app">
<ul>
<li v-for="value in user">{{value}}</li>
</ul>
<ul>
<li v-for="(value,key) in user">{{key}} : {{value}}</li>
</ul>
<ul>
<li v-for="(value,key,index) in user">{{index}} - {{key}} : {{value}}</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
user: {
name: 'js',
age: 18,
city: 'china'
}
}
})
v-if 根据表达式的值的真假条件渲染元素和移出元素
<div v-if="true">我被渲染了</div>
<div v-if="false">我不会被渲染</div>
v-show 根据表达式的值的真假条件,切换元素的display属性
<div v-show="true">我显示了</div>
<div v-show="false">我隐藏了</div>
v-model 在表单控件或者组件上创建双向绑定
<div>
<input v-model="message" type="text" />
</div>
<h2>{{message}}</h2>
new Vue({
el: '#app',
data: {
message: 'hello vue'
}
})
v-on 绑定事件处理函数监听 DOM 事件,简写为@
<div v-on:click="clickHandle">点击事件</div>
<div @click="clickHandle">点击事件</div>
// 需要手动传入$event事件对象
<div v-on:click="clickHandle($event,params)">点击事件</div>
//事件处理函数中的this都指向实例
new Vue({
el: '#app',
data: {},
methods: {
clickHandle(event,params){
console.log(event)
}
}
})
事件修饰符
- .stop 阻止冒泡
- .prevent 阻止默认事件
- .capture 捕获事件
- .self 事件源是本身才出发
- .once 只触发一次
- .left 点击鼠标左键时触发
- .right 点击鼠标右键时触发
- .middle 点击鼠标中键时触发
按键修饰符
- .enter
- .tab
- .delete
- .es
- .space
- .up
- .down
- .left
- .right
new Vue({
el: '#app',
data: {},
methods: {
clickA(){
alert('我是A');
},
clickB(){
alert('我是B');
}
}
})
//阻止冒泡
<div @click="clickA">
我是A
<div @click.stop="clickB">
我是B
</div>
</div>
//self
<div @click="clickA">
我是A
<div @click.self="clickB">
我是B
</div>
</div>
//捕获
<div @click="clickA">
我是A
<div @click.capture="clickB">
我是B
</div>
</div>
//阻止默认事件
<a @click.prevent href="http://www.juejin.com">阻止默认事件</a>
//只触发一次
<div @click.once="clickA">只触发一次</div>
选项卡实例
<style>
button.active{
background: yellow;
}
.card{
padding: 10px;
width: 500px;
height: 500px;
border: 1px solid #ccc;
display: none;
}
.card.active{
display: block;
}
</style>
<div id="app">
<div>
<button v-for="(book,index) in books" @click="showTab(index)" :class="{active: tabIndex==index}" type="button">{{book.name}}</button>
</div>
<div v-for="(book,index) in books" :class="{active: tabIndex==index}" class="card">
<h2>{{book.name}}</h2>
<p>{{book.info}}</p>
</div>
</div>
new Vue({
el: '#app',
data: {
books: [
{
name: 'javascript',
info: 'JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。'
},
{
name: 'nodejs',
info: 'Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。'
},
{
name: 'vuejs',
info: 'Vue是一套用于构建用户界面的渐进式框架。'
}
],
tabIndex: 0
},
methods: {
showTab(i){
this.tabIndex = i;
}
}
})
双向数据绑定
双向数据绑定
Vue将数据对象和DOM进行绑定,彼此之间互相产生影响,数据的改变会引起DOM的改变,DOM的改变也会引起数据的变化
MVVM模式
<div>
<input v-model="message" type="text" />
</div>
<h2>{{message}}</h2>
new Vue({
el: '#app',
data: {
message: 'hello vue'
}
})
响应式原理
- 把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项
- Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter
- Vue内部会对数据进行劫持操作,进而追踪依赖,在属性被访问和修改时通知变化
Object.defineProperty
- 作用:直接在一个对象上定义一个新属性,或者修改一个对象的现有属性
- 语法:Object.defineProperty(obj, prop, descriptor)
- 参数:(对象,属性,属性描述符/存取器描述)
[属性描述符]
是否可配置删除,默认false
configurable: false
是否可枚举,默认false
enumerable: false
属性值,默认undefined
value: undefined
是否可被重写,默认false
writable: false
[存取器描述]
获得属性值的方法
getter: function(){}
设置属性值的方法
setter: function(){}
//添加修改对象属性
let obj = {
a: 1,
b: 2
}
Object.defineProperty(obj, 'a', {
value: 3
});
Object.defineProperty(obj, 'c', {
configurable: true,
enumerable: true,
value: 4,
writable: true
});
console.log(obj) //{a: 3, b: 2, c: 4}
- 使用defineReactive劫持数据
//劫持数据
function observer(data,cb){
Object.keys(data).forEach( (key) => {
defineReactive(data,key,data[key],cb)
})
}
//转换getter,setter
function defineReactive(obj,key,value,cb){
Object.defineProperty(obj,key,{
get(){
return value;
},
set(newValue){
value = newValue;
cb(newValue);
}
})
}
- 使用Proxy劫持数据
function observer(data,cb){
return new Proxy(data,{
get(target,attr){
return target[attr];
},
set(target,attr,newValue){
target[attr] = newValue;
cb(newValue);
}
});
}
<button id="btn" type="button">改变内容</button>
<div id="content"></div>
let content = document.querySelector('#content');
let btn = document.querySelector('#btn');
let data = {
text: 'Vue是一套用于构建用户界面的渐进式框架。'
}
observer(data,function(newVal){
content.innerHTML = newVal;
})
content.innerHTML = data.text;
btn.onclick = function(){
data.text = '内容改变了';
}
选项
data
Vue 实例的数据对象
methods
事件处理器
computed
- 计算属性定义在computed中,它不是方法,属性的值是函数的返回值。
- 把对处理数据的逻辑抽离在计算属性中,使得模板更加轻量易读
- 计算属性的值会被缓存,并根据依赖的数据变化而重新计算
//默认设置的get函数
new Vue({
el: '#app',
data: {
a: 1
},
computed: {
b(){
return 2;
}
}
})
//设置get,set函数
new Vue({
el: '#app',
data: {
a: 1
},
computed: {
b: {
get(){
return 2;
},
set(newVal){
this.b = newVal;
}
}
}
})
watch
watch观察 Vue 实例上的数据变动,键是需要观察的表达式,值是对应回调函数
let vm = new Vue({
el: '#app',
data: {
html: 'html',
js: {
javascript: 'javascript',
nodejs: 'nodejs',
vuejs: 'vuejs'
}
},
watch: {
html(newVal,oldVal){
console.log(newVal,oldVal) // -> 改变html html
}
}
})
vm.html = '改变html';
//深度监控
let vm = new Vue({
el: '#app',
data: {
html: 'html',
js: {
javascript: 'javascript',
nodejs: 'nodejs',
vuejs: 'vuejs'
}
},
watch: {
'js.vuejs':{
handler(newVal,oldVal){
console.log(newVal,oldVal) // -> 改变vuejs vuejs
},
deep: true
}
}
})
vm.js.vuejs = '改变vuejs';
//侦听开始之后被立即调用
let vm = new Vue({
el: '#app',
data: {
html: 'html',
js: {
javascript: 'javascript',
nodejs: 'nodejs',
vuejs: 'vuejs'
}
},
watch: {
html:{
handler(newVal,oldVal){
console.log(newVal,oldVal) // -> html undefined
},
immediate: true
}
}
})
响应的数据变化
- Vue.set( target, key, value )
- vm.$set( target, key, value )
<div id="app">
<button @click="addCity1" type="button">Vue添加城市属性</button>
<button @click="addCity2" type="button">vm添加城市属性</button>
<ul>
<li v-for="(value,key) in user">{{key}} : {{value}}</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
user: {
name: 'js',
age: 18
}
},
methods: {
addCity1(){
Vue.set( this.user, 'city', 'china' )
},
addCity2(){
this.$set( this.user, 'city', 'china' )
}
}
})