ES-6常用语法和Vue初识

一、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的匿名函数。
箭头函数有两种格式,一种只包含一个表达式,省略掉了{ ... }和return。
还有一种可以包含多条语句,这时候就不能省略{ ... }和return。


2. this
-- 普通函数的this取决于函数最近的调用者
-- 箭头函数的this取决于当前上下文的环境


3. 箭头函数示例
3-1、只包含一个表达式
ES6中允许使用“箭头”(=>)定义函数
var f = a => a;
相当于
var f = function( a )  {
    return a;
}

// 无参数的箭头函数
var f = () => 10;
相当于
var f = function() { 
    return 10;
}


// 有参数的箭头函数
var sum = (a, b) => a + b;
相当于
var sum = function(a, b) {
    return a +b;
}


3-2、可以包含多条语句
var f = (a, b) => {
  a = a + 1;
  b = b + 1;
  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.1、数据的解构(相当于python的*args, **kwargs)

复制代码
1. 解构对象 let {key, key} = obj
// 定义对象
var obj = {
    a: 1,
    b: 2,
    x: 3,
    y: 4
};

// 解析对象
var {x, y} = obj;

console.log(x);  // 3
console.log(y);  // 4


// 解析并重命名变量
var {x: x2, y: y2} = obj;  // 解析出x,y的值,并重命名为x2,y2

console.log(x2);  // 3
console.log(y2);  // 4


2. 解构数组 let [x, y, x] = array
// 定义数组
var hobby = ["吹牛", "泡妞", "打架"];

// 解析数组
var [hobby1, hobby2, hobby3] = hobby;

console.log(hobby1);  // 吹牛
console.log(hobby2);  // 泡妞
console.log(hobby3);  // 打架
复制代码

 

4.2、...三个点解析数组或对象

属于ES6的语法,三个点代表扩展运算符。

复制代码
var person = {
  name: '雕茅',
  age: 250
}
 
var work = {
  job: 'python开发',
  ...person
}
 
// 相当于
var work = {
  job: 'python开发',
  name: '雕茅',
  age: 250
}


// ###############
var school_arr = ["小学", "中学"]

var school_all = [...school_arr, "高中", "大学"]

// 相当于

var school_all = ["小学", "中学", "高中", "大学"]


总结:
...x 解析的变量,如果是对象,那么就要放在 {} 内,如果是数组,那么就要放在 [] 内才能正确解析


还可以在函数定义的地方使用,比如使用func(...args)将函数传入的参数都放到args数组里
// 用在函数定义的地方,只能聚合成为数组
function test(...args){
    console.log(...args)
    console.log(args)
}

test(1,2,3)
test(a=1,b=2,c=3)
// 这两个结果都是一样的
// 1 2 3
// [1,2,3]


test({"x":1}, {"y":2})
// {x: 1} {y: 2}
// [{x: 1}, {y: 2}]
复制代码

 

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. 在标签的html中: {{数据}}
    {{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:相当于innerTex
复制代码
<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 动态绑定属性 简写直接冒号 :
复制代码
v-bind用于绑定数据和元素属性
<div id="app">
    <a v-bind:href="url">百度</a>
</div>  

<div id="app">
    <!--简写-->
    <a :href="url">百度</a>
</div> 

var app = new Vue({
    el:'#app',
    data:{
        url:"https://www.baidu.com",
    }
});

以上代码中,使用v-bind绑定了a标签的href属性,当a标签被点击时,会根据对应vue中的对应的url数据进行跳转到https://www.baidu.com


不止是href属性可以被v-bind指令绑定,任何属性都可以被绑定
<div id="app">
    <a v-bind:href="url" v-bind:class="myclass">百度</a>
    <img v-bind:src="myimg">
</div>

<div id="app">
    <!--简写-->
    <a :href="url" :class="myclass">百度</a>
    <img :src="myimg">
</div>

var app = new Vue({
    el:'#app',
    data:{
        url:"https://www.baidu.com",
        myimg:"xxx.png",
        myclass:"clearfix"
    }
});

绑定的属性,其数据分别对应data里中的数据


用v-bind的绑定的属性的值也可以是一个对象,注意:v-bind:class指令可以与普通的class特性共存。
<style>
    .my_style {
        width: 200px;
        height: 200px;
        border: 1px solid red;
    }
    .you_style {
        color: black;
    }
</style>

<div id="app">
    <div v-bind:class="{'my_style': is_show, 'you_style': active}">我的样式</div>
</div> 


var vm= new Vue({
    el:'#app',
    data:{
        is_show:true,
        active:true
    }
})

这种情况下,只有当对象的值为真才会生效。即 is_show active 为true


也可以直接绑定数据里的一个对象:

<div id="app">
    <div v-bind:class="clsObj">我的样式</div>
</div> 

var vm= new Vue({
    el:'#app',
    data:{
        clsObj:{
            'my_style': true, 
            'you_style': true
        }
    }
})

我们可以把一个数组传给v-bind:class,以应用一个class列表

<div id="app">
    <div :class="[cls1, cls2]">我的样式</div>
</div> 


var vm= new Vue({
    el:'#app',
    data:{
        cls1: "my_style", 
        cls2: "you_style"
    }
})


如果想根据条件切换列表中的class,可以用三目运算

<div id="app">
    <div :class="[isTrue ? cls1 : '' , cls2]">我的样式</div>
</div> 


var vm= new Vue({
    el:'#app',
    data:{
        cls1: "my_style", 
        cls2: "you_style",
        isTrue: false
    }
})
这里判断 isTrue 的boolean值,如果为true,则渲染 cls1;
如果为false,则不渲染。
cls2 没有做三目运算,所以是始终显示的

对于多个class,还可以这么写:
<div :class="[cls1, { cls2: is_show_2, cls3: is_show_3 }]">


绑定内联样式
v-bind:style 的对象语法十分直观--非常像CSS,其实它是一个Javascript对象,
CSS属性名必须用驼峰命名法,在官方的文档中写的是既可以用驼峰也可以用 短横分隔命名法,
经过我的测试,如果要使用 短横分隔命名法 ,key 必须带引号。使用驼峰命名法则不需要。

短横分隔命名法
// 这里的 background-color  font-size 必须要用引号引起来
<div id="app" :style="{'background-color': bkColor, 'font-size':size}">hello美女</div>

var vm= new Vue({
    el:'#app',
    data:{
        bkColor: "#fff",
        size: "16px"
    }
})

驼峰命名法
// 这里的 background-color 转为 backgroundColor ,font-size 转为 fontSize。可不用引号
<div id="app" :style="{backgroundColor: bkColor, fontSize:size}">hello美女</div>

var vm= new Vue({
    el:'#app',
    data:{
        bkColor: "#fff",
        size: "16px"
    }
})


也可以直接绑定到一个样式对象

<div id="app" :style="styleObj">hello美女</div>

var vm= new Vue({
    el:'#app',
    data:{
        styleObj: {
            backgroundColor: "#fff", 
            fontSize: "16px"
        }
    }
})


数组语法: 可将多个样式对象应用到一个元素上
<div id="app" :style="[styleObjA, styleObjB]">hello美女</div>

var vm= new Vue({
    el:'#app',
    data:{
        styleObjA: {
            backgroundColor: "#fff", 
            fontSize: "16px"
        },
        styleObjB: {
            color: "black"
        }
    }
})
复制代码

 

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. v-if 与 v-for 同时出现在同一层级,哪个优先级高
  • v-for优先级高于v-if
  • 两者同级出现,每次渲染都会先执行循环再判断条件,无论如何循环都不可避免的浪费性能
  • 所以不推荐v-if和v-for在同一个标签内同时使用

解决办法

复制代码
<!--嵌套的写法-->
<template>
  <div>
    <ul>
      <li v-for="(user,index) in users" v-if="user.isActive" :key="user.index">
        {{ user.name }}
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  name:'usr',
  data () {
    return {
      users: [{name: 'zzz',isActive: true}, 
              {name: 'bj',isActive: false}]
    };
  }
};
</script>

<!--解决方法-->
<template>
 <div>
    <ul>
      <li v-for="(user,index) in activeUsers" :key="user.index">
        {{ user.name }}
      </li>
    </ul>
</div>
</template>
<script>
export default {
  name:'usr',
  data () {
    return {
      users: [{name: 'zzz',isActive: true}, 
              {name: 'bj',isActive: false}]
    };
  },
  computed: {  //通过计算属性过滤掉列表中不需要显示的项目
    activeUsers: function () {
      return this.users.filter(function (user) {
        return user.isActive;  // 返回isActive=true的项,添加到activeUsers数组
      })
    }
  }
};
</script>
复制代码

 

12. 指令修饰符
    -- .lazy:失去焦点时才获取数据,默认是内容改变就获取
    -- .number: 当输入的数据是数字时,转为数字类型
    -- .trim:去空格

 

13. 自定义的指令
复制代码
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
复制代码

 

14. 自定义指令控制某个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>
复制代码

 

15. 自定义模仿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、ref的两种用法

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、ref如果用于子组件,那么父组件可以使用子组件的方法

vue中如果父组件想调用子组件的方法,可以在子组件中加上ref,然后通过this.$refs.name.method调用。

父组件

复制代码
<template>
    <div @click="fmethod">
        <child ref="refChild"></child>
    </div>
</template>

<script>
    import child from './components/child.vue';

    export default {
        components: {
            child
        },
        methods: {
            fmethod() {
                // 这里this.$refs.refChild获取到的是子组件的vue实例
                // 可以使用子组件对应的方法
                this.$refs.refChild.sonMethods();
            }
        }
    };
</script>
复制代码

子组件

复制代码
<template>
    <div>{{test}}</div>
</template>

<script>
    export default {
        data() {
            return {
                test: '测试'
            };
        },
        methods: {
            sonMethods() {
                console.log(this.test);
            }
        }
    };
</script>
复制代码

 

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、对象的可计算的属性名

在ES6中,把属性名用 [ ] 括起来,则括号中就可以引用提前定义的变量。
相当于是一个计算属性,在执行的时候会把这个表达式求值,替换成真正的值调用。

复制代码
var CONST_AGE = 'age';
var person = {
    'name': '狗子',
    [CONST_AGE] : 18  // 引用了变量CONST_AGE。相当于添加了一个属性名为age的属性
}

console.log(person)  // {name: "狗子", age: 18}
console.log(person[CONST_AGE])  // 18
console.log(person.age)  // 18

// ###############################

var AGE_INCREASE = 'age_increase'
var funcobj = {
    [AGE_INCREASE]: function(age) {
        console.log(age)
    }
}


/*
{
    data: function(){return 1}
}

ES6中可以直接简写

{
    data(){return 1})
}
*/

于是上面代码等价于


var AGE_INCREASE = 'age_increase'
var funcobj = {
    [AGE_INCREASE](age) {
        console.log(age)
    }
}


funcobj.age_increase(18)  // 18
funcobj[AGE_INCREASE](18)  // 18


// 区别于数组的解构

// 解构数组 
    // 定义数组
    let hobby = ["吹牛", "泡妞", "打架"];

    // 解析数组
    let [hobby1, hobby2, hobby3] = hobby;

    console.log(hobby1);  // 吹牛
    console.log(hobby2);  // 泡妞
    console.log(hobby3);  // 打架

    [] = xx  有赋值的动作
    

// 计算属性
    var AGE_INCREASE = 'age_increase'
    [AGE_INCREASE]

    [] 直接计算,无需赋值操作
复制代码

 

4、数据的监听

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>
复制代码

 

5、Vue中的nextTick

作者:扶得一人醉如苏沐晨
链接:https://www.jianshu.com/p/8efa5cba7d07
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM,在下次 DOM 更新循环结束之后执行延迟回调。

简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数。
Vue在更新data之后并不会立即更新DOM上的数据,就是说如果我们修改了data中的数据,再马上获取DOM上的值,我们取得的是旧值,我们把获取DOM上值的操作放进$nextTick里,就可以得到更新后得数据。

 

正确的用法是:vue改变data中的数据后,使用vue.$nextTick()方法包裹js对象执行后续代码

什么时候使用$nextTick

1、Vue⽣命周期的created()钩⼦函数进⾏的DOM操作⼀定要放在Vue.nextTick()的回调函数中,原因是在created()钩⼦函数执⾏的时候,DOM 其实并未进⾏任何渲染,⽽此时进⾏DOM操作⽆异于徒劳,所以此处⼀定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。

2、当项⽬中改变data函数的数据,想基于新的dom做点什么,对新DOM⼀系列的js操作都需要放进Vue.nextTick()的回调函数中。

 

posted @   我用python写Bug  阅读(570)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示