Vue2.0基础知识

小白新手常规操作之笔记摘要!!本文主要总结了Vue2.0最最最最基础知识

1、Vue2.0在页面标签的用法

<!DOCTYPE html>
<html>
    <head>
        <!DOCTYPE html>
        <title>Vue.js基础指令</title>
        <link rel="icon" href="/Vue.js/favicon.ico" /><!--title的图标设置-->
        <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
        <style type="text/css">
            .class1 {
                background: #444;
                color: #eee;
            }
        </style>
    </head>
    <body>
        <div id="vue_det" style="width: 100%;margin:auto;">
            <!--{{}}绑定数据-->
            <!--{{}}绑定数据也可以是有返回值的函数方法-->
            <h1>site : {{site}}</h1>
            <h2>{{details()}}</h2>

            <!--v-model作用:实现双向绑定-->
            <span>v-model双向绑定</span>
            <label for="r1"></label>
            <input type="checkbox" v-model="use" id="r1">
            <br />
            <span>v-bind单向绑定</span>
            <!--v-bind 单向绑定,数据只能从data流向页面-->
            <input type="checkbox" :value="use" id="r1">
            <br />
            <p> v-model.lazy修饰符</p>
            <!--修饰符:lazy作用:只有当文本框内容完成(鼠标聚焦事件和回车事件),p标签内容才会改变-->
            <input v-model.lazy="texttitle" />
            <p>文本框内容:{{texttitle}}</p>

            <!--v-once指令,初次动态渲染后,就视为静态内容,
            以后的数据改变不会引起v-once所在结构的更新-->
            <p v-once><span>v-once指令&nbsp;</span>{{texttitle}}</p>

            <!--v-bind:属性名=‘表达式’简写为>>>:属性名=‘表达式’  作用:属性绑定-->
            <!-- <div v-bind:class="{'class1':use}">v-bing:class 指令</div> -->
            <div :class="{'class1':use}">v-bing:class 指令</div>

            <!--v-if满足条件才会渲染到HTML -->
            <p v-if="isIf">if隐藏与显示</p>
            <!--v-show始终渲染到HTML-->
            <p v-show="isShow">Show隐藏与显示</p>

            <br />
            <p>【for循环:】</p>
            <!--此处的in可以修改为of-->
            <!--【(value,name,index) in object】比较 item in object-->
            <!--(value,name,index) in object:输出的是下标,属性名称,对应的值;
             item in object:输出的是:对应的值
             (value,name) in object:输出的是属性名称,对应的值;-->
            <div v-for="(value,index) in object" v-if="index!=2">
                {{index}}.{{value}}
            </div>



            <!--计算属性(computed)和方法函数(methods)调用最大的明显的区别是有无括号
            例如:页面调用:methods--》方法名(),
                            computed--》方法名
            -->
            <!--cimputed基于缓存,相关依赖发生时才会取值-->
            <p>【计算属性(computed)和方法函数(methods)】</p>
            <p>原始字符:{{Messgae}}</p>
            <p>计算后反转字符{{reversedMessage}}</p>
            <p>使用方法后反转字符{{reversedMessage2()}}</p>
            <p><button @click="getSetMessage='你好呀'">改变计算属性的值</button> </p>

            <p>【过滤器】</p>
            <!--v-text 作用:用于输出纯文本元素,v-html 作用:用于输出HTML元素-->
            <!--过滤器  过滤器也可以串联。可以用在v-bind指令中-->
            <!--,过滤器也可以进行传值,如:{{a | filter('b','c')}},filter接收的第一个参数是a,依次是b,c-->
            <p v-bind:id="rawId | formatId" style="background-color: #444;color: white;">
                {{Messgae | capitalize | capitUpper('测试','YJ')}}
            </p>

            <!--v-on:事件名称=‘函数名称’简写为>>>@事件名称=‘函数名称’ 作用:监听DOM事件-->
            <!-- <button v-on:click="onclickMessgae" style="width: 120px;height: 20px;">反转字符</button> -->
            <button @click="onclickMessgae" style="width: 120px;height: 20px;">反转字符</button>
            <button @click="onclickCS('测试')" style="width: 120px;height: 20px;">带参数的click</button>

            <!--原生js阻止冒泡>>>>>>使用Vue阻止冒泡:@click.stop=‘方法名’-->
            <!-- 冒泡发生的情景:子元素和父元素绑定了相同的事件,然后点击了子元素,父元素也触发了该事件 -->
            <div @click="ZuZhiMP" style="width: 120px;border: 1px solid cadetblue;">
                外层div
                <div @click="ZuZhiMP" style="width: 120px;border: 1px solid cadetblue;">
                    里层div
                </div>
            </div>

            <!--阻止默认行为>>>>>使用Vue阻止默认行为:href.prevent='地址' -->
            <a href="http://www.baidu.com" @click="ZuZhiAction">百度</a>

            <!-- 一次事件,只会执行一次 -->
            <div @click.once="OneEvent">一次事件</div>

            <!--capture 在父子事件中,加【capture】无论先点哪一个,都会先执行这个-->
            <div @click.capture="OneEvent">外层div执行顺序
                <div @click="OneEvent">内嵌div</div>
            </div>

            <!--监听事件-->
            <p style="font-size: 25px;">计数器:{{counter}} <input type="text" v-model="counter"></p>

            <button @click="counter++" style="font-size: 25px;">监听属性</button>

            <!-- //注册全局自定义指令 v-focus -->
            <p>全局指令 v-focus:<input type="text" v-focus></p>


            <!-- 自定义全局组件 -->
            <div>
                <input type="text" v-model="texttitle">
                <br />
                <child v-bind:message="texttitle"></child>
            </div>

            <p>组件和for循环:</p>
            <div>
                <!--ref设置:允许我们获取对DOM元素、子组件实例或Vue实例的引用,
                以便在Vue组件的方法中进行操作或者访问-->
                <input type="text" v-model="name" ref="Inputname">   
                <button @click="add">添加</button>
                <todo-item v-for="item in items" v-bind:todo="item">
                </todo-item>
            </div>
            <p>单纯的for循环</p>
            <!--key 的作用:
            更新组件时判断两个节点是否相同,相同就复用
            不同就删除创建新的-->
            <ul>
                <input type="text" v-model="name">
                <button @click="add">添加</button>
                <input type="text" v-model="keyWord" placeholder="请输入名称">
                <button @click="UpdateBork">更换数据</button>
                <!--不加key,添加时,原本勾选的会变成已经添加的,加key时,文本框添加后,还是原本勾选的-->
                <li v-for="item in items" :key="item.id">
                    <input type="checkbox" />{{item.name}} | {{item.age}}
                </li>

                <p>搜索结果:</p> <!--模糊查询此处的v-for不是data的数据,而是事件里面的函数-->
                <li v-for="item in fileitems" :key="item.id">
                    <input type="checkbox" />{{item.name}} | {{item.age}}
                </li>
            </ul>


            <!-- 自定义局部组件 -->
            <div>
                <runoob></runoob>
            </div>

            <p v-color="curColor">我自定义参数</p>

             <!--ref和this.$nextTick()的用法-->
             <p>ref和this.$nextTick()的用法</p>
             <button ref="tar" type="button" name="button"
             @click="testClick">{{testTick}}</button>
        </div>
        <br /><br />

        <script type="text/javascript">
            //注册组件 (全局)    组件名称
            Vue.component('child', {
                //props是子组件用来接受父组件传递过来的一个自定义属性
                //父组件的数据通过props传子组件,子组件显示,需要声明props
                props: ['message'], //声明
                template: '<span>{{message}}</span>'
            })
            Vue.component('todo-item', {
                props: ['todo'],
                template: '<li><input type="checkbox"> {{todo.name}}</li>'
            })

            //局部组件
            var Child = {
                template: '<h5>局部组件</h5>'
            }


            //注册全局自定义指令 v-focus
            Vue.directive('focus', {
                //当绑定元素插入到DOM中 
                //inserted:绑定指令的元素被添加到父元素上的时候执行
                //(指业务逻辑代码中用到了元素事件)
                //el -->被绑定指令的那个元素
                inserted: function(el) {
                    //聚焦元素
                    el.focus();
                }
            });
            //自定义参数
            Vue.directive('color', {
                //bind:指令被绑定到元素上的时候执行(指令业务逻辑
                //代码中没有用到元素事件)
                //el -->被绑定指令的那个元素
                bind: function(el, obj) {
                    el.style.color = obj.value;
                }
            })

            //全局过滤器
            Vue.filter('capitUpper', function(value, a, b) {
                //console.log(a+b);
                if (!value) return '';
                value = value.toString();
                return value + '1234';
            })

            var cnt = 1;
            var data = {
                site: "Vue教程",
                use: false,
                isIf: false,
                Messgae: "zxcvb",
                isShow: false,
                counter: 1,
                texttitle: '事件',
                rawId: 'someHoId',
                newId: 3,
                name: '',
                keyWord: '',
                curColor: 'green',
                testTick:'初始值',
                object: { //对象
                    title: 'How to',
                    Name: 'Jone Doe',
                    age: '12'
                },
                items: [{ //数组
                        id: '1',
                        name: 'Alice',
                        age: 25
                    },
                    {
                        id: '2',
                        name: 'Bob',
                        age: 30
                    },
                    {
                        id: '3',
                        name: 'Charlie',
                        age: 35
                    }
                ]

            };
            //data:{}和data(){return{}},最大的区别是组件数据的共享
            //data:{}是对象方式定义数据,父子组件时,修改一个data的属性另一个data属性也会修改;
            //data(){return{}}是函数方式定义数据,每一个组件都会调用一次data函数,返回新的data对象
            // var 定义也可以省去。
             //export default {}是在构建工具中使用。
            var vm = new Vue({ //Vue的"V"大写
                //el,template,render函数的优先级:el<template<render.
                //例如:el和template同时存在,会显示template的内容。
                //template: "<div id='haha'>SVYJ</div>",
                //vm.$mount("#vue_det")和el:'',作用是一样的
                //如果el和$mount都存在,绑定的元素有差异,那么以el为主,
                el: '#vue_det', //标签对应的id  绑定节点,el不存在时才会使用vm.$mount("#vue_det")
                // render: function(createElement) {
                //     return createElement('h1', '我是render出来的HTML,年龄' + this.site);
                // },
                //对象的方式
                data: data,
                //函数的方式
                // data(){
                //     return{
                //         site: "菜鸟教程",
                //         use: false,
                //         isIf: false,
                //         Messgae: "zxcvb",
                //         isShow: false
                //     }
                // },

                //局部组件
                components: {
                    'runoob': Child
                },
                //局部过滤器
                filters: {
                    capitalize: function(value) {
                        if (!value) return '';
                        value = value.toString();
                        return value.charAt(0).toUpperCase() + value.slice(1);
                    },
                    //对象,过滤器
                    formatId(value) {
                        return `SC-${value}` //此处的是``,而不是‘’,单引号
                    }

                },
                //函数方法 methods和computed,效果是一样的,但是,computed是基于缓存的
                methods: {
                    //ES6+语法-->UpdateBork() {}
                    //JavaScript对象-->UpdateBork:function(){}
                    //以上两种方式都可以
                    //函数
                    details: function() {
                        return this.site + " - 学的不仅是技术,更是梦想!";
                    },
                    //有返回值的点击事件
                    onclickMessgae: function() {
                        //split('') 报数据拆分为数组
                        //reverse(),反转的意思,只对数组有效,所以要跟在split('')后面
                        //join('') 重组,把数组合成一个字符串
                        return this.Messgae = this.Messgae.split('').reverse().join('');
                    },
                    //有参数的点击事件
                    onclickCS(a) {
                        alert(a);
                    },
                    //阻止冒泡
                    ZuZhiMP(event) {
                        alert('测试!')
                        //使用Vue阻止冒泡时,注销这段
                        //event.stopPropagation(); //原生js阻止冒泡
                    },
                    //阻止默认行为
                    ZuZhiAction(event) {
                        alert('不可跳转')
                        event.preventDefault(); //阻止原生js默认行为
                    },
                    //一次事件,只会执行一次
                    OneEvent(event) {
                        alert('一次事件!')
                    },
                    reversedMessage2: function() {
                        cnt += 1;
                        return cnt + '-' + this.Messgae.split('').reverse().join('');
                    },
                    //添加
                    add() {
                        //push(),末尾添加N个元素,console.log(this.item.push({}))并返回新的长度
                        //unshift(),向数组的开头添加N个元素,并返回新的数组长度
                        this.items.unshift({
                            id: ++this.newId,
                            name: this.name,
                            age: ++this.newId,
                        })
                        //console.log(this.$refs.Inputname);
                        //shift(),用于删除数组的第一个元素 console.log(this.items.shift()),并返回值
                        //pop(),删除数组的最后一个元素,console.log(this.items.pop())并返回值

                        //splice(1)-->保留前一个元素之后的全部删除
                        //splice(2,1)-->从索引位置(index:2)删除,删除一个元素
                        //splice(1,2,'a','b')-->从索引位置(index:1)删除,删除两个元素,并添加两个元素替代被删除的元素
                        //splice(1,0,'a')-->从索引位置(index:1)添加,添加两个元素

                        //reverse() 颠倒数组中元素的顺序  this.items.reverse()
                    },
                    //事件:ref和this.$nextTick的用法
                    testClick(){
                         this.testTick='改变了的值';
                         //这时候直接打印,由于dom还没有更新
                         //值还是改变之前的值
                         console.log(this.$refs.tar.innerText);
                         
                         //this.$nextTick方法是当数据被修改后使用这个方法
                         //会回调获取更新后的dom在渲染出来
                         this.$nextTick(()=>{
                             //dom元素更新后执行,这里打印的是更新之后的值
                             console.log(this.$refs.tar.innerText);
                         })
                         
                    },
                    //Vue的更新语法,暂有问题
                    UpdateBork() {
                        //Vue.set(this.items, 1, 'sss');
                        //this.$set('对象','属性','值'); 或 this.set('对象','属性','值');

                    }
                },
                //1、在实例化之前被调用
                beforeCreate: function() {
                    //这个方法的时候data还没有加载,所以此方法一般用不到
                    console.log("[beforeCreate]组件实例化之前执行的函数");
                },
                //2、实例被创建后调用
                //实例化初始之后,被添加到DOM元素之前触发
                created: function() {
                    console.log("[created]组件实例化完毕,但是页面还没有显示");
                },
                //3、在元素*(虚拟DOM)已经准备好被添加到DOM,但是还没有添加时触发
                beforeMount: function() {
                    //要保证有el,或者vm.$mount(),负责这里不会执行
                    console.log("[beforeMount]组件挂载前,但页面还未显示,但是虚拟的DOM已经配置");
                },
                //4、html加载完成后执行,执行顺序:子组件-父组件
                mounted: function() {
                    //  如果有template属性模板,会用模板替换外部的el,
                    //只要有此属性,直接卸载外部el找中的内     
                    // 这将没有任何意义了          
                    //  template只能有一个更元素,不能是文本节点,      
                    // 真实的dom渲染完了,可以操作dom了 
                    console.log("[mounted]组件挂载后,此方法执行后,页面显示");
                },
                //5、数据更新将要对DOM做一些修改时的触发
                //数据发生改变,还没有渲染之前
                 beforeUpdate: function() {
                    //当页面依赖的数据发生变化时才执行,一般用watch来替换,这个方法不好用
                    //页面依赖的数发生变化,数据已变化,页面还没有渲染
                    console.log("[beforeUpdate]组件更新前,但是页面还没有显示,但是虚拟DOM已配置")
                },
                //6、在DOM的更新已经完成后触发
                //数据重新渲染之后
                updated: function() {
                    //重新渲染页面后执行,可以执行操作DOM
                    console.log("[updated]组件更新后,此方法执行后, 页面显示");
                },
                //7、在组件即将被销毁并且从DOM上移出时触发
                beforeDestroy: function() {
                    console.log("[beforeDestroy]组件销毁前")
                },
                //8、组件被销毁后触发
                destroyed: function() {
                    console.log("[destroyed]组件销毁");
                },
                //计算属性,
                computed: {
                    reversedMessage: function() {
                        cnt += 1;
                        return cnt + '-' + this.Messgae.split('').reverse().join('');
                    },
                    //模糊查询
                    fileitems() {
                        return this.items.filter((p) => {
                            return p.name.indexOf(this.keyWord) !== -1
                        })
                    },
                    //计算属性中get和set
                    getSetMessage: {
                        ////getter
                        get: function() {
                            return this.Messgae.split('').reverse().join('');
                        },
                        //// setter
                        set: function(newValue) { //例如:点击事件传的参数
                            this.Messgae = newValue;
                        }
                    }
                },
                //监听事件
                watch: {
                    // (1).Vue中的watch默认不监测对象内部值的改变(一层)。
                    // (2).配置deep:true可以监测对象内部值改变(多层)。
                    // 备注:
                    // (1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
                    // (2).使用watch时根据数据的具体结构,决定是否采用深度监视。
                    counter: function(val) {
                        deep: true, //深度监视
                        console.log((val));
                    },

                }

            });
            //document.write(vm.$data==data) // true
            //监听事件
            vm.$watch('counter', function(nval, oval) {
                alert('计数器的变化:' + oval + '变为' + nval + '');

            })
        </script>








    </body>
</html>

2、Vue2.0钩子方法的讲解

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>钩子函数的介绍</title>
    </head>
    <body>
        <!-- 前沿:
        通过前面几节的学习,我们已经对vue有了初步的了解,vue可以帮我们干什么,
                而接下来就介绍vue的生命周期和它常用的钩子函数,
        那么我们就来看看对于vue的生命周期.

        1. 理解生命周期的含义
        生命周期:就是一个组件从实例化创建并添加到DOM开始 ,一直到组件被销毁的整个过程 。
        生命周期函数(钩子函数): 就是在Vue生命周期的整个过程的不同阶段被调用的函数

        2. 生命周期图
        首先来一下官网的对于vue生命周期的图解, 官网上目前有8个生命周期函数,
        还有两个我们之后再看. 先看看基本的8个钩子函数

        3. 钩子函数的理解
        通过打断点的方式,让我们好好理解声明周期的钩子函数,
        你们也可以自己复制代码进行测试好好理解Vue的钩子函数 -->

        <script>
            new Vue({
                el: "#app",
                data: {},
                methods: {},
                // 1. 在实例化之前被调用       
                beforCreate: function() {
                    // 这个方法的时候data还没有加载,所以此方法用不到      
                    // 一般不会再这里处理什么事情     
                    alert("组件实例化之前执行的函数");
                    debugger;
                },
                // 2. 实例化初始之后,被添加到DOM元素之前触发        
                created: function() {
                    // 可以在这里发送ajax,初始化操作         
                    alert("组件实例化完毕,但页面还未显示");
                    debugger;
                },
                // 3. 在元素(虚拟DOM)已经准备好被添加到DOM,但是还没有添加时触发      
                beforeMount: function() {
                    // 要保证有el,或者vm.$mount() 否则这里不会执行         
                    alert("组件挂载前,但页面还未显示,但是虚拟DOM已经配置");
                    debugger;
                },
                // 4. 会在元素创建后触发  
                mounted: function() {
                    //  如果有template属性模板,会用模板替换外部的el,
                    //只要有此属性,直接卸载外部el找中的内     
                    // 这将没有任何意义了          
                    //  template只能有一个更元素,不能是文本节点,      
                    // 真实的dom渲染完了,可以操作dom了        
                    alert("组件挂载后,此方法执行后,页面显示");
                    debugger;
                },
                // 5. 在数据更新将要对DOM做一些修改时触发     
                beforeUpdate: function() {
                    //  当页面依赖的数据发生变化时才执行,一般用watch来替换,这个方法不好用   
                    // 页面依赖的数据发生变化,数据已变化,页面还没有渲染           
                    alert("组件更新前,但页面还未显示,但是虚拟DOM已经配置");
                    debugger;
                },
                // 6. 后在DOM的更新已经完成后触发     
                updated: function() {
                    // 重新渲染页面后执行, 可以操作DOM了           
                    alert("组件更新后,此方法执行后,页面显示");
                    debugger;
                },
                // 7. 在组件即将被销毁并且从DOM上移出时触发       
                beforeDestroy: function() {
                    //没什么意义,死了就什么都干不了了         
                    alert("组件销毁前");
                    debugger;
                },
                // 8. 组件被销毁后触发     
                destroyed: function() {
                    alert("组件销毁");
                    debugger;
                }
            })
        </script>

        <!--4. 绑定节点
        我们之前学到一直是使用vue配置对象里的el来绑定DOM节点
        生命周期图告诉我们,如果我们没有el属性就会查找vue实例对象有没有通过$mount方法来绑定DOM元素
        其实就算你是用el绑定了DOM元素,在Vue源码中也是会转为$mount处理 -->

        <div id="app">
            <div v-html="msg"></div>
        </div>
        <div id="haha"></div>
        <script>
            const vm = new Vue({
                el: "#app",
                data: {
                    msg: "hello"
                },
            }) vm.$mount("#haha")
        </script>
        <!-- 同时我们还会发现,如果el和$mount都存在,绑定的元素有差异,那么以el为主,
        因为生命周期图告诉我们只有当el属性不存在的时候,才会查看$mount方法 -->

        <!--5. template模板编译
        我们之前学习一直使用的都是没有template模板的, 根据生命周期图显示,
        如果我们没有template,模板,我们就会将el 属性对应的挂在点作为我们的模板
        如果有template模板,我们就会用以后的模板替换之前的模板 -->

        <div id="app"> {{ msg }}</div>
        <script>
            const vm = new Vue({
                el: "#app",
                template: "<div id='haha'>我是小当家</div>",
                data: {
                    msg: "hello"
                },
            })
        </script>


        <!-- 5.1 注意template模板里只能有一个根标签
        所以下面的写法会报错,是错误的写法 -->
        const vm =
        new Vue(
        {
        template:` <div id='haha'> 我是小当家 </div> <span></span> `,
        data: { msg:"hello" },
        }
        )


        <!-- 5.2 改变数据绑定的位置
        如果有template 模板,我们动态绑定的数据,就需要在模板中绑定 -->

        <div id="app"> {{ msg }}</div>
        <script>
            const vm = new Vue({
                el: "#app",
                template: "<div id='haha'>我是小当家{{ msg }}</div>",
                data: {
                    msg: "hello"
                },
            })
        </script>


        <!-- 6. 关于mounted钩子函数中获取DOM元素的问题
        6.1 正常在mounted钩子函数里获取DOM -->
        <div id="app">
            <div v-html="msg"></div>
        </div>
        <script>
            const vm = new Vue({
                el: "#app",
                data: {
                    msg: "<h2 id='box'>hello</h2>"
                },
                mounted() {
                    console.log("mounted:");
                    console.log(box);
                },
            })
        </script>
        <!-- 我们会发现获取DOM元素完全没有问题,

        6.2 更改DOM节点内容
        如果我们动态的修改了DOM节点,那么我们在获取看看 -->

        <div id="app">
            <div v-html="msg"></div>
        </div>
        <script>
            const vm = new Vue({
                el: "#app",
                data: {
                    msg: "<h2 id='box'>hello</h2>"
                },
                mounted() { // 动态修改DOM 节点          
                    this.msg = `<h2 id="box">你好</h2>`
                    // 获取DOM 节点        
                    console.log(box);
                },
            })
        </script>
        <!-- 这是我们就会发现我们获取的还是原先的DOM节点, 
        此时去获取节点内容就会有问题,
        获取的DOM节点并不是更改后最新的DOM节点



        6.3 解决动态DOM 节点的问题
        我们可以使用$nextTice来解决此类问题

        在下次 DOM 更新循环结束之后执行延迟回调。
        在修改数据之后立即使用这个方法,
        获取更新后的 DOM。
        $nextTick(),是将回调函数延迟在下一次dom更新数据后调用,
        简单的理解是:数据更新后,在dom重新渲染完毕,自动执行该函数,
        通过$nextTick 方法来异步操作vue实例

        示例: -->

        <div id="app">
            <div v-html="msg"></div>
        </div>
        <script>
            const vm = new Vue({
                el: "#app",
                data: {
                    msg: "<h2 id='box'>hello</h2>"
                },
                mounted() {
                    // 动态修改DOM 节点           
                    this.msg = `<h2 id="box">你好</h2>`
                    // 获取DOM 节点            console.log(box);        
                    // 通过$nextTick异步处理方法来获取就会得到最新的值     
                    this.$nextTick(() => {
                        console.log(box);
                    })
                },
            })
        </script>
        
        <!-- 上面的示例,我们打印了2次box ,box是DOM元素的id,可以用来获取DOM元素, 
        但是此时两次获取的DOM元素展示的结果不一样
        $nextTick.png
        第一次获取box虽然数据已经改变, 页面也准备重新渲染新的DOM元素, 
        但是此时DOM还没有更新完成,就获取box,获取的就是原来的DOM元素内容,
        $nextTick方法会在DOM元素更新完成以后才会触发回调函数,
        在回调函数中获取的box才是更改后最新的DOM元素
        建议在组件学习后在回来看:
        带有子组件的示例: -->

        <div id="app">
            <child ref="child"></child>
        </div>
        <template id="child">
            <div> <span v-for="a in arr">{{a}}</span> </div>
        </template>
        <script>
            var vm = new Vue({
                // 根实例      
                el: '#app',
                data: {
                    radio: 'home',
                },
                mounted() {
                    console.log(1);
                    // 在执行父组件的mounted    
                    // console.log(this.$refs.child.$el.innerHTML);       
                    // 这里打印的是 1,2,3的数组          
                    // 这里可以选择$nextTick方法,这个是在页面渲染完毕后执行    
                    this.$nextTick(() => {
                        console.log(this.$refs.child.$el.innerHTML);
                        // 这个时候才4,5,6       
                    })
                },
                components: {
                    child: {
                        template: '#child',
                        data() {
                            return {
                                arr: [1, 2, 3]
                            }
                        },
                        mounted() {
                            console.log(
                                2);
                            // 先打印子组件的mounted        
                            this.arr = [4, 5, 6];
                            // 说明这里mounted是异步的     
                        }
                    }
                }
            });
        </script>

    </body>
</html>

 

posted @ 2025-05-01 22:50  小鱼记忆  阅读(40)  评论(0)    收藏  举报