🥔:成功之后就能光明正大地回望所有苦难
VUE-Day1
- Vue简介
- 1、Vue是什么?
- 2、谁开发的? 发展历程?
- 3、Vue的特点
- 4、容器和实例、实例中的el和data
- 总结
- Vue模板语法
- 插值语法
- 指令语法
- 数据绑定
- 1.单向数据绑定(v-bind)
- 2.双向数据绑定(v-model)
- el和data的两种写法
- 1、el的两种写法
- 2、data的两种写法
- MVVM
- 数据代理
- Object.defineProperty方法
- 数据代理
- Vue中的数据代理
- 事件处理
- 事件处理
- 事件修饰符
- 键盘事件
- 补充两个小技巧
- 补充两个小技巧
Vue简介
1、Vue是什么?
官网说法:Vue是一套用于构建用户界面的渐进式JavaScript框架。
- 构建用户界面:数据—>界面
- 渐进式:Vue可以自底向上逐层的应用
Vue官网:
英文官网: https://vuejs.org/
中文官网: https://cn.vuejs.org/
2、谁开发的? 发展历程?
Vue是尤雨溪开发的。
3、Vue的特点
-
采用组件化模式,提高代码复用率,且让代码更好维护。
一个.vue就是一个组件
-
声明式编码,让编码人员无需直接操作DOM,提高开发效率。
- 使用虚拟DOM+优秀的Diff算法,尽量复用DOM节点。
4、容器和实例、实例中的el和data
- el: 用来指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
- data: 用来存储数据,数据给el指定的容器所使用,注意,一旦data中的数据发生更改,Vue模板就会重新解析,这样页面中用到data的地方都会自动更新。data的值可以写成对象,也可以写成函数(后面组件会讲)。
总结
-
想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象。
-
root容器里代码依然符合HTML规范,只不过混入了一些特殊的Vue语法。
-
root容器里的代码被称为【Vue模板】。
-
Vue容器与与Vue实例是一对一关系,一个容器只能被一个Vue实例接管,一个Vue实例只能接管一个容器。
-
真实开发中只有Vue实例,并且会配合着组件一起使用。
-
{{xxx}}中的xxx要写js表达式(不能写if,for这样的js代码),且xxx可以自动读取到data中的所有属性。
-
一旦data中的数据发生改变,那么模板中用到该数据的地方也会自动更新。
Vue模板语法
插值语法
功能:用于解析标签体内容。也就是插值语法都是写在html标签体内容里的。
写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
指令语法
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件等等)。
举例:v-bind:href="xxx"
或简写为:href=“xxx”
,xxx同样要写js表达式,且可以直接读取到data中的所有属性。
备注:Vue中有很多指令,且形式都为:v-???
,此时仅用v-bind举例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>模板语法</title>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备一个容器 -->
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr />
<h1>指令语法</h1>
<!-- 如果不加"v-bind"或":"的话,url就只是一个普通的字符串,不会跳转 -->
<a href="two.url">{{two.name}}一下</a>
<a v-bind:href="two.url">{{two.name}}一下1</a>
<!-- v-bind可以直接简写成冒号: -->
<a :href="two.url.toUpperCase()">{{two.name}}一下2</a>
<!-- 这个url直接就当成表达式来执行了 -->
</div>
<script type="text/javascript">
new Vue({
el: "#root",
data: {
//此处有两个name,但是有层级结构所以他们不会冲突,但是在前面容器使用时要注意指定好是哪个name
name: "www",
two: {
name: "百度",
url: "https://www.baidu.com/",
},
},
});
</script>
</body>
</html>
数据绑定
1.单向数据绑定(v-bind)
数据只能从data流向页面。
单向数据绑定:<input type="text" v-bind:value="name">
单向数据绑定简写:<input type="text" :value="name">
2.双向数据绑定(v-model)
页面↔data
双向绑定一般都应用在表单类元素上(如:input、select等输入类元素)
v-model:value可以简写为v-model,因此v-model默认收集的就是value值
双向数据绑定:<input type="text" v-model:value="name">
双向数据绑定简写:<input type="text" v-model="name">
el和data的两种写法
1、el的两种写法
1.new Vue时配置el属性。el:‘#demo’
const vm = new Vue({
el: '#demo', //第一种写法,新建Vue实例的时候就指定关联的容器
data: {
name: 'www'
}
})
2.先创建Vue实例,随后再通过vm.$mount(‘#demo’)
指定el属性。
const vm = new Vue({
data: {
name: 'www'
}
})
vm.$mount('#demo'); //第二种写法
- mount:挂载
2、data的两种写法
1.对象式
data: {
name: 'www'
}
2.函数式
data: function () {
return {
name: 'www'
}
}
函数式简写:
data() {
return {
name: 'www'
}
}
- 目前哪种写法都可以,当学到组件时,data必须使用函数式,否则会报错。
- 由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了,而是window。
MVVM
这个模型在Vue之前就有了,尤雨溪只是参考了MVVM,其中:
M:模型(Model):对应data中的数据
V:视图(View):模板
VM:视图模型(View Model):Vue实例对象
- VM就像一个纽带。M(数据)经过VM放到页面(V)上,页面(V)需要映射回M(数据)的数据也经过VM。
- 我们经常会使用vm(ViewModel)这个变量名来表示Vue实例,因此我们使用变量接收Vue实例时一般变量名都叫vm。
总结:
1、data中所有的属性,最后都出现在了vm身上。(这里其实是数据代理,后面会提到)
2、vm身上所有的属性以及Vue原型上所有的属性,在Vue模板上都可以直接使用。
数据代理
Object.defineProperty方法
Object.defineProperty方法会直接在对象上定义一个新的属性,或者修改一个对象的现有属性,然后返回该对象。
比如下面这个案例,我们可以借助这个方法让变量number和person对象中的age产生关联
//回顾Object.defineproperty方法
let number = 18;
let person = {
name: 'www',
sex: '男',
// age: number
}
Object.defineProperty(person, 'age', {
// value: 18,
// enumerable: true, //控制属性是否可以被遍历,默认值是false
// writable: true, //控制属性是否可以被修改,默认值是false
// configurable: true //控制属性是否可以被删除,默认值是false
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
console.log('有人读取age了');
return number;
},
//当有人修改person的age属性时,set函数(setter)就会被调用,且返回值就是age的值
set(val) {
console.log('有人修改age的值,' + val);
number = val;
}
})
console.log(person);
console.log(Object.keys(person));
数据代理
数据代理:通过一个对象代理另一个对象中属性的操作(读/写)
比如下面这个案例,我们可以通过obj2来管理obj1里面的x(读/写)
记住这个案例,后面的理解起来可能会容易些
//数据代理:通过一个对象代理另一个对象中属性的操作(读/写)
let obj1 = { x: 1 };
let obj2 = { y: 2 };
//通过obj2来读取或修改obj1里的x
Object.defineProperty(obj2, 'x', {
get() {
console.log('有人要通过obj2读取obj1里的x');
return obj1.x
},
set(val) {
console.log('有人要通过obj2修改obj1里的x');
obj1.x = val;
}
})
console.log(obj1);
console.log(obj2);
Vue中的数据代理
1、Vue中的数据代理:
通过vm对象来代理data(或者说是_data)对象中属性的操作(读/写)
2、Vue中数据代理的好处:
更加方便的操作data中的数据
3、基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的数据。
其实_data
和data
就是一个东西,这里先理解为_data
是收集了data
中的数据,然后vm对_data
进行数据代理,也就是对data
中的数据进行数据代理,目的只有一个,就是为了编码方便,要不然插值语法每次还得写{{_data.name}}什么的,有了这个数据代理,直接{{name}}就搞定了。
事件处理
事件处理
1、使用v-on:xxx
或@xx
x绑定事件,其中xxx是事件名。
2、事件的回调需要配置在methods对象中,最终会在vm上。
3、methods中配置的函数,不要用箭头函数!否则this就不是vm了。
4、methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象。
5、@click="demo"
和 @click="demo($event)"
效果一致,但后者可以传参。
6、如果不传参,默认第一个形参是事件对象
;如果传参,按照参数顺序来接,如果想接事件对象,要传入$event
关键字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>事件的基本使用</title>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>欢迎,{{name}}</h1>
<!-- <button v-on:click="showInfo">提示信息</button> -->
<button @click="showInfo1">点我提示信息</button>
<button @click="showInfo2(666,$event)">点我提示信息</button>
</div>
<script type="text/javascript">
new Vue({
el: "#root",
data: {
name: "www",
},
methods: {
//这里是可以传多个参数的,如果不传参,默认第一个是事件对象
//如果传参,按照参数顺序来接,如果想接事件对象,要传入$event关键字
showInfo1(event) {
console.log(event.target); //获得当前点击的元素信息
console.log(this); //此处的this是vm
// alert("同学你好!");
},
showInfo2(number, e) {
console.log(number, e);
},
},
});
</script>
</body>
</html>
事件修饰符
1、prevent:阻止默认事件(常用)
2、stop:阻止事件冒泡(常用)
3、once:事件只触发一次(常用)
4、capture:使用事件的捕获模式
5、self:只有event.target是当前操作的元素时才触发事件
6、passive:事件的默认行为立即执行,无需等待事件的回调执行完毕
<!-- 准备好一个容器 -->
<div id="root">
<h2>我的名字叫{{name}}</h2>
<!-- 1.prevent阻止默认事件 -->
<a href="http://www.baidu.com" @click.prevent='hello'>点击提示信息1</a><br>
<!-- 2.stop阻止事件冒泡 -->
<div @click="hello">
<button @click.stop="hello">点击提示信息2</button>
</div>
<!-- 3.once件只触发一次,触发完了就失效 -->
<button @click.once="hello">点击提示信息3</button>
<!-- 4.capture捕获阶段处理事件(默认的是冒泡阶段处理事件) 这个意思就是说外边的div在捕获阶段就处理事件了-->
<div @click.capture="showInfo(1)">111111
<div @click="showInfo(2)">22222</div>
</div>
<!-- 5.self只有event.target是当前操作的元素时才触发事件,也就是冒泡不管用了(类似阻止冒泡?)-->
<div @click.self="hello">111111
<div @click="hello">22222</div>
</div>
<!-- 6.passive事件的默认行为立即执行,无需等待事件的回调执行完毕-->
<!-- 加上这个的话,不用等待creazyShow函数执行完毕,滚动条就可以流畅滚动-->
<ul @wheel.passive="creazyShow">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: 'www',
age: 18
},
methods: {
hello(e) {
// e.preventDefault(); //阻止默认事件的js写法
// e.stopPropagation(); //阻止事件冒泡的js写法
alert('DJ drop the beat');
},
showInfo(val) {
console.log(val);
},
creazyShow() {
for (let i = 0; i < 100000; i++) {
console.log('我输出完了你再滚动');
}
}
}
})
</script>
键盘事件
按键 | 代码 |
---|---|
回车 | enter |
删除 | delete(捕获删除和退格键) |
退出 | esc |
空格 | space |
换行 | tab(特殊,必须配合keydown使用) |
上 | up |
下 | down |
左 | left |
右 | right |
<!-- 准备好一个容器 -->
<div id="root">
<h2>我的名字叫{{name}}</h2>
<input type="text" placeholder="按下回车输出" @keyup.enter="showInfo">
<input type="text" placeholder="按下回车输出" @keyup.13="showInfo">
<input type="text" placeholder="按下回车输出" @keyup.huiche="showInfo">
<input type="text" placeholder="按下删除或退格输出" @keyup.delete="showInfo">
<input type="text" placeholder="按下切换大小写输出" @keyup.caps-lock="showInfo">
</div>
<script>
Vue.config.keyCodes.huiche = 13; //定义一个别名为huiche的enter按键
const vm = new Vue({
el: '#root',
data: {
name: 'www',
age: 18
},
methods: {
showInfo(e) {
// if (e.keyCode !== 13) return //原生js实现按下回车输出值
console.log(e.target.value);
}
}
})
</script>
1、Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
比如我想按下切换大小写的按键就触发showInfo:
<input type="text" placeholder="按下切换大小写输出" @keyup.caps-lock="showInfo">
2、系统修饰键(用法特殊):ctrl、alt、shift、meta
- 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
- 配合keydown使用:正常触发事件。
3、也可以使用keyCode去指定具体的按键(不推荐)
<input type="text" placeholder="按下回车输出" @keyup.13="showInfo">
4、Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
Vue.config.keyCodes.huiche = 13; //定义一个别名为huiche的enter按键
补充两个小技巧
1、修饰符可以连续写
比如先停止冒泡,再阻止默认行为:
<button @click.stop.prevent="showInfo">你好</button>
2、如果先让两个键同时按下才触发,键名也可以连续绑定
比如按下ctrl+y触发showInfo方法:
<input type="text" @keyup.ctrl.y="showInfo">
被触发。
- 配合keydown使用:正常触发事件。
3、也可以使用keyCode去指定具体的按键(不推荐)
<input type="text" placeholder="按下回车输出" @keyup.13="showInfo">
4、Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
Vue.config.keyCodes.huiche = 13; //定义一个别名为huiche的enter按键
补充两个小技巧
1、修饰符可以连续写
比如先停止冒泡,再阻止默认行为:
<button @click.stop.prevent="showInfo">你好</button>
2、如果先让两个键同时按下才触发,键名也可以连续绑定
比如按下ctrl+y触发showInfo方法:
<input type="text" @keyup.ctrl.y="showInfo">