• 08: vue组件


    1.1 初识组件

      1、什么是组件

          1. Html中有组件,是一段可以被复用的结构代码

          2. Css中有组件,是一段可以被复用的样式

          3. Js中有组件,是一段可以被复用的功能

          4. Vue中也有组件,指的就是一个模块,是一个独立的,完整的(包含html,css,js等),可以直接拿来用的

      2、使用组件分成三步

        1、第一步 定义组件容器(定义自定义元素)

        2、第二步 定义组件Vue.extend方法

            1. 参数是组件对象,对象属性跟vue实例化时候传递的参数对象的属性是一样的,例如 data,methods,computed
            2. 在vue实例化时候,data属性的属性值是一个对象,在组件中,data属性值是一个函数,返回值是一个对象
            3. 组件中,可以通过template定义模板,通常模板写在一个根元素内

        3、第三步 将组件注册到页面中 Vue.component

            第一个参数表示容器元素的名称
            第二个参数表示组件类

      3、组件特性

            1. 组件的实例化对象,跟vue实例化对象一样,因此,我们也可以将vue实例化对象看成组件

            2. 组件间是独立的,因此数据要独立存储,方法要独立定义,彼此间不能共享。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <Home></Home>
        </div>
    
        <script src="vue.js"></script>
        <script>
            var Home = Vue.extend({
               template:"<h1>I am h1!! 显示变量: {{msg}}</h1>",
                data:function () {
                    return {
                        'msg':'I am msg'
                    }
                }
            });
    
            Vue.component('home',Home);
    
            var app = new Vue({
                el:'#app',
                data:{}
            })
        </script>
    </body>
    </html>
    最简单组件

        

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="msg">
            <h1 v-on:click="clickH1">{{msg}}</h1>
            <!-- 第一步 定义容器元素 -->
            <ickt></ickt>
        </div>
        <script type="text/javascript" src="vue.js"></script>
        <script type="text/javascript">
            // 第二步 定义组件类
            var Ickt = Vue.extend({
                template: '<div><input type="text" v-model="msg" /><h1 v-on:click="clickH1">{{msg}}</h1></div>',            // 定义模板
                data: function() {            // 绑定数据
                    return {
                        msg: 'ickt'          // 返回值才是真正绑定的数据
                    }
                },
                methods: {                   // 定义方法
                    clickH1: function() {
                        console.log(222, this)
                    }
                }
            });
    
            // 第三步 注册组件
            Vue.component('ickt', Ickt);
    
            // vue实例化对象
            var app = new Vue({
                el: '#app',
                data: {
                    msg: 'hello'
                },
                methods: {            // 定义方法
                    clickH1: function() {
                        console.log(111)
                    }
                }
            })
        </script>
    </body>
    </html>
    定义组件

    1.2 父组件向子组件间的通信

      1、组件间的通信说明

          1. 组件间通信就是指组件之间是如何传递数据的
              父组件:vue实例化对象
              子组件:自定义组件

          2. 组件的tempalte属性,除了可以是字符串,还可以是元素的id

          3. 我们在页面中定义模板的时候,除了可以定义在script模板标签中,还可以定义在template模板中

          父组件子组件:如果你在一个组件A里面,用到了另外一个组件B,那么B就是A的子组件,A就是B的父组件

       2、父组件向子组件通信:分为以下两步

        1. 第一步

            1. 在组件容器元素上,定义自定义属性,属性值可以传递父组件中的数据

            2. 如果属性使用了v-bind指令,属性值就是js环境

            3. 如果属性没有使用v-bind指令,属性值就是字符串

            <ickt demo="hello" v-bind:parent-msg="msg"></ickt>     # hello 是字符串,  msg是变量

        2. 第二步

            1. 在组件中定义props属性,属性值是数组,每一个成员代表组件容器元素上的一个属性

            2. 作用:将属性作为变量,注册在子组件中,可以在子组件中使用(包括模板)

            3. 注意: 如果属性名称,出现了-, 注册的变量要使用驼峰式命名法

      3、例子说明

          1. 在当页面中注册了子组件:Ickt,在子组件中是无法使用父组件中定义的数据 msg 的

          2. 如果想要在子组件Ickt中使用父组件的 msg 变量,可以使用 <ickt  v-bind:parent-msg="msg"></ickt> 

          3. 在子组件中 使用{{parent-msg}} 就可以访问父组件的msg变量了

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="msg">
            <h1 @click="clickH1">vue:{{msg}}</h1>
    
            <!-- 1 容器 第一步 绑定属性   demo 没有使用v-bind所以是字符串 -->
            <ickt demo="hello" v-bind:parentmsg="msg"></ickt>
        </div>
        <template id="tpl">
            <div>
                <input type="text" v-model="childMsg">
                <h1 @click="clickChildH1">demo: {{childMsg}}</h1>
                <h2>{{demo}}</h2>             <!-- demo 是父组件中的字符串 -->
                <h3>{{parentmsg}}</h3>        <!-- parentmsg 是父组件中的变量 -->
            </div>
        </template>
        <script type="text/javascript" src="vue.js"></script>
        <script type="text/javascript">
            // 2 组件类
            var Ickt = Vue.extend({            // 第二步 注册属性变量
                props: ['demo', 'parentmsg'],
                template: '#tpl',
                data: function() {             // 绑定数据
                    return {
                        childMsg: ''
                    }
                },
                methods: {                     // 绑定事件
                    clickChildH1: function() {
                        console.log(222)
                    }
                }
            });
    
            // 3 注册
            Vue.component('ickt', Ickt);    // 创建vue实例化对象: 父组件
    
            var app = new Vue({
                el: '#app',
                data: {
                    msg: ''
                },
                methods: {                    // 定义方法
                    clickH1: function() {
                        console.log(1111)
                    }
                }
            })
        </script>
    </body>
    </html>
    父组件向子组件通信

    1.3 子组件向父组件通信

       1、1.0中子组件向父组件通信分以下两步

        1. 第一步:注册事件

            在父组件的events属性中 注册消息,参数就是触发是传递的数据,作用域是组件实例化对象

        2.第二步:触发事件

            在子组件中,通过$dispatch方法触发消息

      2、2.0中改变   

          1. 将$dispatch, $broadcast 移除了,新增了$emit, $on, $off

              $emit发布消息

              $on 注册消息: 参数就是$emit传递的数据,作用域就是组件实例化对象

              $off 注销消息

          2. 每一个组件相当于一个事件对象,只能在自身订阅,触发,以及发布

          3. 注意:工作中,注册事件通常在组件生命周期方法中注册,例如created

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="msg">
            <h1 @click="clickH1">vue:{{msg}}</h1>
            <!-- 1 容器 第一步 绑定属性 -->
            <ickt demo="hello" v-bind:parent-msg="msg"></ickt>
        </div>
        <template id="tpl">
            <div>
                <input type="text" v-model="childMsg">
                <h1 @click="clickChildH1">demo: {{childMsg}}</h1>
                <h2>{{demo}}</h2>
                <h3>{{parentMsg}}</h3>
            </div>
        </template>
        <script type="text/javascript" src="vue.js"></script>
        <script type="text/javascript">
            // 2 组件类
            var Ickt = Vue.extend({
                props: ['demo', 'parentMsg'],       // 第二步 注册属性变量
                template: '#tpl',
                data: function() {                   // 绑定数据
                    return {
                        childMsg: ''
                    }
                },
                methods: {                          // 绑定事件
                    clickChildH1: function() {
                        this.$parent.$emit('icktmsg', 'hello', 'everyone')       //2、触发消息
                    }
                }
            });
            // 3 注册
            Vue.component('ickt', Ickt);
    
            var app = new Vue({             // 创建vue实例化对象: 父组件
                el: '#app',
                data: {
                    msg: ''
                },
                methods: {                 // 定义方法
                    clickH1: function() {
                        this.$on('icktmsg', function() {       //1、注册消息
                            console.log(arguments, this)
                        })
                    }
                }
            })
        </script>
    </body>
    </html>
    子组件向父组件通信

    1.4 组件的生命周期 

      1、说明

          1. Vue将组件看成是一个有生命的个体,跟人一样,定义了各个阶段,

          2. 组件的生命周期:组件的创建过程

          3. 组件生命周期钩子函数:当组件处在某个阶段,要执行某个方法,来通知我们,组件进入某个阶段,这个方法就是组件生命周期的钩子函数

          4. 组件的创建过程:这些方法在组件中直接定义,会按照顺序执行,没有参数,作用域都是组件实例化对象

      2、组件生命周期中依次执行的八个钩子函数

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <Home></Home>
        </div>
    
        <script src="vue.js"></script>
        <script>
            var Home = Vue.extend({
               template:"<h1>I am h1!! 显示变量: {{msg}}</h1>",
                data:function () {
                    return {
                        'msg':'I am msg'
                    }
                },
    
                // 方法1:组件实例被创建,组件属性计算之前,如data属性等
                 beforeCreate: function () {
                     console.log(111, this, arguments)
                 },
    
                // 方法2:组件实例创建完成,属性已经绑定,但DOM还未生成,$el 属性还不存在
                 created: function () {
                     console.log(222, this, arguments)
                 },
    
                // 方法3:模板编译/挂载之前
                 beforeMount: function () {
                     console.log(333, this, arguments)
                 },
    
                // 方法4:模板编译/挂载之后(不保证组件已在document中)
                 mounted: function () {
                     console.log(444, this, arguments)
                 },
    
    
                // 方法5:组件更新之前
                 beforeUpdate: function () {
                     console.log(555, this, arguments)
                 },
    
                // 方法6:组件更新之后
                 updated: function () {
                     console.log(666, this, arguments)
                 },
    
                 // 方法9:组件销毁前调用
                 beforeDestory: function () {
                     console.log(777, this, arguments)
                 },
    
                // 方法10:主键销毁后调用
                 destoryed: function () {
                     console.log(888, this, arguments)
                 },
    
    
                // 方法7:组件被激活时调用(用的少)
                // activated: function() {
                //     console.log(777, this, arguments)
                // },
    
                // 方法8:组件被移除时调用(用的少)
                // deactivated: function () {
                //     console.log(888, this, arguments)
                // },
    
    
    
    
            });
    
            Vue.component('home',Home);
    
            var app = new Vue({
                el:'#app',
                data:{
                    'isShow':true,
                }
            })
        </script>
    </body>
    </html>
    组件中八个钩子函数执行顺序

      3、图片展示

         

      4、组件生命周期 常用的两个过程

          1)created: 实例已经创建完成,并且已经进行数据观测和事件配置

          2)mounted:模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Vue生命周期</title>
        <script src="js/vue.js"></script>
        <script>
            window.onload=function(){
                let vm=new Vue({
                    el:'#itany',
                    data:{
                        msg:'welcome to itany'
                    },
                    methods:{
                        update(){
                            this.msg='欢迎来到南京网博!';
                        },
                        destroy(){
                            // this.$destroy();
                            vm.$destroy();
                        }
                    },
                    beforeCreate(){
                        alert('组件实例刚刚创建,还未进行数据观测和事件配置');
                    },
                    created(){  //常用!!!
                        alert('实例已经创建完成,并且已经进行数据观测和事件配置');
                    },
                    beforeMount(){
                        alert('模板编译之前,还没挂载');
                    },
                    mounted(){ //常用!!!
                        alert('模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示');
                    },
                    beforeUpdate(){
                        alert('组件更新之前');
                    },
                    updated(){
                        alert('组件更新之后');
                    },
                    beforeDestroy(){
                        alert('组件销毁之前');
                    },
                    destroyed(){
                        alert('组件销毁之后');
                    }
                });
            }
        </script>
    </head>
    <body>
        <div id="itany">
            {{msg}}
            <br>
    
            <button @click="update">更新数据</button>
            <button @click="destroy">销毁组件</button>
        </div>
    </body>
    </html>
    生命周期执行顺序
  • 相关阅读:
    数据结构3——图
    数据结构2——树
    数据结构1——堆栈和队列
    最大流——Dinic算法
    最大流——EK算法
    网络流——poj1273(入门)
    网络流(进阶)
    网络流
    并查集——poj1182(带权并查集高阶)
    并查集——poj1308(并查集延伸)
  • 原文地址:https://www.cnblogs.com/xiaonq/p/9685234.html
Copyright © 2020-2023  润新知