学习笔记:Vue2.5开发去哪儿网App 第三章笔记

132 阅读3分钟

1. vue 生命周期函数

  每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如,实例需要配置数据观测(data observer)、编译模版、挂载实例到 DOM ,然后在数据变化时更新 DOM 。在这个过程中,实例也会调用一些 生命周期钩子 ,这就给我们提供了执行自定义逻辑的机会

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue实例生命周期函数</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            test:'template option'
        },
        template:'<div>{{test}}</div>',
        beforeCreate:function () {
            // 在实例初始化之后
            // 数据观测(data observer) 和 event/watcher 事件配置之前被调用。
            console.log('beforCreate')
        },
        created:function () {
            // 实例已经创建完成之后被调用。
            // 在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
            console.log('created')
        },
        beforeMount:function () {
            // 在挂载开始之前被调用:相关的 render 函数首次被调用
            console.log('beforeMount')
            console.log(this.$el);
        },
        mounted:function () {
            // el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
            // 如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
            console.log('mounted')
            console.log(this.$el);
            this.$data.test = '我改变了test'
            // beforeUpdate   updated方法

        },
        beforeDestroy:function () {
            // 实例销毁之前调用。在这一步,实例仍然完全可用。
            console.log('beforeDestrory')
        },
        destroyed:function () {
            // ue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
            console.log('destroyed')
        },
        beforeUpdate:function () {
            // 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
            console.log('boforeUpdate')
        },
        updated:function () {
            // 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
            // 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
            console.log('updated')
            this.$destroy();
            // 完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。
            // 触发 beforeDestroy 和 destroyed 的钩子。
        }
    })
</script>
</body>
</html>

2. 模板语法

 Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。

在底层的实现上, Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,在应用状态改变时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板语法</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
    {{name}}
    <!--#插值表达式-->
    <div v-text="name"></div>
    <!--文本-->
    <div v-html="name" :title="title"></div>
    <!--被插入的内容都会被当做 HTML —— 数据绑定会被忽略-->

    <div v-text="age + '岁'"></div>

    <!--#过滤器-->
    {{ msg | capitalize }}

    <a v-bind:href="url">百度一下</a>


    v-bind 缩写
    <!-- 完整语法 -->
    <a v-bind:href="url"></a>
    <!-- 缩写 -->
    <a :href="url"></a>


    v-on 缩写
    <!-- 完整语法 -->
    <a v-on:click="doSomething"></a>
    <!-- 缩写 -->
    <a @click="doSomething"></a>


</div>
<script>
    var app = new Vue({
        el:'#app',
        data:{
            name:'<h1>Dell</h1>',
            title:'this is a title',
            age:20,
            msg:'this is a message',
            url:'https://www.baidu.com/'
        },
        filters: {
            capitalize: function (value) {
                if (!value) return ''
                value = value.toString()
                return value.charAt(0).toUpperCase() + value.slice(1)
            }
        }
    })
    console.log(app.$data)
</script>
</body>
</html>

3. 计算属性,方法,侦听器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性,方法,侦听器</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
    <!--获取fullName-->
    <!--第一种方式-->
    <!--{{ fullName }}-->

    <!--第二种方式-->
    <!--{{getFullName()}}-->

    <!--第三种方式-->
    {{fullName}}

    {{ age }}

</div>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            firstName:'Dell',
            lastName:'Lee',
            age:20,
            fullName:'Dell Lee'
        },
        // #计算属性  缓存机制,如果依赖的值没有发生改变,不会重新执行
        // computed:{
        //     fullName:function () {
        //         console.log('fullName 计算了一次')
        //         return this.firstName+"   "+this.lastName
        //     }
        // },
        // methods:{
        //     // 即使依赖的值没有发生改变,也会重新执行
        //     getFullName:function () {
        //         console.log('getFullName 计算了一次')
        //         return this.firstName+"   "+this.lastName
        //     }
        // },
        watch:{
            // #类似computed
            firstName:function () {
                console.log('我执行了firstName')
                return this.fullName = this.firstName+this.lastName
            },
            lastName:function () {
                return this.fullName = this.firstName+this.lastName
                console.log('我执行了lastName')
            },
        }
    })
</script>
</body>
</html>

4. 计算属性的 setter,getter

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性setter和getter</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
    {{fullName}}
</div>
<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 name = value.split(" ");
                    console.log(name);
                    this.firstName = name[0];
                    this.lastName = name[1];
                }
            }
        }
    })
</script>
</body>
</html>

5.样式的绑定

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

:class="{activated:isactivated}"

上面的语法表示 activated 的更新将取决于数据属性 isActive 是否为 真值 。

实现动态切换:

<div @click="HandleDivClick" :class="{activated:isactivated}">hello world</div>
HandleDivClick:function () {
    this.isactivated = !this.isactivated
}

:class = "[class1,class2,class3......]" 添加多个样式

<div @click="HandleDivClick1" :class="[activated,'defaultClass']">hello world1</div>
HandleDivClick1:function () {
    this.activated = this.activated==='activated'?'':'activated';
}

6.绑定内联样式

v-bind:style 的对象语法十分直观——看着非常像 CSS ,其实它是一个 JavaScript 对象。 CSS 属性名可以用驼峰式(camelCase)或短横分隔命名(kebab-case)

<div :style="styleObj" @click="HandleDivClick2">my style</div>
styleObj:{
    color:'black',
    fontSize:'50px'
}
HandleDivClick1:function () {
    this.activated = this.activated==='activated'?'':'activated';
}

<div :style="[styleObj,{cursor:'pointer'}]" @click="HandleDivClick2">my style</div>
HandleDivClick2:function () {
    this.styleObj.color = this.styleObj.color==='black'?'red':'black';
}

7.条件渲染

v-if 是真实的条件渲染,因为它会确保条件块在切换当中适当地销毁与重建条件块内的事件监听器和子组件。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>条件渲染</title>
    <script src="../../vue.js"></script>
</head>
<div id="app">

    <div  v-if="show" data-test="v-if">{{message}}</div>
    <div  v-else>Bye</div>
    <!--v-else 元素必须紧跟在 v-if 或 v-show 元素的后面——否则它不能被识别-->


    <!--#dom在页面上存在,display: none;-->
    <div  v-show="show" data-test="v-show">{{message}}</div>


    <template>
        <div v-if="charactor === 'a'">This is A</div>
        <div v-else-if="charactor==='b'">This is B</div>
        <div v-else>This is others</div>
    </template>

    <div v-if="myinput==='email'">
        邮箱:
        <input type="text" key="email">
    </div>
    <div v-else>
        用户名:
        <input type="text" key="username">
    </div>
</div>
<body>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            show:false,
            message:'hello world',
            charactor:'a',
            myinput:'email'
        }
    })
</script>
</body>
</html>

相比之下, v-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。

一般来说, v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换使用 v-show 较好,如果在运行时条件不大可能改变则使用 v-if 较好

因为 v-if 是一个指令,需要将它添加到一个元素上。但是如果我们想切换多个元素呢?此时我们可以把一个<template> 元素当做包装元素,并在上面使用 v-if,最终的渲染结果不会包含它

8.列表渲染

我们用 v-for 指令根据一组数组的选项列表进行渲染。 v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名

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

列表的遍历:

    <div v-for="(item,index) in list" :key="item.id">
        {{item.text}}--{{index}}
    </div>
list:[
    {
        id:'asjdflsfsaf',
        text:'hello'
    },
    {
        id:'12316581',
        text:'dong'
    },
    {
        id:'wefdsadf',
        text:'nyyyy'
    },
],

对象的遍历:

 UserInfo:{
    username:"boss dong",
    age:20,
    school:'ny'
}
<!--key:键 item:值  index:索引-->
<div v-for="(item,key,index) in UserInfo">
    {{item}}---{{key}}---{{index}}
</div>

vue数组方法:push pop shift unshift splice sort reverse

重点 数据视图双向修改:

列表数据的修改(例如修改第二项):

 //方法1. splice()
// 语法
// arrayObject.splice(index,howmany,item1,.....,itemX)
// 参数  描述
// index   必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
// howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
// item1, ..., itemX   可选。向数组添加的新项目。
 this.list.splice(1,1,{id:'xlj',text:'new dong'});

// 方法2.修改引用
this.list=[
    {
        id:'asjdflsfsaf',
        text:'hello'
    },
    {
        id:'12316581',
        text:'new dong'
    },
    {
        id:'wefdsadf',
        text:'nyyyy'
    },
]
// 方法3:
Vue.set(this.list,1,{    id:'456789',    text:'changed by Vue.set'})

对象数据的修改:

  //方法1:// this.UserInfo.username = 'new boss';
// 方法2:
Vue.set(this.UserInfo,'username','new boss');

对象增加数据:

  // 方法1.添加一个plac字段,修改引用
// this.UserInfo = {
//     username:"boss dong",
//     age:20,
//     school:'ny',
//     place:'重庆'
// }
//方法2.Vue.set方法
Vue.set(this.UserInfo,'place','北京')
  <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>列表渲染</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
    <div v-for="(item,index) in list" :key="item.id">
        {{item.text}}--{{index}}
    </div>
    <button @click="HandleBtnClick">修改dong</button>


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


    <!--对象的遍历-->
    <!--key:键 item:值  index:索引-->
    <div v-for="(item,key,index) in UserInfo">
        {{item}}---{{key}}---{{index}}
    </div>
    <button @click="ChangInfo">修改Info</button>
    <button @click="AddInfoPlace">添加地址</button>
</div>
<script>
    //vue数组方法:push pop shift unshift splice sort reverse

    var vm = new Vue({
        el:"#app",
        data:{
            list:[
                {
                    id:'asjdflsfsaf',
                    text:'hello'
                },
                {
                    id:'12316581',
                    text:'dong'
                },
                {
                    id:'wefdsadf',
                    text:'nyyyy'
                },
            ],
            UserInfo:{
                username:"boss dong",
                age:20,
                school:'ny'
            }
        },
        methods:{
            HandleBtnClick:function () {
                // #修改第二项

                //方法1. splice()
                // 语法
                // arrayObject.splice(index,howmany,item1,.....,itemX)
                // 参数    描述
                // index    必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
                // howmany    必需。要删除的项目数量。如果设置为 0,则不会删除项目。
                // item1, ..., itemX    可选。向数组添加的新项目。
                // this.list.splice(1,1,{id:'xlj',text:'new dong'});

                // 方法2.修改引用
                this.list=[
                    {
                        id:'asjdflsfsaf',
                        text:'hello'
                    },
                    {
                        id:'12316581',
                        text:'new dong'
                    },
                    {
                        id:'wefdsadf',
                        text:'nyyyy'
                    },
                ]

                // 方法3:
                Vue.set(this.list,1,{
                    id:'456789',
                    text:'changed by Vue.set'
                })
            },
            ChangInfo:function () {
                //方法1:
                // this.UserInfo.username = 'new boss';
                // 方法2:
                Vue.set(this.UserInfo,'username','new boss');
            },
            AddInfoPlace:function () {
                // 方法1.添加一个plac字段,修改引用
                // this.UserInfo = {
                //     username:"boss dong",
                //     age:20,
                //     school:'ny',
                //     place:'重庆'
                // }
                //方法2.Vue.set方法
                Vue.set(this.UserInfo,'place','北京')
            }
        }
    })
</script>
</body>
</html>