Vue.js 是构建用户界面的MVVM框架 ,只关注视图层
Vue将DOM和数据绑定起来,一旦创建了绑定,DOM将和数据保持同步,每当变更了数据,DOM也会相应地更新。这样就减少了不必要的DOM操作提高渲染效率,让前端程序员只需要关心业务逻辑不再关心DOM是如何渲染的
MVC和MVVM的区别:MVC是后端分层开发概念,MVVM是前端视图层的概念,主要关注于视图层分离,也就是MVVM把前端的视图层分为了三部分Model、View、ViewModel
相关介绍、教程和下载使用关注Vue官网
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/vue.js"></script>
</head>
<body>
<!--将来new的Vue实例会控制这个元素中的所有内容,这个区域就是MVVM中的View-->
<div id="app">{{ msg }}</div>
<script>
//创建一个Vue实例,当我们导包后在浏览器内存中就多了一个Vue构造函数
//new出来的vm对象就是MVVM中的ViewModel
var vm = new Vue({
el: '#app', //表示new的这个实例,要控制页面的哪个区域.el为element缩写,填入的是选择器
data: { //data属性中存放的是el中要用到的数据,这个数据就是MVVM中的Model,专门用来保存每个页面数据
msg: 'Hello Vue'
}
//通过Vue提供的指令,很方便地就能把数据渲染到页面上,Vue不推荐手动操作DOM
})
</script>
</body>
</html>
基本指令
v-bloak 这个指令保持在元素上直到关联实例结束编译,和CSS规则如 [v-cloak]{ display: none }
一起用时,这个指令可以隐藏未编译的Mustache标签
Vue实例编译前,页面会显示{{ msg }},不想它显示,可用v-bloak配合CSS来隐藏
<div id="app" v-bloak>{{ msg }}</div>
v-text 和 {{ }} 插值表达式一样会把数据插入到元素里,不同的是v-text会覆盖整个元素的内容,而插值表达式只会替换自己位置的字符
<div id="app" v-text="msg"></div>
v-html 将数据插入到元素里,并且会识别标签,v-text和v-html的区别就像innerText和innerHTML
<div id="app" v-html="msg"></div>
v-bind 用于绑定属性,如想插入数据到title属性中,使用插值表达式是不行的,此时就要用v-bind来绑定属性,此指令可简写为 :
v-bind中可写合法的js表达式,msg就相当于变量,所以可拼接字符串
<input type="button" v-bind:title="msg" value="按钮">
<input type="button" :title="msg" value="按钮">
<input type="button" :title="msg+'123'" value="按钮">
v-on 事件绑定机制,很像原生js在标签中注册事件 onclic=“show()” 的方式,只不过现在使用vue的方式来绑定事件。可简写为 @
事件老是无法触发,检查了多遍后才发现,input标签要放在View中,也就是el指定的那个区域,否则v-on:指令无效
<div id="app">
<input type="button" value="按钮" v-on:click="show">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '123'
},
methods: { //这个methods属性中定义了当前Vue实例所有可用的方法
show: function () {
alert('Hello')
}
}
})
</script>
事件修饰符,绑定事件时可阻止事件冒泡、默认行为
.stop 阻止冒泡
.prevent 阻止默认行为
.capture 使用事件捕获模式,也就是反向冒泡
.self 只有当事件在该元素本身时才触发,隔绝其他元素对自身的冒泡,类似 jQuery中的mouseenter事件
.once 事件只触发一次,底层可能是事件触发后进行了事件解绑
<input type="text" value="按钮" v-on:click.stop="show">
按键修饰符,原生js中通过keyCode来判断指定的键有没有被按下,在Vue中只需要在事件后点按键名即可指定某键
.enter .tab .delete(捕获删除和退格键) .esc .space .up .down .left .right
<input type="text" v-on:keydown.enter="show">
直接使用键码值是可以的,v-on:keyup.13 = “show”,但为了好记所以起了别名
可通过全局config.keyCodes对象来自定义键值修饰符别名
//在Vue构造函数外自定义全局按键修饰符
Vue.config.keyCodes.haha = 11
v-model 实现表单元素和Model中数据的双向绑定,只能用于表单元素。v-bind只是单向绑定,如在文本框中,v-bind:value="msg" 后,msg的值会出现在文本框中,但这只是单向绑定,修改文本框中的值后msg值也跟着改变,这才是双向绑定
注意v-model后没有冒号也不跟属性,直接写等于
<input type="text" v-model="msg">
v-for 用来遍历数组、对象甚至数字
<!--遍历数组,list为data里的名为list的数组-->
<p v-for="item in list">{{ item }}</p>
<!--可以加第二个参数,(元素,索引)-->
<p v-for="(item,i) in list">{{ item }}索引是{{ i }}</p>
<!--如果是遍历对象的话,可以有三个参数,(值,键,索引)-->
<p v-for="(val,key,i) in obj">值是{{ val }},键为{{ key }},属性索引为{{ i }}</p>
<!--如果是遍历数字,则从1开始而不是0-->
<p v-for="n in 10">{{n}}</p>
有相同父元素的子元素必须有独特的 key,重复的 key 会造成渲染错误
key属性值只能是number或string,而且因为key是属性所以也要用v-bind来绑定
<p v-for="item in list" :key="item.id">
<input type="checkbox">{{item.name}}的id为{{item.id}}
</p>
v-if 根据表达式的真假来渲染元素
v-show 根据表达式的真假切换元素的display CSS属性,都能实现元素的显示隐藏,不同的是v-if是通过删除添加DOM元素的方式,v-show是通过CSS的方式,v-if有较高的切换性能消耗,v-show有较高的初始渲染消耗
所以如果元素要频繁地切换,最好用v-show,如果元素可能永远都不会被显示出来给用户看,则推荐用v-if
<input type="button" @click="flag = !flag">
<h3 v-if="flag">v-if控制的h3</h3>
<h3 v-show="flag">v-show控制的h3</h3>
Vue操作样式
Vue中使用class样式,由于class也是标签属性,所以要用v-bind指令来绑定数据
<!--原生写法-->
<h1 class="red thin"> </h1>
<!--传递一个数组,里面是类样式名-->
<h1 :class="['thin', 'italic']"> </h1>
<!--在数组中使用三元表达式,flag为data中定义的布尔类型属性-->
<h1 :class="['thin', 'italic', flag?'active':'']"> </h1>
<!--在数组中使用对象来代替三元表达式,提高代码的可读性-->
<h1 :class="['thin', 'italic', {'active':flag} ]"> </h1>
<!--直接使用对象,键为类样式名,值为布尔,表示是否应用这个样式-->
<h1 :class="{red:true,italic:true,thin:true,active:true}"> </h1>
Vue中使用内联样式,类似jq的css方法,里面传入对象
<h1 :style="{'color':'red','font-size':'16px'}"></h1>
也可将对象定义到data中,再在标签里写对象的引用
文字跑马灯小案例
<div id="app">
<!--方法带不带括号都可以,带的话可以传参数-->
<input type="button" value="浪起来" v-on:click="start">
<input type="button" value="淡定" v-on:click="stop">
<p>{{msg}}</p>
</div>
<script>
//VM实例中获取data的数据或者调用methods里的方法,必须通过this来访问
var vm = new Vue({
el: '#app',
data: {
msg: '划船不用桨全靠浪~~~',
timeId:null //定时器id
},
methods: { //这个methods属性中定义了当前Vue实例所有可用的方法
start: function () {
if(this.timeId != null) return //使用节流阀防止定时器多次开启
this.timeId = setInterval(() => {
var start = this.msg.substring(0, 1) //截取第一个字符
var end = this.msg.substring(1) //截取剩下的字符
this.msg = end.concat(start)
}, 500)
},
stop: function () {
clearInterval(this.timeId)
this.timeId = null
}
}
})
</script>
也可以启动前先清除定时器的方式来防止定时器多次开启,不过感觉相比下此方式应该是比较耗性能的
定时器里的this指向的是window,但用了ES6的箭头函数,this指向仍是vm实例对象
实例化后window里会有vm实例对象,底层会把data里的属性挂载到vm实例对象上作为vm的属性,所以可以直接通this点来获取