如何理解渐进式框架
渐进式框架是指如果你开发的是一个小型应用可以使用vue的核心库轻松开发,如果你开发的是一个大型应用可以添加vue的插件库进行开发。也就是说可以根据应用的大小来选择不至于让框架太冗余。
如何理解虚拟dom
传统的JavaScript的是通过操作真实dom来操作页面元素,这样做会使浏览器响应速度变慢。并且每修改一次代码所有的元素都会进行刷新,旧的元素无法复用。虚拟dom是在代码与真实dom之间添加了一层过渡。通过diff函数判断元素是否相同,若相同则直接复用而不是生成新的元素。
VUE环境搭建
- 引入vue
可以下载官网的js包或者引入在线cdn
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
- 安装vue devtools
- 关闭开发版提示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="../JS/vue.js"></script>
<body>
</body>
<script type="text/javascript">
Vue.config.productionTip=false//阻止vue生成生产提示
</script>
</html>
改变icon的代码
<link rel="icon" href="../favicon.ico" type="image/x-icon">
容器和vue实例一一对应
真实开发中只会有一个vue实例,并且会配合组件使用。
{{属性和js表达式和js代码}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<script src="../JS/vue.js"></script>
<body>
<div class="root">
<h1 >
{{name.toUpperCase()}} {{age}} {{Date.now()}}
</h1>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip=false
new Vue({
el:'.root' ,
data:{
name:'vue'
}
}
)
</script>
</html>
模板语法
插值语法: 标签体内使用{{}}
指令语法: 标签属性使用v-bind:属性=可简写为:属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<script src="../JS/vue.js"></script>
<body>
<div class="root">
<a v-bind:href="url">百度</a>
<a :href="url">百度</a>
<!-- 简写-->
</div>
</body>
<script type="text/javascript">
new Vue({
el:'.root' ,
data:{
url:'http://www.baidu.com'
}
}
)
</script>
</html>
属性分级
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<script src="../JS/vue.js"></script>
<body>
<div class="root">
<h1 >
{{name}} {{obj.name}}
</h1>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'.root' ,
data:{
name:'vue',
obj:{
name: 'ddd'
}
}
}
)
</script>
</html>
数据绑定
v-bind:单向数据绑定,后台数据绑定页面展示值,页面展示值发生改变时,后台数据不会发生改变。
v-model:双向数据绑定。只能运用在表单类元素(输入类元素)。有value值才能绑定到后台数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="../JS/vue.js"></script>
<body>
<div class="root">
单向数据绑定<input v-bind:value="name"><br>
双向数据绑定<input v-model="modelname">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip=false
new Vue({
el:'.root' ,
data:{
name:'单向',
modelname:'双向'
}
}
)
</script>
</html>
el和data的两种写法
el的两种写法
- new Vue的时候配置el属性
- 先创建实例,再使用$mount('xxx’)挂载到实例上去
data的两种写法
- 对象式
- 函数式
注:vue的函数要写出普通函数,不能写箭头函数,否则this不再指向vue实例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="../JS/vue.js"></script>
<body>
<div class="root">
<h1 >{{name}}</h1>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip=false
const v = new Vue({
// el:'.root' //el的第一种写法
// data:{
// name:'zjq'
// }
//data的对象式写法
data:function () {//不能写成箭头函数 必须写成普通函数
return{
name:'zjq'//data的函数式写法
}
}
}
)
console.log(v)
v.$mount('.root')//el的第二种写法
</script>
</html>
MVVM
M:model data中的数据
V:View 视图模板 前端页面
VM:视图模型 VUE实例对象
vue实例对象通过dom listener监听view的变化,通过data binding把数据绑定到model上。
Object.defineProperty
通过这个方法可以修改属性的值,设置属性可否枚举,可否修改,可否删除等。get和set方法在读取和设置值属性时会被调用。通过此方法可实现数据与属性的动态关联。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="../JS/vue.js"></script>
<body>
<div class="root">
</div>
</body>
<script type="text/javascript">
let num = 19
let person = {
name:'zjq',
age:num
}
Object.defineProperty(person,'age',{
// value:18,
// enumerable:true,//控制属性是否可以枚举
// writable:true,//控制属性是否可以修改
// configurable:true,//控制属性是否可以删除
get(){
return num
},
set(value){
num=value
}
// console.log(Object.keys(person))//遍历person的属性
})
</script>
</html>
数据代理
数据代理就是通过一个对象实现对另一个对象中属性的读写。
<script>
let obj1 = {
x:100
}
let obj2 = {
y:200
}
Object.defineProperty(obj2,'x',{
get(){
return obj1.x
} ,
set(v) {
obj1.x=v
}
}
)
</script>
这是最简单的数据代理,Vue也实现了数据代理,我们new的Vue实例对象本身有一个属性叫做_data,和我们在new实例时传入的data属性是一致的。然后vue把传入的属性赋值到自身以便我们可以直接使用,但是_data和data还并不完全一样,_data内部做了数据劫持以便监听data中数据的修改同时更新页面数据。
事件处理
- 使用v-on:click(可以是任何事件名)或者@xxx绑定事件。
- 事件回调需要配置在methods当中最后会加在vm身上,但是method中的方法不做数据代理,数据代理的目的是为了监控数据的修改,而方法不需要做修改。
- methods中的函数不要用箭头函数,否则this不再是vue实例。
- 如果不传参就直接写函数名不加括号,默认第一个参数时event事件。传参就加(参数名)直接接收参数,可以用$event接收事件。
事件修饰符
@wheel=“gun” 鼠标滚轮滚动事件
@scroll=“ha” 滚动条滚动事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="../JS/vue.js"></script>
<body>
<style>
#box1{
padding: 10px;
height: 50px;
background-color: aqua;
}
#box2{
padding: 5px;
height: 20px;
background-color: blue;
}
#box3{
height: 300px;
background-color: brown;
overflow: auto;
}
li{
height: 100px;
}
</style>
<div class="root">
<a href="http://www.baidu.com" @click.prevent="showInfo" >baidu</a>
<!-- prevents就是阻止默认事件发生-->
<!-- a标签的默认事件是跳转指定网页-->
<!-- 这时候加上事件修饰符,默认事件就被阻止了-->
<!-- 只发生showInfo函数中的内容-->
<div @click="showInfo">
<button @click.stop="showInfo" >baidu</button>
<!-- 阻止事件冒泡-->
<!-- 在a标签的父元素身上也有一个点击事件,当a标签被点击时,div的点击事件也会被触发,先发生a标签的事件再发生div的事件-->
<!-- stop就是阻止父元素即div身上的点击事件-->
</div>
<button @click.once="showInfo" >点击一次</button>
<div id="box1" @click.capture="showMsg(1)">
<!--捕获事件-->
<!-- 事件发生的顺序是先捕获再冒泡,也就是说他从外向内依次捕获showMsg(1)和showMsg(2)-->
<!-- 然后事件发生的顺序是从内向外依次发生-->
<!-- capture就是在事件捕获时就发生-->
div1
<div id="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 只有事件的target是本身时点击事件才发生 从某种程度上也可以阻止事件冒泡-->
<div class="box1" @click.self="showInfo">
div1
<div class="box2" @click="showInfo">
div2
</div>
</div>
<!-- 正常的执行顺序是先执行回调函数再执行默认事件 .passive可以先执行默认事件同时执行回调函数 提高程序响应速度 但是比较少用-->
<div id="box3" @wheel="gun" @scroll.passive="ha">
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
</div>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'.root' ,
methods:{
showInfo(e){
// alert("同学你好!")
console.log(e.target)
},
showMsg(num){
console.log(num)
},
gun(){
for (let i = 0; i <10000 ; i++) {
console.log("@")
}
},
ha(){
console.log("1")
}
}
}
)
</script>
</html>
键盘事件
<div>
<input @keyup.enter="showMsg">
</div>
showMsg(e){
console.log(e.target.value)
}
注意事项:
- 如果函数只接收一个默认参数event那是不需要加()的,比如@keyup.enter=“showMsg()”,否则会报错。
- 像CapsLcok这种由两个单词组成的键盘需要使用@keyup.caps-lock="showMsg"来绑定事件
- tab键使用keyup是绑定不上去的,因为tab本身按下就会切换事件焦点,所以tab需要绑定keydown事件