Day1.
1.安装环境:安装node、webstorm,注册git
2.学习ES6.0新特性
let变量声明特性
(1)变量不可重复声明
(2)块级作用域,只在代码块中有效
(3)不存在变量提升 即不可在变量声明之前使用变量
(4)不影响作用域链 当前找不到会向上级寻找
const声明常量
(1)必须赋初始值
(2)一般使用大写
(3)常量值不能修改
(4)块级作用域
(5)对于数组和对象的元素修改不算做对常量的修改,不会报错(以下操作不算修改,因为const指向的地址未改变)
const TEAM=["12","sa","bdhiew"];
TEAM.push("dw");
解构赋值
ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值
1.数组的解构:数组解构时数组的元素是按次序排列的,变量的取值由位置决定
const F1=["a","b","c","d"];
let [A,C,B,D]=F1;
console.log(A) a
console.log(B) c
console.log(C) b
2.对象的解构:对象解构时对象的属性时没有次序的,变量必须与属性同名才能取得正确的值
let chen={
name:chenduoduo,//此处name、age为变量,变量名必须与属性名相同
age:es,
activity:
}={
name:"Chen",//此处name、age为属性
age:18
}
模板字符串
1.声明
引入新的声明字符串的方式—反引号
let str= 这是一串字符串
2.内容中可以直接出现换行符不会报错
3.可以直接进行变量拼接 拼接格式: ${变量}
let name=`陈朵朵`
let who=` ${name} 今年18岁`
console.log(who) / / 陈朵朵今年18岁
ES6简化对象写法
let name=`陈朵朵`;
let sayHi = function(){
alert("陈朵朵同学你好");
}
const chen={
name:name,
sayHi:sayHi,
sayName:function(){
alert(`吴彦霖`);
}
可缩写为
const chen={
name,
sayHi,
sayName(){
alert(`吴彦霖`);
}
} 等价于
Day2.
1.搭建项目环境
2.学习ES6.0新特性
ES6允许使用箭头=>定义函数
声明函数
let fn=function(a,b){
return a+b;
} 可写为
let fn=(a,b)=>{
return a+b;
}
调用函数
```javascript
let sum=fn(1,3);
console.log(sum); //4
箭头函数适用场景:
适合与this无关的回调、定时器、数组的方法回调
不适合与this有关的场景如don元素的事件回调,对象的方法
特性:
1.this是静态的,始终指向函数声明时所在作用域下的this值
2.不可作为构造函数实例化对象
3.不可使用arguments变量(arguments变量用于构造函数中保存实参)
4.箭头函数的简写
(1)省略小括号:形参有且只有一个
let add=(n)=>{
return n+n;
}
可改写为
let add =n=>{
return n+n
}
(2)省略{}:当代码体只有一条语句时可省略{},此时必须省略return,语句执行结果即返回值
let add=(n)=>{
return n*n;
}
可改写为
let add = n => return n*n;
从数组中返回偶数的元素
const arr=[1,26,9,10,100,35];
const result = arr.filter(function(item){
if(item%2==0)
return true;
else
return false;
})可改写为
const arr=[1,26,9,10,100,35];
const result=arr.filter(item=>{
if(item%2= = =0)
return true;
else
return false;
})可改写为
const arr=[1,26,9,10,100,35];
const result=arr.filter(item%2= = =0)
ES6允许给函数参数赋默认值
1.形参赋初始值,具有默认值的参数一般默认靠后
function add(a,b,c)
{
return a+b+c;
}
add(1,2,3) 6
add(1,2) NAN
function add(a,b,c=0)
{
return a+b+c;
}
add(1,2,3) 6
add(1,2) 3
2.与解构赋值结合
ES6引入rest参数用于获取函数的参数用来代替arguments
ES5获取实参:
function data()
{
console.log(arguments)
}
data("陈","朵","朵") //"陈","朵","朵" 返回的是对象
ES6获取参数
function data(...args)
{
console.log(args);
}
data("吴","彦","霖");
扩展运算符 将数组[“ws”,“xw”,“as”]转化为参数序列"ws",“xw”,"as"
let print=function (){
console.log(arguments);
}
tf=["wy","wjk","yyqx"];
print(tf);//返回的参数个数是1
print(...tf);//返回的参数个数是3
应用:
1.数组的合并
const arr1=["cdd","wyl"];
const arr2=["22","angel"];
const mergeArr=[...arr1,...arr2];
2.数组的克隆
const arr1=["cdd","wyl"];
const arr2=[...arr1]
3.将伪数组转为真正的数组
const divs=document.querySelectorAll('div'); //获取所有的div 返回的是伪数组 类型是对象
divArr=[...divs];
Day3
1.学习ES6.0新特性
Symbol数据类型
Symbol是类似于字符串的数据类型
Symbol特点
1.Symbol值是唯一的,用于解决命名冲突
2.Symbol值不可与其他数据进行运算做数据运算
3.Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
创建Symbol
let s1=Symbol();
console.log(s1,typeof(s1)) //Symbol "Symbol"
let s2=Symbol("描述字符串:用于对变量进行描述以便更好理解该变量作用,类比注释");
Symbol应用场景 向对象中添加属性和方法
//已有一个对象S
let S1={
name:"hiwue",
age:171,
sayHi(){
console.log("Hi~");
}
};
//声明一个对象,存放新建方法
let method={
up:Symbol(),//即使S中已有up down也无妨,因为此时的up down 是symbol类型
down:Symbol(),
};
//给S1新增方法
S1[method.up]=function(){
console.log("向上");
}
S1[method.down]=function(){
console.log("向下");
}
let S2={
name:"陈朵朵",
//为S2新增方法
[Symbol('say')]:function(){
console.log("My name is Chen");
},
[Symbol('Cry')]:function(){
console.log("I'm sad");
},
}
Symbol内置值 整体作为对象的属性进行设置
迭代器iterator
可使用for…of…进行遍历 for …of…返回键值,for…in…返回键名
const Arr=['aaa','bbb','ccc'];
for(let v in Arr)
console.log(v);//aaa,bbb,ccc
for(let x in Arr)
console.log(x);//0,1,2
自带iterator的类型:Array,Arguments,Set,Map,String,TypeArray,NodeList
工作原理:
(1)创建一个指针对象指向当前数据结构的起始位置
(2)第一次调用对象的next方法,指针自动指向数据结构的第一个成员
(3)接下来不断调用next方法,指针一直往后移动直到指向最后一个成员
(4)每调用一次next方法就会返回一个包含value和done属性的对象 done表示是否遍历完成
迭代器应用
需要自定义遍历属性时要想到迭代器
<script>
const student={ //声明一个对象
name:"Zhang",
age:18,
families:["Daddy","Mommy","sister","brother"],
[Symbol.iterator](){ //为student对象新增一个迭代方法
let index=0; //定义一个index索引 根据index决定返回的done为true还是false
let _this=this;
return { //迭代器要求返回一个对象
next:function(){ //迭代器需包含next方法
if(index<_this.families.length)
{
let result= {
value:_this.families[index], //读出families中的数据
done:false
}
index++;
return result; //next()方法必须返回一个含value属性和done属性的对象
}
else
{
return {
value:_this.families[index],
done:true
}
}
}
}
}
}
for(let v of student)
console.log(v);
</script>
生成器函数
解决异步问题,返回的是迭代器,避免回调地狱
定义:
function * 函数名(){
yield 代码1;//yeild语句本身返回值为undefied,当next()传参时会将参数作为上一个yield语句的返回值
yield 代码2;
}
生成器函数需通过迭代器的next()调用
let iterator=生成器函数名();
iterator.next();
生成器函数的应用
1s后输出1111,2s后输出2222,3s后输出3333
<script>
function one()
{
setTimeout( ()=>{console.log("1111");iterator.next();},1000 );
}
function two()
{
setTimeout( ()=>{console.log("2222");iterator.next();},2000 );
}
function three()
{
setTimeout( ()=>{console.log("3333");iterator.next();},3000 );
}
function * print(){ //生成器函数 funtion * 函数名(){函数体}
yield one(); //yield为代码分隔符
yield two();
yield three();
}
let iterator=print() //调用生成器函数
iterator.next() //生成器函数的执行需依靠迭代器的next方法,执行 one()
</script>
next()传参解决异步问题
<script>
function fn1(){
setTimeout( ()=>{let one="one";it.next(one);},1000 );
//第二次调用next(),其参数one将作为上一个yield语句的返回值
}
function fn2(){
setTimeout( ()=>{let two="two";it.next(two)},1000 );
}
function fn3(){
setTimeout( ()=>{let three="three";it.next(three)},1000 );
}
function * gen()
{
let onedata=yield fn1();
console.log(onedata); //返回one 可用于数据操作
let twodata=yield fn2(); //返回two
console.log(twodata);
let threedata=yield fn3();
console.log(threedata);//返回three
}
let it=gen();
it.next(); //第一次调用next
</script>
2.Vue2.0学习
初识Vue
1.想让Vue工作必须建立一个Vue实例且传入一个配置对象
2.Vue实例与容器是一一对应的且真是开发中只会有一个Vue实例并配合组件一起使用
3.{{}}为插值分隔符,其中要写表达式,el用来绑定容器,决定该实例为那个容器所使用;data中存放所有该容器需要用到的数据
4.一旦data中的数据发生改变,页面中用到该数据的地方也会自动更新
模板语法
1.插值语法{{JS表达式}} 用于解析标签体内容,可以直接读取到data中所有属性 {{VM中有的属性以及Vue原型中的数据}}
2.指令语法 用于解析标签,包括标签属性、事件、标签体内容
v-bind: 单项数据绑定属性 data改变即可改变页面 但页面改变不会改变data 可缩写为 :
<body>
<div id="root">
<a v-bind:href="url">点击跳转百度</a> //url被解析为表达式
<button v-on:click="sayHi()">点击打招呼</button>
</div>
</body>
<script>
new Vue({
el:"#root",
data:{
name:"Chen",
age:18,
url:"http://www.baidu.com",
sayHi(){
alert("Hi~");
}
}
})
</script>
v-model:value=“属性” 双向数据绑定 只能应用在表单类元素(输入类元素)中
可缩写为v-model="属性"因为-model默认收集的就是value值
Day4
Vue2.0学习
el和data的两种方式
<body>
<div id="box">
{{name}}
</div>
</body>
<script>
var v=new Vue({ //创建一个Vue实例并用v接收
data(){ //函数式data 不可写成箭头函数
return {
name:"Chen",
age:22,
}
}
})
v.$mount("#box");//将v绑定box,代替el:"#box",使用更灵活
</script>
MVVM模型
M:Model模型 对应data中的数据
V:视图层 对应模板DOM
VM:视图模型 对应Vue实例对象
数据绑定:将Model中的模型绑定到视图层
DOM监听:监听视图层的变化反馈给Model层
ObjectdefineProperty(对象,“属性名”,{属性配置})
<body>
<div id="box">
</div>
</body>
<script>
var year=23;
const vm=new Vue({
el:"#box",
data:{
name:"Chenduoduo"
}
})
// Object.defineProperty(对象名,"属性值",{属性配置项}) 为对象新增属性
// 添加并配置sex属性
Object.defineProperty(vm.$data,"sex",{
//控制属性值
enumerable:true, //控制属性是否参与枚举,默认false
writable:true, //控制属性值是否可改,默认false
configurable:true //控制属性是否可以被删除,默认false
})
console.log(Object.keys(vm.$data)); //获取vm实例的data对象 [name,age,sex]
console.log(vm.$data.sex); //获取vm实例data对象中的sex属性 female
vm.$data.sex="girl";
console.log(vm.$data.sex); //girl
// 添加并配置age属性
Object.defineProperty(vm.$data,"age",{
get(){ //get()函数(getter)当age被使用时get被调用 返回的是age的value值
return year;
}
set(value){ //set(修改后的值) 当有人修改age时set()函数被调用 将value传给year才能真正的修改age
year=value;
}
})
</script>
数据代理
通过一个对象代理对另一个对象中属性的操作称为数据代理
<script>
var obj1={
x:100
}
var obj2={
y:200
}
//通过obj2代理obj1
ObjectdefineProperty(obj2,"x",{
get(){
return obj1.x; //当obj2.x被使用时,返回的是obj1.x
}
set(value){
obj1.x=value //当obj2.x被修改时,修改obj1.x的值
}
})
</script>
Vue中的数据代理:通过vm对象代理data对象中属性的操作
优点:更加方便地操作data中的数据
基本原理:通过Object.defineProperty()将data对象中的所有属性添加到vm中,为每一个添加到vm的属性都指定一个setter/getter,在setter/getter内部操作data中的对应属性 即通过vm代理data
ES6新特性学习
Promise
Day5
Vue
事件的基本使用:
1.使用v-on:xxx或@xxx都可绑定事件,xxx是事件名
2.事件的回调需要在methods对象中,最终会出现在vm上
3.methods中配置的函数不要使用箭头函数,否则this不是vm而是windows
4.methods中配置的函数都是被Vue管理的函数,this指向vm或组件实例对象
5.@click="demo"与@click=“demo(
e
v
e
n
t
)
"
效
果
相
同
,
但
后
者
可
以
传
参
,
形
式
为
@
c
l
i
c
k
=
"
d
e
m
o
(
a
r
g
s
,
event)"效果相同,但后者可以传参,形式为@click="demo(args,
event)"效果相同,但后者可以传参,形式为@click="demo(args,event)”
事件修饰符
修饰符可以连续写
1.prevent :阻止默认事件
<div id="box">
<a href="http://www.baidu.com" @click="showInfo.prevent">点击跳转百度</a>
</div>
//阻止a标签默认点击跳转的事件
<script>
var vm=new Vue({
el:"#box",
methods:showInfo(){
alert("即将跳转转百度");
}
})
</script>
2.stop:阻止事件冒泡
<div id="box">
<div @click="alertInfo">
<button @click.stop="alertInfo">点击弹窗</button> //无stop时由于冒泡会弹窗两次,.stop后无冒泡,外部div的click事件不被触发
</div>
</div>
<script>
var vm=new Vue({
el:"#box",
methods:{
alertInfo(){
alert("Information");
}
}
})
</script>
3.once:事件只触发一次
<div id="box">
<button @click.once="alertInfo">点击弹窗</button>
</div>
<script>
var vm=new Vue({
el:"#box",
methods:{
alertInfo(){
alert("Information");
}
}
})
</script>
4.capture:使用事件的捕获模式,事件在捕获阶段就开始执行,无需等到冒泡阶段
5.self:只有event.target是当前操作的元素时才会触发事件
<div id="box">
<div @click.target="alertInfo">
//无.target时由于冒泡若点击下面的button则此处div的click事件也会被触发,.target后由于此时的event.target=button,所以div的click事件不会被触发,只有点击div时此处的click事件才会被触发
<button @click="alertInfo">点击弹窗</button>
</div>
</div>
<script>
var vm=new Vue({
el:"#box",
methods:{
alertInfo(){
alert("Information");
}
}
})
</script>
6.passive:立即执行事件的默认行为,无需等待事件回调执行完毕 不加则会先执行回调函数再触发默认事件
键盘事件
1.Vue常用按键别名:
回车:enter
删除:delete
退出:esc
空格:space
换行:tab //必须配合keydown使用
上:uo
下:down
左:left
右:right
@keyup.enter=“fn”
@keydown.tab=“fn”
2.Vue未提供别名的按键可以使用原始的key值绑定,双单词组合按键要使用短横线连接
3.系统修饰键:ctrl、alt、shift、meta
配合keydown使用时正常触发事件
配合keyup使用时按下修饰键的同时按下其他键,随后释放其他键事件才会被触发
4.定制按键别名:Vue.config.keyCodes.自定义键名=键码
计算属性
姓:
名:
姓名:
1.通过{{}}实现
<script>
window.onload=function(){
var vm=new Vue({
el:"#root",
data:{
firstName:"陈",
lastName:"朵朵"
}
})
}
</script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"/>
名:<input type="text" v-model="lastName" />
姓名:<span>{{firstName}}-{{lastName}}</span>
</div>
2.通过methods实现
<script>
window.onload=function(){
var vm=new Vue({
el:"#root",
data:{
firstName:"陈",
lastName:"朵朵"
},
methods:{
gn(){
return this.firstName+"-"+this.lastName; //this指向Vue实例
}
}
})
}
</script>
<body>
<div id="root">
姓:<input type="text" v-model="firstName" /><br /> //绑定firstName数据
名:<input type="text" v-model="lastName" /><br /> //绑定lastName数据
姓名:<span>{{gn()}}</span> //通过插值语法获取gn返回值
</div>
</body>
3.通过计算属性实现
计算属性computed,要用的属性不存在,需要通过已有属性计算得到全新的属性,放在computed中,并为此属性建立一个对象并设置get()
计算属性直属于vm,可直接读取使用,若需要修改则必须写set()响应式修改,必须在set中修改所依赖的数据
<script>
window.onload=function(){
var vm=new Vue({
el:"#root",
data:{
firstName:"陈",
lastName:"朵朵"
},
computed:{
name:{ //name也属于vm
get(){ //firstName和lastName改变时,name发生改变
//get作用:当name被读取时,get被调用,且返回值作为name的值
//get什么时候被调用:1.初次读取name时 2.所依赖的数据发生变化时
return this.firstName+"-"+this.lastName; //this指向vm
},
//set什么时候被调用:当name被修改时
set(value){ //当name被修改时,firstName和lastName同时被修改
const arr=value.split("-");
this.firstName=arr[0];
this.lastName=arr[1];
}
}
}
})
}
</script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName" /><br />
名:<input type="text" v-model="lastName" /><br />
姓名:<input type="text" v-model="name" />
</div>
</body>
计算属性的简写
//完整写法:
computed:{
name:{
get(){
return this.firstName+"-"+this.lastName; //this指向vm
},
set(value){
const arr=value.split("-");
this.firstName=arr[0];
this.lastName=arr[1];
}
}
}
//只有确定该计算属性只读不写时,可使用缩写
computed:{
name(){ //此函数当作name.get()使用 name为该计算属性的属性名 使用时直接用name
return this.firstName+"-"+this.lastName;
}
}
<body>
<div id="root">
姓:<input type="text" v-model="firstName" /><br />
名:<input type="text" v-model="lastName" /><br />
姓名:<span>{{name}}</span> //name是vm上的属性,直接使用
</div>
</body>
监视属性
1.利用计算属性更改天气
<script>
window.onload=function(){
var vm=new Vue({
el:"#root",
data:{
isHot:true
},
methods:{
change(){
this.isHot=!this.isHot;
}
},
computed:{
weather(){ //只读的计算属性weather缩写
return this.isHot?"炎热":"寒冷";
}
}
})
}
</script>
</head>
<body>
<div id="root">
<h1>今天天气很{{weather}}</h1>
<button @click="change">切换天气</button>
</div>
</body>
在Vue实例中添加监视
<script>
window.onload=function(){
var vm=new Vue({
el:"#root",
data:{
isHot:true
},
methods:{
change(){
this.isHot=!this.isHot;
}
},
computed:{
weather(){ //只读的计算属性weather缩写
return this.isHot?"炎热":"寒冷";
}
},
watch:{
"isHot":{ //""可省略简写为isHot
immediate:false,//初始化时让handler调用一下,默认false
handler(newValue,oldValue) //当isHot发生改变时handler()被调用
{
console.log("isHot被修改了",newValue,oldValue);
}
},
"weather":{ //计算属性也可被监视
handler(newValue,oldValue) //当weather发生改变时handler()被调用
{
console.log("isHot被修改了",newValue,oldValue);
}
}
}
})
}
</script>
</head>
<body>
<div id="root">
<h1>今天天气很{{weather}}</h1>
<button @click="change">切换天气</button>
</div>
</body>
创建完实例后添加监视
<script>
window.onload=function(){
var vm=new Vue({
el:"#root",
data:{
isHot:true
},
methods:{
change(){
this.isHot=!this.isHot;
}
},
computed:{
weather(){ //只读的计算属性weather缩写
return this.isHot?"炎热":"寒冷";
}
}
})
vm.$watch("isHot",{
immediate:false,//初始化时让handler调用一下,默认false
handler(newValue,oldValue) //当isHot发生改变时handler()被调用
{
console.log("isHot被修改了",newValue,oldValue);
}
})
}
</script>
</head>
<body>
<div id="root">
<h1>今天天气很{{weather}}</h1>
<button @click="change">切换天气</button>
</div>
</body>
深度监视
1.Vue自身可以监测到对象内部值的改变,但Vue提供的watch默认不可以,配置deep:true可以检测对象内部值改变(多层)
2.使用watch时根据数据的具体解构决定是否采用深度监视
监测的简写:当监测时只需配置handler时才可以简写
watch:{
//完整写法
"isHot":{ //""可省略简写为isHot
handler(newValue,oldValue) //当isHot发生改变时handler()被调用
{
console.log("isHot被修改了",newValue,oldValue);
}
}
//缩写
isHot(){
console.log("isHot被修改了",newValue,oldValue);
}
}
//完整写法
vm.$watch("isHot",{
handler(newValue,oldValue) //当isHot发生改变时handler()被调用
{
console.log("isHot被修改了",newValue,oldValue);
}
})
//缩写
vm.$watch("isHot",function(){ //不可写成箭头函数
console.log("isHot被修改了",newValue,oldValue);
})
利用监视实现姓名案例
<body>
<div id="root">
姓:<input type="text" v-model="firstName" /><br />
名:<input type="text" v-model="lastName" /><br />
姓名:<input type="text" v-model="fullName" /><br />
</div>
</body>
<script>
var vm=new Vue({
el:"#root",
data:{
firstName:"Chen",
lastName:"duoduo",
fullName:"Chen-duoduo"
},
watch:{
firstName(newValue){
this.fullName=newValue +"-" +this.lastName;
},
lastName(newValue){
this.fullName=this.firstName +"-" +newValue;
},
fullName(newValue){
var arr=newValue.split("-");
this.firstName=arr[0];
this.lastName=arr[1];
}
}
})
</script>
computed和watch对比:
watch可实现异步任务,computed不可实现异步
watch、computed都能实现时推荐使用computed,需要实现异步任务时使用watch
Tips:1.所有被Vue管理的函数最好写成普通函数,这样this才是vm
2.所有不被Vue管理的函数(定时器的回调函数、ajax的回调函数、Promise的回调函数等)最好写成箭头函数,这样this才能是vm