一、es6的语法

1、let与var的区别

  ES6 新增了let命令,用来声明变量。它的用法类似于var(ES5),但是所声明的变量,只在let命令所在的代码块内有效。如下代码:

{
  let a = 10;
  var b = 1;
}
a // ReferenceError: a is not defined.
b // 1

  上面代码在代码块之中,分别用let和var声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效

  for循环的计数器,就很适合使用let命令,如下代码:

for (let i = 0; i < 10; i++) {
  // ...
}
console.log(i);    // ReferenceError: i is not defined

  上面代码中,计数器i只在for循环体内有效,在循环体外引用就会报错。

2、var变量提升现象,如下代码:
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();   // 10

  上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。如果使用let,声明的变量仅在块级作用域内有效,最后输出的是 6。

3、另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}    // abc// abc// abc

  上面代码正确运行,输出了 3 次abc。这表明函数内部的变量i与循环变量i不在同一个作用域,有各自单独的作用域。

4、let不存在变量提升

  var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined。而let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。如下代码:

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

  上面代码中,变量foo用var命令声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined。变量bar用let命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误。

5、let不允许在相同作用域内重复声明同一个变量,如下代码:
// 报错
function func() {
  let a = 10;
  var a = 1;
}
// 报错
function func() {
  let a = 10;
  let a = 1;
}
6、ES6还添加了const命令,const声明一个只读的常量,一旦声明,常量的值就不能改变,如下:
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.

  const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。也就是说,const只声明不赋值,就会报错。

  const的作用域与let命令相同,即只在声明所在的块级作用域内生效,不能重复声明,并且不存在变量提升。

7、ES6模板字符串

  模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。模板字符串中嵌入变量,需要将变量名写在${}之中。

let name = 'tom';
let str = `我是 ${name}.`
8、变量的解构赋值

  ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

  ES6 允许写成下面这样:

let [a, b, c] = [1, 2, 3];

  上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。

  本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值就等于undefined。

9、函数

  (1)es5的普通函数,function声明函数,如下:

  function add(x) {
    return x;
  };
  add(10);  // 10

  (2)函数对象的写法,如下:

  let add = function (x) {
    return x;
  };
  add(10);  // 10

  (3)es6箭头函数,如下:

  let add = (x) => {    
    return x;
  };
  add(10)   // 10

  (4)上面的箭头函数可简写成如下形式:

  let add = x => x;
  add(10);   // 10

  // 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。如下:
  var sum = (num1, num2) => { return num1 + num2; }

  // 如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。如下:
  let getTempItem = id => { id: id, name: "Temp" };   // 报错
  let getTempItem = id => ({ id: id, name: "Temp" });   // 不报错
10、es6的对象(this指向问题)

(1)匿名函数中this指向

// 字面量方式声明一个对象person
let person = {
    name: "tom",
    age: 30,
    fav: function () {
        console.log(this); // this指向 当前的调用者person对象
        console.log(this.name);
    }
};
person.fav()
// {name: "tom", age: 30, fav: ƒ}
// tom

(2)对象的单体模式,本质与上个示例一样:

let person = {
    name: "tom",
    age: 30,
    fav(){
        console.log(this); // this指向 当前的调用者person对象
        console.log(this.name);
    }
};
person.fav()
// {name: "tom", age: 30, fav: ƒ}
// tom

(3)箭头函数中this指向

let person = {
    name: "tom",
    age: 30,
    fav: () => {
        console.log(this);  // this指向 person的父级对象(上下文),即window
        console.log(this.name);
    }
};
person.fav()
// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
11、es6的类

(1)es5

function Person(name, age) {
    this.name = name;
    this.age = age;
}
// 基于原型给对象声明方法,原型prototype是当前类的父类(继承性)
Person.prototype.showName = function () {
    console.log(this.name);
};

let p1 = new Person('alex', 29);
p1.showName() // alex

(2)es6

class Person{
    constructor(name='alex', age=29){   // 单体模式
        this.name = name;
        this.age = age;
    }
    showname(){   // 单体模式
        console.log(this.name);  // this指向当前对象Person
    }
    showage(){
        console.log(this.age);
    }
}
let p1 = new Person();
p1.showname();  // alex

二、vue的基本语法

1、vue的介绍

(1)前端三大框架(可以去github查看三个框架的 star星)   

  vue     尤雨溪,渐进式的JavaScript框架                                

  react    Facebook公司,里面的(高阶函数 es6)非常多,对初学者不友好           

  angular  谷歌公司,目前更新到6.0,学习angular得需要玩一下typescript

(2)cdn方式引用

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>

(3)下载到本地引用

<script src='./vue.js'></script>

4)库和框架

  上面vue.js文件是一个库,小而精;

  框架是功能比较齐全,像Django,大而全,功能比较多;

5)实例化对象

Vue(1)- es6的语法、vue的基本语法、vue应用示例,vue基础语法

  示例代码:

<script src="./vue.js"></script>
<script>
    // 实例化对象
    new Vue({
        el:"#app",
        // 这里data是一个对象,在后续学习中发现data中一般是一个函数
        data:{
            // 数据属性
            msg1:"黄瓜",
            person:{
                name:"alex"
            },
            msg2:'hello Vue',
        isShow:'True'
        },
        methods:{
            // 该组件中声明的方法
        },
        watch:{
            // 该组件中监听的数据属性
        }
    });
</script>

  注意:如果是我们自己定义的属性和方法,则全部暴露在外面,如果是vue实例对象自己属性和方法,会在前边加一个”$”进行区分。另外,data中有一个观察者Observer,在观察着一些数据是否发生了改变,若改变,则将改变后的值立马渲染到DOM中对应的地方,控制台查看data效果如下图:

Vue(1)- es6的语法、vue的基本语法、vue应用示例,vue基础语法

2、vue的模板语法 
<div >
    <!--模板语法-->
    <h2>{{ msg1 }}</h2>
    <h3>{{ 'haha' }}</h3>
    <h3>{{ 1+1 }}</h3>
    <h4>{{ {'name':'alex'} }}</h4>
    <h5>{{ person.name }}</h5>
    <h2>{{ 1>2?'真的':'假的' }}</h2>
    <p>{{ msg2.split('').reverse().join('') }}</p>
</div>
3、vue的思想

  数据驱动视图,设计模式MVVM(model view viewmodel)

4、vue的基本指令(使用指令系统后边一定是字符串,且字符串中的变量一定是数据属性中已有的变量)

(1)vue的指令系统之v-text和v-html(***),如下:

<div >
    {{ msg }}
    <div v-text="msg"></div>    <!-- v-text相当于innerText -->
    <div v-html="msg"></div>    <!-- v-html相当于innerHTML -->
</div>
<script src="./vue.js"></script>
<script>
    // 实例化对象
    new Vue({
        el:"#content",
     // data中是一个函数 函数中return一个对象,可以是空对象,但不能不return
        data(){       // 函数的单体模式
            return{
                msg:"<h2>alex</h2>"
            }
        }
    });
</script>

  效果如下图:

Vue(1)- es6的语法、vue的基本语法、vue应用示例,vue基础语法

2)条件渲染v-if和v-show,如下:效果如下图:

  <div class="box1" v-show="isShow">hello</div>
  <div class="box2" v-if="isShow">hello</div>

  分析:isShow为真则显示div,为假则不显示;

  区别:v-show为假时相当于display:none;v-if为假时相当于移除该div,但是有一个占位的注释”<!-- -->”;

  官网对v-if和v-show的区别:

    1)v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

    2)v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

    3)相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

    4)一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

  v-if与v-else:可以使用 v-else 指令来表示 v-if 的“else 块”:

<div v-if="Math.random() > 0.5">
   Now you see me
</div>
<div v-else>
   Now you don't
</div>
// 注意:v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

(3)v-bind和v-on

  v-bind:标签中所有属性,如img标签的src alt,a标签的href title id class等,如下:

  <img v-bind:src="imgSrc" v-bind:alt="msg">

  v-bind:class='{active:isActive}'表示若isActive(数据属性中定义的变量)为真,则对应div增加active类,否则不增加,如下:

  <div class="box" v-bind:class='{active:isActive}'></div>

  v-on:监听js中的所有事件,如click,mouseover,mouseout等,如下:

  <button v-on:click="clickHandler">切换颜色</button>

  v-bind的简便写法是":",如:<div class="box" :class='{active:isActive}'></div>

  v-on的简便写法是"@",如:<button @click="clickHandler">切换颜色</button>

(4)列表渲染v-for(不仅可以遍历数组,还可以遍历对象),如下:

<div >
    <ul v-if="res.status === 'ok'">
        <!-- v-for的优先级是最高的  diff算法 -->
        <li v-for='(item,index) in res.users' :key="item.id">
            <h3>{{ item.id }} -- {{ item.name }} -- {{ item.age }}</h3>
        </li>
    </ul>
    <div v-for='(value,key) in person'>
        {{ key }}-----{{ value }}
    </div>
</div>
<script src="./vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data(){
            return {
                res: {
                    status: 'ok',
                    users: [
                        {id: 1, name: 'alex', age: 18},
                        {id: 2, name: 'wusir', age: 30},
                        {id: 3, name: 'yuan', age: 48}
                    ]
                },
                person: {
                    name: 'tom'
                }
            }
        },
        methods:{
            // 该组件中声明的方法
        },
        watch:{
            // 该组件中监听的数据属性
        }
    });
</script>

  总结:遍历数组时,一个参数是值,两个参数是(值,索引);遍历对象时,一个参数是值,两个参数是(值,键)。

  注意:一定要绑定一个标识(有id就绑定id,没有id绑定index),则值改变会直接通过key查找,而不用再去遍历查找,提升效率。

Vue应用示例

1、实现轮播图,代码如下:
<div >
    <img :src="images[currentIndex].imgSrc" @click="imgHandler" alt="">
    <br />
    <button @click="prevHandler">上一张</button>
    <button @click="nextHandler">下一张</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    // Vue实例对象,可以有返回值vm,官网中就是用vm代表Vue实例对象
    let vm = new Vue({
        el: '#app',
        data() {
            return {
                // 实际项目中images这个数据以及图片是后端返回过来的
                images:[
                    {id:1, imgSrc:'./images/1.jpg'},
                    {id:2, imgSrc:'./images/2.jpg'},
                    {id:3, imgSrc:'./images/3.jpg'},
                    {id:4, imgSrc:'./images/4.jpg'}
                ],
                currentIndex:0
            }
        },
        methods:{
            nextHandler(){
                this.currentIndex++;
                if(this.currentIndex == 4){
                    this.currentIndex = 0;
                }
            },
            prevHandler(){
                this.currentIndex--;
                if(this.currentIndex == -1){
                    this.currentIndex = 3;
                }
            },
            imgHandler(e){
                console.log(e);  // e是当前事件对象
                console.log(e.target);  // 当前事件对象的目标对象
                console.log(this);  // this指当前Vue实例对象
            }
        },
        // 组件创建完成时调用created函数,可发送ajax
        created(){
            // 注意:开定时器就要清定时器,后面会介绍在destroyed函数中清掉
            setInterval(()=>{
                // 定时器中若不用箭头函数则this指则定时器对象
                console.log(this);  // 这时this指当前Vue实例对象
                this.currentIndex++;
                if(this.currentIndex == 4){
                    this.currentIndex = 0;
                }
            },2000);

            // 若定时器中不用箭头函数,也可以用下面方式
            let _this = this;
            setInterval(function () {
                console.log(_this);   // _this指当前Vue实例对象
            },2000)
        }
    })
</script>
示例代码

相关文章: