一、ES6常用语法
1、变量的定义
1. 介绍
ES6以前 var关键字用来声明变量,无论声明在何处都存在变量提升这个事情,会提前创建变量。
作用域也只有全局作用域以及函数作用域,所以变量会提升在函数顶部或全局作用域顶部。
let 关键字表示变量,const 表示常量。都是块级作用域,比如一个函数内部,代码块{}内部~ 不会报错:(但是会显示undefined)
<script>
console.log(age);
var age = 18;
</script> <script>
function f() {
console.log(age);
if(1){
var age = 1;
}
}
</script> 会报错:
<script>
console.log(age);
</script> 2. let:块级作用域,let定义的变量只能作用于一对花括号内{} 会报错:
<script>
console.log(age);
let age = 18;
</script> <script>
function f() {
console.log(age);
if (1) {
let age = 1;
}
}
f()
</script> 不会报错:
<script>
let age = 18;
console.log(age);
</script> <script>
function f() {
if (1) {
let age = 1;
console.log(age);
}
}
f()
</script> 3. 修改
var:可以重新定义,也可以重新赋值
let:不可以重新定义,但可以重新赋值
const:不可以重新定义,也不可以重新赋值 不会报错:
<script>
var age = 18;
var age = 20;
</script> <script>
var age = 18;
age = 20;
</script> <script>
let age = 18;
age = 20;
</script> 会报错:
<script>
let age = 18;
let age = 20;
</script> <script>
const age = 18;
const age = 20;
</script> <script>
const age = 18;
age = 20;
</script>
2、模板字符串
1. 语法:反引号``
2. 变量:${}
3. 相对于普通字符串:模板字符串可以换行,变量可以使用${}来替换
4. 示例
<body>
<div id="app"> </div> <script>
// 给div添加HTML代码
let ele = document.getElementById("app");
let hobby1 = "抽烟";
let hobby2 = "打架";
let hobby3 = "看女主播";
ele.innerHTML = `<ul>
<li>${hobby1}</li>
<li>${hobby2}</li>
<li>${hobby3}</li>
</ul>`
</script>
</body> 如果使用普通的字符串:不可以换行,变量不能放在引号里面,因为在引号里面会被解析成普通字符而不是变量
ele.innerHTML = "<ul><li>" + hobby1 + "</li></ul>"
3、箭头函数
1. 介绍
类比Python的匿名函数 2. this
-- 普通函数的this取决于函数最近的调用者
-- 箭头函数的this取决于当前上下文的环境 3. 箭头函数示例
3-1、
ES6中允许使用“箭头”(=>)定义函数
var f = a => a;
相当于
var f = function( a ) {
return a;
} 3-2、无参数的箭头函数
var f = () => 10;
相当于
var f = function() {
return 10;
} 3-3、有参数的箭头函数
var sum = (a, b) => a + b;
相当于
var sum = function(a, b) {
return a +b;
} 4. this是谁
<script>
// 普通函数的this取决于函数最近的调用者
// 箭头函数的this取决于当前上下文的环境 // 普通函数
function aa() {
console.log(this)
} aa(); // aa这个函数最近的调用者是window,this是window let obj1 = {
a: 1,
func: aa
}
obj1.func(); // aa这个函数最近的调用者是obj1,this是obj1 let obj2 = {
obj1: obj1,
a: 2
}
obj2.obj1.func(); // aa这个函数最近的调用者是obj1,this是obj1 // 箭头函数
let fun2 = () => this;
console.log(fun2()) // 这个箭头函数是在window下调用的,this是window
</script>
4、数据的解构(相当于python的*args, **kwargs)
1. 解构对象 let {key, key} = obj
<script>
// 定义对象
let obj = {
a: 1,
b: 2,
x: 3,
y: 4
}; // 解析对象
let {x, y} = obj; console.log(x); // 3
console.log(y); // 4
</script> 2. 解构数组 let [x, y, x] = array
<script>
// 定义数组
let hobby = ["吹牛", "泡妞", "打架"]; // 解析数组
let [hobby1, hobby2, hobby3] = hobby; console.log(hobby1); // 吹牛
console.log(hobby2); // 泡妞
console.log(hobby3); // 打架
</script>
5、类的定义:ES6中已经开始支持使用class定义类
1. 定义类:class
2. 构造方法:constructor(相当于python中__init__)
3. 没有self,只有this,this代表这个类本身
4. 继承使用关键字:extends
5. 继承后的子类没有this,需要用super方法来找到父类的this 6. 例子
<script>
class Animal {
// 初始化
constructor(){
// 设置一个属性名为type
this.type = "animal"
};
// say方法
say(){
console.log("FFFFFUUUU")
}
};
// 狗类继承动物类
class Dog extends Animal {
// 子类没有this
constructor(){
// 用super方法拿到父类的this
super();
// 修改属性type的值
this.type = "dog"
}
// 重写say方法
say(){
console.log("wow wow wow")
}
}
let animal = new Animal();
console.log(animal.type); // animal
animal.say() // FFFFFUUUU let dog = new Dog();
console.log(dog.type); // dog
dog.say() // wow wow wow
// 如果Dog类没有重写say方法,那么则会使用父类的say方法
</script>
6、import export
1. 介绍
在ES6中,import 导入模块、export导出模块
一个js文件可以导入另一个js文件的变量,但是目前浏览器并不支持这种语法,
不过在后面会讲到 打包 ,打包后就可以使用,现在演示一下语法(目前没有打包,会报错的,这里只是演示语法) 2. aa.js
let name = "xiaoming";
let age = 18;
// export抛出变量,其他js文件就可以导入这些抛出的变量
export {name, age} 3. index.js
// import导入aa抛出的变量
import {name, age} from "aa" console.log(name)
console.log(age) 4. HTML文件
<script src="index.js"></script>
二、Vue初识
1、Vue框架介绍
Vue是一个构建数据驱动的web界面的渐进式框架。
目标是通过尽可能简单的API实现响应式的数据绑定和组合的视图组件。
使用Vue需要引入相应的JS文件,可到官网下载或者直接使用CDN:https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js
借鉴后端的MVC架构模式: Model数据 Views模板 Controler数据与模板交互的控制器
Vue是MVVM架构:Model数据 View模板 ViewModel为模板提供处理好的数据
主要思想是数据驱动视图
从获取DOM渲染DOM的操作中解脱出来
2、Vue常用指令
1. 介绍
Vue的指令directives很像我们所说的自定义属性,指令是Vue模板中最常用的功能,
它带有v-前缀,功能是当表达式改变的时候,相应的行为作用在DOM上。 两种获取数据方式:
1. {{数据}}
{{name}} 获取数据name 2. v-..="数据"
<h3 v-text="age"></h3> 2. demo
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-type" charset="utf-8">
<title>Title</title>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head> <body>
<div id="app">
<!--使用Vue的数据name-->
{{name}}
</div> <script>
// 实例化一个Vue对象,其中el必须要有
const app = new Vue({
el: "#app", // el表示这个Vue对象的作用域是id为app的这块,无论app这块嵌套了多少个div,都可以使用这个对象
data: { // data存放数据
name: "小明",
} })
</script> </body>
</html> 上面代码相当于:
let ele = document.getElementById("app");
ele.innerText = "小明";
3. v-text:相当于innerText
<body>
<div id="app">
<h3 v-text="name"></h3>
<h3 v-text="age"></h3>
</div> <script>
const app = new Vue({
el: "#app",
data: {
name: "狗明",
age: 18,
} })
</script>
</body>
4. v-html:相当于innerHtml
<body>
<div id="app">
<h3 v-text="name"></h3>
<h3 v-text="age"></h3>
<div>
<div v-html="hobby">
</div>
</div>
</div> <script>
const app = new Vue({
el: "#app",
data: {
name: "狗明",
age: 18,
hobby: `<ul>
<li>泡妞</li>
<li>打架</li>
</ul>
`
}
})
</script>
</body>
5. v-for
<body>
<div id="app">
<ul> <!--循环的索引是位置参数,在第二位,用什么变量名接收都可以-->
<!--key为了唯一标识这个循环的每个循环体,避免后续太多循环后可能出现的错乱,一般让key等于index,且key是唯一的-->
<li v-for="(course, index) in course_list" :key="index">{{course}}{{index}}</li>
</ul> <ul> <!--拿到的每个元素p是一个对象类型(字典),JS中可以使用点去取值-->
<li v-for="(p, index) in people" :key="index">{{p.name}}{{p.age}}</li>
</ul> <ul> <!--若循环的是对象,那么第一个参数是值,第二个参数是键 -->
<li v-for="(val, key) in obj" :key="key">{{val}}, {{key}}</li>
</ul>
</div> <script>
const app = new Vue({
el: "#app",
data: {
course_list: ["语文", "数学", "英语"],
people: [
{
name: "小明",
age: 18
},
{
name: "狗明",
age: 38
}
],
obj: {
dic: "对象",
tup: "元组"
}
}
})
</script>
</body>
6. v-bind 动态绑定属性 简写直接冒号 :
<div id="app">
<!--完整语法-->
<a v-bind:href="baidu">百度</a>
<img v-bind:src="imgUrl"/> <!--缩写-->
<a :href="baidu">百度</a>
<img :src="imgUrl"/>
</div> <script type="text/javascript">
const app= new Vue({
el: '#app',
data: {
baidu: 'http://www.baidu.com',
imgUrl: 'https://xxx.png'
},
})
</script>
v-bind的两种写法
<body>
<style>
.my_style {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style> <div id="app">
<!--v-bind动态绑定class样式 my_style,is_show控制样式是否应用上-->
<div v-bind:class="{my_style: is_show}">
</div>
<!--v-bind的简写-->
<img :src="my_src">
</div> <script>
const app = new Vue({
el: "#app",
data: {
is_show: true,
my_src: "https://pic.cnblogs.com/avatar/1449477/20180725103023.png"
}
})
</script>
</body>
7. v-on 绑定事件 简写直接 @
<body>
<div id="app">
<!-- v-on绑定事件 v-on:事件="methods里面的方法名"-->
<button v-on:click="my_click">屠龙宝刀点击就送</button>
<!-- v-on绑定事件简写 -->
<button @click="game('天龙八部')">玩游戏</button>
<!-- v-on一次绑定多个事件,v-on="{事件1: 方法名1, 事件2: 方法名2}" -->
<button v-on="{mouseenter: my_enter, mouseleave: my_leave}">鼠标事件</button>
</div> <script>
const app = new Vue({
el: "#app",
data: {
},
methods: {
my_click: function(){
alert("屠龙宝刀");
},
game: function(gg){
alert("玩"+gg);
},
my_enter: function () {
console.log("mouse enter")
},
my_leave: function () {
console.log("mouse leave")
},
}
})
</script>
</body>
8. v-if v-else-if v-else:是使用appendChild实现的,只有符合条件的才会塞到html页面上,不符合条件的不会生成html代码
<body>
<div id="app">
<div v-if="role == 'admin'">管理员</div>
<div v-else-if="role == 'hr'">HR</div>
<div v-else>不是人</div>
</div> <script>
const app = new Vue({
el: "#app",
data: {
role: "admin"
}
})
</script>
</body>
9. v-show:是使用display实现的,不显示的html代码只是用display: none隐藏起来了
<body>
<div id="app">
<div v-show="admin">管理员</div>
<div v-show="hr">HR</div>
<div v-show="others">不是人</div>
<button @click="my_click">点击显示或隐藏</button>
<h2 v-show="is_show">嘿嘿</h2>
</div> <script>
const app = new Vue({
el: "#app",
data: {
admin: true,
hr: false,
others: false,
is_show: false,
},
methods: {
my_click: function(){
this.is_show = !this.is_show
}
}
})
</script>
</body>
10. v-model 数据的双向绑定
-- input
-- textarea
-- select
<body>
<div id="app">
<!--lazy失去焦点时才更新,trim去空格-->
<input type="text" v-model.lazy.trim="username">
{{username}}
<pre>{{username}}</pre>
<hr>
<!--number:输入数字时,把数据转为数字类型-->
<input type="text" v-model.lazy.number="phone">
{{phone}}
{{typeof phone}}
<textarea name="" id="" cols="30" rows="10" v-model="article"></textarea>
{{article}} <select name="" id="" v-model="choices" multiple>
<option value="1">小明</option>
<option value="2">狗明</option>
<option value="3">番薯明</option>
</select>
{{choices}}
</div>
<script>
const app = new Vue({
el: "#app",
data: {
username: "", // 这里设置默认值
phone: "",
article: "",
choices: ["1"],
}
})
</script>
</body>
11. 指令修饰符
-- .lazy:失去焦点时才获取数据,默认是内容改变就获取
-- .number: 当输入的数据是数字时,转为数字类型
-- .trim:去空格 12. 自定义的指令
Vue.dirctive("指令名称", function(el, binding){
el 绑定指令的标签元素
binding 指令的所有信息组成的对象
binding.value 指令绑定数据的值
binding.modifires 指令修饰符
})
binding对象的参数:
def: {bind: ƒ, update: ƒ}
expression: "posed" // 绑定的数据名
modifiers: {right: true, top: true} // 修饰符的值
name: "pos" // 指令名称
rawName: "v-pos.right.top" // 指令带修饰符
value: true // 绑定的数据posed的值
__proto__: Object
12-1. 自定义指令控制某个div元素的位置
<body>
<style>
.my_box {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style> <div id="app">
<div class="my_box" v-pos.right.top="posed"> </div>
</div> <script>
// 第一个参数:指令名称
// 第二个参数绑定一个回调函数
// 函数中el是我们绑定指令的标签元素
// binding是绑定这个指令的一些数据
// modifiers(对象):指令修饰符组成的对象的布尔值right top
// value:绑定的数据posed
Vue.directive("pos", function(el, binding) {
console.log(el);
console.log(binding);
let gps = binding.modifiers;
if (binding.value){
el.style.position = "fixed";
// el.style.right = 0;
// el.style.bottom = 0;
for(let posi in gps){
el.style[posi] = 0;
} }
});
const app = new Vue({
el: "#app",
data: {
posed: true
}
})
</script>
</body>
12-2. 自定义模仿v-text原理
<body>
</style> <div id="app">
<h2 v-my_text="name"></h2>
</div> <script>
Vue.directive("my_text", function(el, binding){
el.innerText = binding.value;
}) const app = new Vue({
el: "#app",
data: {
name: "小明"
}
})
</script>
</body>
三、Vue常用指令补充
1、在Vue中获取DOM
1、在Vue中获取DOM
1. 给要获取的HTML标签设置一个 ref="name" 属性
2. 在Vue中通过 $refs.name 获取到这个DOM元素
3. 示例
<body>
<div id="app">
<div ref="my_div"></div>
<button v-on:click="my_click">点击显示文本</button>
</div> <script>
const app = new Vue({
el: "#app",
methods: {
my_click: function() {
// 找到这个DOM对象(vue实例里面的this都是代表这个实例,这里是app)
let ele = this.$refs.my_div;
// 给这个div添加文本
ele.innerText = "嘿嘿嘿!惊喜吧!"
}
}
})
</script>
</body>
2、计算属性
1. computed存放需要计算的数据,键对应函数,通过return把计算结果赋值给 键 ,在HTML页面上就可以使用{{键}}获取结果
2. computed计算出来的数据会放入缓存,同时会一直监听用于计算的各个数据,当数据变化时,会重新计算并得出结果。
3. 示例
<body>
<div id="app">
<table>
<thead>
<tr>
<th>科目</th>
<th>成绩</th>
</tr>
</thead>
<tbody>
<tr>
<td>语文</td>
<td><input type="text" v-model.number="Chinese"></td>
</tr>
<tr>
<td>数学</td>
<td><input type="text" v-model.number="meths"></td>
</tr>
<tr>
<td>英语</td>
<td><input type="text" v-model.number="English"></td>
</tr>
<tr>
<td>总分</td>
<td>{{sum}}</td>
</tr>
<tr>
<td>平均分</td>
<td>{{avg}}</td>
</tr>
</tbody>
</table>
</div> <script>
const app = new Vue({
el: "#app",
data: {
Chinese: "",
meths: "",
English: ""
},
computed: {
sum: function() {
return this.Chinese + this.meths + this.English
},
avg: function() {
return this.sum/3
}
}
})
</script>
</body>
3、数据的监听
1. 监听数据用watch
2. watch里面的每个键就是要监听的数据,handler对应一个函数,参数val是新的值,oldVal是原本的值
3. 在可变数据类型中,val和oldVal都是修改后的数据,因为可变数据类型修改的是原本的值,而不是生成新的值。
4. watch能直接监听到数组长度的变化
5. 但是监听不到数组的某个值发生改变,也就是说,数组只是改变了某个值是不会触发watch的,深度监听也监听不到
6. 想要在数组不改变长度,只改变某个值的时候监听就需要用: Vue实例.$set(某个数组, 索引, "新值");
7. 对象(字典)的某个值发生改变,使用深度监听可以监听得到
8. 对象(字典)增加一些键值对,使用深度监听也监听不到,但是使用:Vue实例.$set(某个对象, 键, "新值"); 可以监听到
9. 示例
<body>
<div id="app">
{{name}}
<br>
{{hobby}}
<br>
{{girl}}
<br>
<button @click="my_click">点我改变数据</button>
</div> <script>
const app = new Vue({
el: "#app",
data: {
name: "小明",
hobby: ["泡吧", "打劫", "碰瓷"],
girl: {
name: "小凤姐",
age: 48
}
},
methods: {
my_click: function() {
// 修改数据
// this.name = "狗明"; // 数组长度发生了变化,触发watch
//this.hobby.push("*"); // 数组长度不变,某个值改变了,不会触发watch
//this.hobby[0] = "狗子"; // 全局的$set,相当于修改完后会去告诉Vue实例一声,可以触发watch
// app.$set(this.hobby, 0, "狗子"); // 修改对象某个值,深度监听就能触发watch
// this.girl.age = 58; // 增加对象内容,需要全局的$set
// this.girl['sex'] = 'boy'; // 监听不到
app.$set(this.girl, "sex", "boy");
}
},
watch: {
name: {
handler: function(val, oldVal) {
console.log(val);
console.log(oldVal);
}
},
hobby: {
handler: function(val, oldVal) {
// 改变数组长度的时候,新旧值相同
console.log(val);
console.log(oldVal);
},
// 深度监听
deep: true
},
girl: {
handler: function(val, oldVal) {
// 改变数组长度的时候,新旧值相同
console.log(val);
console.log(oldVal);
},
// 深度监听
deep: true
}
}
})
</script>
</body>