VUE入门 生命周期 计算属性 监听器 组件【2】

我心飞翔 分类:vue

目录

生命周期

什么是生命周期

生命周期流程

计算属性computed计算属性与监听器

计算属性computed

        存在的问题

        基本使用

       案例:字符串倒排

        computed和method的区别

        案例:购物车

监听器watch

        什么是监听器

        基本语法

        案例:拆分姓名

组件

        什么是组件

        组件分类

                全局组件

              局部组件

        组件自定义属性

                什么是组件属性

                定义属性

                绑定属性值

                组件事件


生命周期

什么是生命周期

  • Vue的生命周期, 就是Vue实例从创建到销毁的过程.
  • 完整过程包含: 开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁
  • vue生命周期含8步骤(有8个沟子函数):创建、挂载、更新、销毁
  •  created() 创建后
  • mounted() 挂载后

生命周期流程

VUE入门 生命周期 计算属性 监听器 组件【2】

属性名

执行时机

描述

beforeCreate

创建前

Vue实例创建时触发, 一般不做操作

created

创建后

挂载数据,绑定事件等之后,执行created函数 一般可以获取初始数据

beforeMount

挂载到页面前

已经创建虚拟dom, 准备渲染

mounted

挂载到页面后

已经渲染真实dom

beforeUpdate

更新页面前

updated

更新页面后

beforeDestroy

销毁vue之前

destroyed

销毁之后

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model="message"> <br/>
        原始数据:{{message}} <br/>
    </div>
</body>
</html>
<script>
    let vue = new Vue({
        el: '#app',
        data:{
            message: 'abc'
        },
        beforeCreate() {
            console.info('1.创建前')  
        },
        created() {
            console.info('2.创建')
        },
        beforeMount() {
            console.info('3.挂载前')  
        },
        mounted() { //页面加载成功
            console.info('4.挂载')  
        },
        beforeUpdate() {
            console.info('5.更新前')  
        },
        updated() {
            console.info('6.更新')  
        },
        beforeDestroy() {
            console.info('7.销毁前')  
        },
        destroyed() {
            console.info('8.销毁')  
        },
    })
    //销毁
    // vue.$destroy()
</script>

计算属性computed计算属性与监听器

计算属性computed

        存在的问题

  • 插值表达式, 可以完成表达式的计算,如果逻辑复杂时,将很难维护. 例如:
<div id="app">
  {{ message.split('').reverse().join('') }}
</div>

        基本使用

  • Vue计算属性computed就是用来处理复杂逻辑的. 当data区域的数据变更是,将进行自动计算.
<script>
    new Vue({
        el: '#app',
        computed: {
            属性名(){
			  // 功能
                return 返回值;
            }
        },

    })
</script>

       案例:字符串倒排

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        {{showMessage}}
    </div>
</body>
</html>
<script>
    new Vue({
        el: '#app',
        data: {
            message : 'abcd'
        },
        computed: {
            showMessage(){
                return this.message.split('').reverse().join('')
            }
        },

    })
</script>

        computed和method的区别

  • 计算属性,用于实时计算,只要数据发生了更改才计算。缓存计算结果。
  • 方法,每次调用都执行

        案例:购物车

VUE入门 生命周期 计算属性 监听器 组件【2】
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
    <style>
        a {
            text-decoration: none;      /*a标签取消下划线*/
            font-size:20px;
        }
    </style>
</head>
<body>
    <div id="app">
        <table border="1" width="500">
            <tr>
                <td>编号</td>
                <td>标题</td>
                <td>单价</td>
                <td>购买数量</td>
                <td>小计</td>
            </tr>
            <tr v-for="(book,index) in cart" :key="index">
                <td>{{index+1}} </td>
                <td>{{book.title}} </td>
                <td>{{book.price}} </td>
                <td>
                    <a href="#" @click.prevent="book.count > 0 ? book.count-- : 0">-</a>
                    {{book.count}}
                    <a href="#" @click.prevent="book.count++">+</a>
                </td>
                <td>{{book.price * book.count}} </td>
            </tr>
            <tr>
                <td colspan="3"></td>
                <td colspan="2">总价:{{totalPrice}} </td>
            </tr>
        </table>
    </div>
</body>
</html>
<script>
    new Vue({
        el: '#app',
        data: {
            cart :[
                {
                    title : '葵花籽真经',
                    price : 32,
                    count : 0
                },
                {
                    title : '程序员的修养',
                    price : 66,
                    count : 0
                }
            ]
        },
        computed: {
            totalPrice() {
                var sum = 0
                this.cart.forEach( (book) => {
                    sum += book.price * book.count;
                })
                return sum;
            }

        }
    })
</script>

监听器watch

        什么是监听器

监听数据的变化

<script>
    new Vue({
        el: '#app',
        data: {
            变量: '',
        },
        watch: {
            变量: function(新数据, 旧数据) {
                
            },
 	       变量2:{
                handler: function (val, oldVal) { /* ... */ },
      		  deep: true					/*监听对象属性,不论嵌套多深*/
		  }
        },

    })
</script>

        基本语法

        案例:拆分姓名

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        请输入姓名:<input type="text" v-model="username">  <br/>

        姓:{{firstname}} <br/>
        名:{{secondname}}

    </div>
</body>
</html>
<script>
    new Vue({
        el: '#app',
        data: {
            username: '',
            firstname: '',
            secondname: ''
        },
        watch: {
            username: function(val, oldVal) {
                if(val){
                    this.firstname = val.substring(0,1)
                    this.secondname = val.substring(1)
                } else {
                    this.firstname = ''
                    this.secondname = ''
                }
            }
        },

    })
</script>

        案例:拆分姓名

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        请输入姓名:<input type="text" v-model="user.username">  <br/>

        姓:{{firstname}} <br/>
        名:{{secondname}}

    </div>
</body>
</html>
<script>
    new Vue({
        el: '#app',
        data: {
            user: {
                username: '',
            },
            firstname: '',
            secondname: ''
        },
        watch: {
            user: {
                handler: function(val, oldVal) {
                    if(val.username){
                        this.firstname = val.username.substring(0,1)
                        this.secondname = val.username.substring(1)
                    } else {
                        this.firstname = ''
                        this.secondname = ''
                    }
                },
                deep: true
            }
        },

    })
</script>

组件

        什么是组件

组件是可复用的 Vue 实例,且带有一个名字

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如:头部导航、尾部信息等模块。

但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

        组件分类

  • 组件的作用域分为两种:全局组件 和 局部组件。
    • 全局组件:在所有的Vue实例中都可以使用
    • 局部组件:只有在注册了组件的Vue实例中才可以使用

                全局组件

使用 Vue.component 定义的组件为全局组件,在所有的 Vue 实例中都可以使用。

比如以下代码中定义了一个全局组件,这个组件在两个Vue实例中都可以使用:

  • 语法
    Vue.component("",{
        template: ``,   // 定义html部分,要求有一个根标签
        data() {        // 定义数据部分
            return {
                
            }
        },
    })
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>vue组件</title>
  <script src="js/vue.js"></script>
</head>

<body>
  <div id="app1">
    <!--组件必须绑定在实例下面才能起作用-->
    <my-nav></my-nav>
  </div>

  <div id="app2">
      <!--组件必须绑定在实例下面才能起作用-->
      <my-nav></my-nav>
    </div>
  <script>
    //定义组件1
    Vue.component("MyNav", {
      template: '<div>您好!{{name}}</div>',

      data: function () {
        return {
          name: "jack"
        }
      }
    })

    //下面两个实例都可以使用全局组件
    new Vue({
      el: '#app1'
    });

    //下面两个实例都可以使用全局组件
    new Vue({
      el: '#app2'
    });
  </script>
</body>

</html>

              局部组件

局部组件是指只能在注册了该组件的 Vue 实例中才可以使用。(先需要注册才能用)

局部组件的定义只是定义一个组件对象:

局部组件的定义只是定义一个组件对象:

var 组件名 = { ... }

在需要使用这个组件的Vue中注册组件

const app = new Vue({
    ...
    components:{
        组件名:组件对象
    }
})

局部组件使用实例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>vue组件</title>
  <script src="js/vue.js"></script>
</head>

<body>
   <div id="app1">
      <!--组件必须绑定在实例下面才能起作用-->
      <my-hello></my-hello>
    </div>
  <script>

    var hello = {
      template: '<div>您好!现在是在使用子组件</div>',
    };
    //下面两个实例都可以使用全局组件
    new Vue({
      el: '#app1',
      components:{
        "MyHello":hello
      }
    });
  </script>
</body>

</html>

        组件自定义属性

                什么是组件属性

什么是组件属性?比如我们在使用img标签时, src就是属性。如果我们把img看做一个组件的话,src就是这个组件的属性。

  • 总结:组件属性用于父组件向子组件传递数据。

                定义属性

当需要为组件设置属性时,我们需要先在定义组件时使用 props 来设置这个组件上所有属性的名字

Vue.component('...',{
    ...
    props:[属性名字数组]
})

定义了组件属性之后,在组件中就可以像使用一个普通数据一样使用属性:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>vue组件</title>
  <script src="js/vue.js"></script>
</head>

<body>
  <div id="app1">
    <!--组件必须绑定在实例下面才能起作用-->
    <my-nav welcome="张三丰"></my-nav>
  </div>
  <script>

    Vue.component('MyNav', {
      props: ['welcome'],
      template: '<div>欢迎您,游客! {{welcome}}</div>'
    })
    //下面两个实例都可以使用全局组件
    new Vue({
      el: '#app1'
    });
  </script>
</body>

</html>

                绑定属性值

还可以把属性值绑定到 Vue 的数据中,实现方式如下

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>vue组件</title>
  <script src="js/vue.js"></script>
</head>

<body>
  <div id="app1">
    <!--组件必须绑定在实例下面才能起作用-->
    <my-nav :welcome="txt"></my-nav>
  </div>
  <script>

    Vue.component('MyNav', {
      props: ['welcome'],
      template: '<div>欢迎您,游客! {{welcome}}</div>'
    })
    //下面两个实例都可以使用全局组件
    new Vue({
      el: '#app1',
      data:{
        txt:"绑定数据到属性"
      }
    });
  </script>
</body>

</html>

                组件事件

  • 原生事件

当需要在组件上绑定 JS 中原生的事件时,必须要添加 .native 修饰符,否则该事件是无法触发的。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>vue组件</title>
  <script src="js/vue.js"></script>
</head>

<body>
  <div id="app1">
    <!--组件必须绑定在实例下面才能起作用-->
    <my-nav :welcome="txt" @click.native="hello">您好</my-nav>
  </div>
  <script>

    Vue.component('MyNav', {
      props: ['welcome'],
      template: '<button>欢迎您,游客! {{welcome}}</button>'
    })
    //下面两个实例都可以使用全局组件
    new Vue({
      el: '#app1',
      data:{
        txt:"绑定数据到属性"
      },
      methods:{
        hello:function(){
          alert("组件事件");
        }
      }
    });
  </script>
</body>

</html>
  •  自定义事件

除了原生的事件外,还可以为组件添加自定义的事件,通过自定义的事件,子组件可以向父组件传递消息

  • 在组件中我们可以使用 emit 触发一个事件,这个事件的名字是我们自己定义的:

定义方法如下:声明事件名称

this.$emit('事件名')

在使用这个组件时,就可以为这个新的事件名绑定一个事件:

<my-component v-on:事件名="doSomething"></my-component>

或者:

<my-component @事件名="doSomething"></my-component>

VUE入门 生命周期 计算属性 监听器 组件【2】
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>vue组件</title>
  <script src="js/vuejs-2.5.16.js"></script>
  <script src="js/toDao.js"></script>
</head>

<body>
  <div id="app1">
    <!--组件必须绑定在实例下面才能起作用-->
    <to-do @todo="todo"></to-do>
  </div>
  <script>
    

    //下面两个实例都可以使用全局组件
    new Vue({
      el: '#app1',
      methods: {
        todo: function () {
          console.log('todo组件中发表了新的todo')
        }
      }
    });
  </script>
</body>

</html>
VUE入门 生命周期 计算属性 监听器 组件【2】

回复

我来回复
  • 暂无回复内容