Vue2.5去哪儿学习笔记【二】

一、Vue实例生命周期函数

生命周期函数就是vue实例在某一个时间点会自动执行的函数。
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会.
 
例子:
<div id="app"></div>
    <script>
        var vm = new Vue({
            el: '#app',
            template: "<div>{{test}}</div>",
            data: {
                test: "hello world"
            },
            beforeCreate: function() {
                console.log("beforeCreate");
            },
            created: function() {
                console.log("created");
            },
            //执行这个函数的时候页面还没被渲染
            beforeMount: function() {
                console.log(this.$el);
                console.log("beforeMount");
            },
            //执行这个函数的时候页面已被渲染
            mounted: function() {
                console.log(this.$el);
                console.log("mounted");
            },
            beforeDestroy: function() {
                console.log("beforeDestroy")
            },
            destroyed: function() {
                console.log("destroyed");
            },
            beforeUpdate: function() {
                console.log("beforeUpdate");
            },
            updated: function() {
                console.log("updated");
            }
        })
    </script>

运行按下F12查看控制台结果:

 

调用vm.$destroy()方法:

控制台更改数据:

注意:vue的生命周期函数并不放在methods里,而是单独放在vue实例里

 

二、Vue的模板语法

1.插值表达式

数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:{{数据对象}}

2.v-text

v-text:vue的指令之一,v-text是用于操作纯文本,它会替代显示对应的数据对象上的值。当绑定的数据对象上的值发生改变,插值处的内容也会随之更新

3.v-html

v-html:vue的指令之一,将元素当成HTML标签解析后输出.

4.区别

通过以下这个例子来区别它们的异同

<div id="app">
    <div>{{name}}</div>
    <div v-text="name"></div>
    <div v-html="name"></div>
</div>   
 <script>
        var vm = new Vue({
            el: "#app",
            data: {
                name: "<h1>Dell</h1>"
            }
        })
 </script>

从结果可以看到:

v-text{{}}表达式渲染数据,但不解析标签。
v-html不仅可以渲染数据,而且可以解析标签。

三、计算属性,方法,侦听器

1.计算属性

在模板中放入太多的逻辑会让模板过重且难以维护,对于任何复杂逻辑,都应当使用计算属性

例子:

<div id="app">
     {{fullName}} {{age}}
 </div>
<script>
        var vm = new Vue({
            el: "#app",
            data: {
                firstName: "Dell",
                lastName: "Lee",
                age: 28
            },
            computed: {
                fullName: function() {
                    console.log("计算了一次");
                    return this.firstName + " " + this.lastName
                }
            }
         })
</script>

运行结果:

打开浏览器的控制台,修改例子中的 vm,可以看到结果:

当修改vm.age的值时,计算属性没有执行;当修改vm.firstName或vm.lastName时,计算属性会再执行。

计算属性基于它们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时它们才会重新求值。依赖的值没有任何改变,就不会再次执行函数

计算属性的setter和getter:
计算属性默认只有 getter,在需要时你也可以提供一个 setter
<script>
        var vm = new Vue({
            el: "#app",
            data: {
                firstName: "Dell",
                lastName: "Lee"
            },
            computed: {
                fullName: {
                    //通过其他值算出新值
                    get: function() {
                        return this.firstName + " " + this.lastName
                    },
                    // 通过设置一个值改变相关联的值
                    set: function(value) {
                        var arr = value.split(" ");
                        this.firstName = arr[0];
                        this.lastName = arr[1];
                        console.log(value);
                    }
                }
            }
        })
    </script>

现在再运行 vm.fullName = 'Mike Wang' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。

2.方法

上述第一个例子,可以通过在表达式中调用方法来达到同样的效果

<div id="app">
        {{fullName()}} {{age}}
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                firstName: "Dell",
                lastName: "Lee",
                age: 28
            },
                methods: {
                    fullName: function() {
                        console.log("计算了一次")
                        return this.firstName + " " + this.lastName;
                    }
                }
        })
    </script>

运行结果:

打开浏览器的控制台,修改例子中的 vm,可以看到结果:

当修改vm.age的值时,fullName方法执行了一次,这是因为每当触发重新渲染时,调用方法将总会再次执行函数

3.侦听器

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性

    <div id="app">
        {{fullName}} {{age}}
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                firstName: "Dell",
                lastName: "Lee",
                fullName: "Dell Lee",
                age: 28
            },
            watch: {
                firstName: function() {
                    console.log("计算了一次");
                    this.fullName = this.firstName + " " + this.lastName;
                },
                lastName: function() {
                    console.log("计算了一次");
                    this.fullName = this.firstName + " " + this.lastName;
                }
            }
        })
</script>

运行结果:

打开浏览器的控制台,修改例子中的 vm,可以看到结果:

侦听器:有缓存机制,不相关的数据发生变化时,监听函数不会执行 

上面代码是命令式且重复的。将它与计算属性的版本进行比较,计算属性既简洁又方便

4.总结

在Vue中 计算属性基于它们的依赖进行缓存的,而方法不会基于它们的依赖进行缓存的。计算属性侦听器都有缓存机制,但计算属性代码简洁且方便。

 

四、Vue中的样式绑定

通过Vue中的样式绑定来实现以下例子:

当Hello world这个div被点击一次时变成红色,当再次点击的时候恢复 默认展示

1.绑定HTML Class

①对象语法

可以传给v-bind:class一个对象,以动态地切换 class

例子:

    <style>
        .activated {
            color: red;
        }
    </style>


<
div id="app"> <div @click="handleDivClick" :class="{activated:isActivated}">Hello world</div> </div> <script> var vm = new Vue({ el: "#app", data: { isActivated: false }, methods: { handleDivClick: function() { // 取反,第一次点击从false变成true;第二次点击从true变成false this.isActivated = !this.isActivated; } } }) </script>

上面的语法表示activated这个 class 存在与否将取决于数据 property isActivated的 truthness。

②数组语法

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

例子:

    <style>
        .activated {
            color: red;
        }
    </style>

<div id="app"> <div @click="handleDivClick" :class="[activated]">Hello world</div> </div> <script> var vm = new Vue({ el: "#app", data: { activated: "" }, methods: { handleDivClick: function() { this.activated = this.activated === "activated" ? "" : "activated" } } }) </script>

当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法

2.绑定内联样式

①对象语法

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。

例子:

    <style>
        .activated {
            color: red;
        }
    </style>

<
div id="app"> <div :style="styleObj" @click="handleDivClick">Hello world</div> </div> <script> var vm = new Vue({ el: "#app", data: { styleObj: { color: "black" } }, methods: { handleDivClick: function() { this.styleObj.color = this.styleObj.color === "black" ? "red" : "black" } } }) </script>

②数组语法

v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上

例子:

    <style>
        .activated {
            color: red;
        }
    </style>

<
div id="app"> <div :style="[styleObj]" @click="handleDivClick">Hello world</div> </div> <script> var vm = new Vue({ el: "#app", data: { styleObj: { color: "black" } }, methods: { handleDivClick: function() { this.styleObj.color = this.styleObj.color === "black" ? "red" : "black" } } }) </script>

 

五、Vue中的条件渲染

Vue中的条件渲染需要用到v-if指令或v-show指令

 1.v-if

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

例子:

<div v-if="show" data-test="v-if">
{{message}}
</div>
<script>
        var vm = new Vue({
            el: "#app",
            data: {
                show: false,
                message: "Hello World"
            }
        })
 </script>

 v-if 表达式的返回值true或false决定了标签div是否被真实的挂载到页面上 

可以用 v-else 添加一个“else 块”,或者v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用

例子:

 <div id="app">
        <!-- ifelse /if else 要紧贴在一起使用 如果被其他标签阻隔浏览器会报错-->
        <div v-if="show ==='a'">This is A</div>
        <div v-else-if="show === 'b'">This is B</div>
        <div v-else>This is others</div> 
 </div>

 <script>
        var vm = new Vue({
            el: "#app",
            data: {
                show: “a”

            }
        })
  </script>

注意:类似于 v-elsev-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后,如果被其他标签阻隔浏览器会报错

使用条件渲染可能出现的bug

例子:代码中根据条件渲染显示用户名/邮箱名的输入框

<div id="app">
        <div v-if="show">
            用户名:<input/>
        </div>
        <div v-else>
            邮箱名:<input/>
        </div>
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                show: false,

            }
        })
    </script>

在切换过程中,将不会清除用户已经输入的内容。因为两个模板使用了相同的元素<input> 不会被替换掉——仅仅是替换了它的 placeholder

原因:vue在重新渲染的时候会尽量复用页面上已经存在的dom 

解决办法:Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key attribute 即可

<div id="app">
        <div v-if="show">
            用户名:<input key="username" />
        </div>
        <div v-else>
            邮箱名:<input key="password" />
        </div>
    </div>
当你给某个元素标签加个key值,vue会知道它是页面上唯一的一个元素,如果两个<input>的key值不一样,vue就不会尝试去复用以前的input标签了

 2.v-show

另一个用于根据条件展示元素的选项是 v-show 指令。用法与v-if大致一样:

 

<div v-show="show" data-test="v-show">{{message}}
</div>

 

与v-if不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中v-show 只是简单地切换元素的 CSS property display

 

六、Vue中的列表渲染

 1.使用列表渲染

我们可以用 v-for 指令基于一个数组来渲染一个列表。

用 v-for 把一个数组对应为一组元素

v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法

<div id="app>
    <div v-for="item of list">
            {{item}}
    </div>
</div>
 <script>
        var vm = new Vue({
            el: "#app",
            data: {
                list: [1,2,3,4,5]
            }
        })
 </script>

v-for 还支持一个可选的第二个参数,即当前项的索引。

<div id="app>
    <div v-for="(item,index) of list">
            {{item}} ---- {{index}}
    </div>
</div>

在v-for需要多次执行相同的循环时,可以用<template></template>  模板占位符来循环渲染一段包含多个元素的内容。最终的渲染结果将不包含 <template> 元素。

<template v-for="(item,index) of list">
            <div :key="item.id">
                {{item.text}} ---- {{index}}
            </div>
            <span>
                {{item.text}}
            </span>
        </template>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                list: [{
                    id: "010120201",
                    text: "hello"
                }, {
                    id: "010120202",
                    text: "nice"
                }, {
                    id: "010120203",
                    text: "to"
                }, {
                    id: "010120204",
                    text: "meet"
                }, {
                    id: "010120205",
                    text: "you"
                }]

            }
        })
    </script>

 

②可以用 v-for 来遍历一个对象的 property

<!-- 做对象的循环 -->
    <div id="app">
        <!-- item:键值 key:对象的键名 index:索引-->
        <div v-for="(item,key,index) of userInfo">
            {{item}} --- {{key}}
        </div>
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                userInfo: {
                    name: "Rose",
                    age: 18,
                    gender: "female",
                    salary: "secret"
                }
            }
        })
    </script>

2.数组变更方法

当我们要给数组加数据的时候,不能通过下标的形式来改变数组(改了之后页面不会发生变化)。只能靠vue提供数组的变异方法或者改变数组的引用才能实现数据变化页面也跟着变化

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push():可向数组的末尾添加一个或多个元素,并返回新的长度。
  • pop():用于删除并返回数组的最后一个元素。
  • shift():用于把数组的第一个元素从其中删除,并返回第一个元素的值。
  • unshift():可向数组的开头添加一个或更多元素,并返回新的长度。
  • splice():向/从数组中添加/删除项目,然后返回被删除的项目。
  • sort():用于对数组的元素进行排序。
  • reverse():用于颠倒数组中元素的顺序。

注意:同样的,对对象变更数据,不能直接修改,需要改这个对象的引用或vue提供的set方法

 

3.Vue中的set方法

通过set方法向页面中注入数据 数据发生变化时页面也会发生变化 

①修改数组的set方法应用

<!-- vue的set方法
    Vue.set(vm.userInfo,1,5) 
    vm.$set(vm.userInfo,2,10)-->
    <div id="app">
        <div v-for="(item,index) of userInfo">
            {{item}}
        </div>
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                userInfo: [1, 2, 3, 4]
            }
        })
    </script>

②修改对象的set方法应用

    <!-- 
        Vue中的set方法向对象改变数据的内容
        Vue.set(vm.userInfo,"address","beijing") -->
    <!-- 实例的set方法
        vm.$set(vm.userInfo,"address","beijing") -->
    <!-- 做对象的循环 -->
    <div id="app">
        <!-- item:键值 key:对象的键名 index:索引-->
        <div v-for="(item,key,index) of userInfo">
            {{item}} --- {{key}}
        </div>
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                userInfo: {
                    name: "Rose",
                    age: 18,
                    gender: "female",
                    salary: "secret"
                }
            }
        })
    </script>

 

posted @ 2021-01-29 16:33  小风车吱呀转  阅读(98)  评论(0编辑  收藏  举报