三十六-四十:组件生命周期钩子函数和图解
四十一、使用$refs获取DOM元素
四十二、使用$nextTick的特殊情况
三十六-四十:组件生命周期钩子函数和图解
<body> <div id="main"> <App /> <!--App也可以写在这里!template里面为空--> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var Test = { data(){ return{ msg:'哈哈哈', } }, template:`<div id="test"> <h3>{{msg}}</h3> <button type="button" @click="clickHandler">修改msg</button> </div> `, methods:{ clickHandler(){ this.msg += 'alex' } }, //组件创建之前 用的不多 beforeCreate() { //一般不用 console.log('组件创建前:'+this.msg); //undefined }, //组件创建之后 created() { //可以操作数据,发送ajax请求,并且可以实现 //vue对页面的影响 应用:发送ajax请求 console.log('组件创建后:'+this.msg); //哈哈哈 }, //装载数据到DOM之前 用的不多 beforeMount() { console.log('DOM装载前:'+document.getElementById('app')); //null }, //装载数据到DOM之后 mounted() { //可以操作DOM console.log('DOM装载后:'+document.getElementById('app')); //<div id="app"><div id="test"></div></div> }, //获取更新之前的DOM beforeUpdate() { console.log('DOM更新前:'+document.getElementById('test').innerHTML); //<h3>哈哈哈</h3> <button type="button">修改</button> }, //获取更新之后的DOM updated() { console.log('DOM更新后:'+document.getElementById('test').innerHTML); //<h3>哈哈哈alex</h3> <button type="button">修改</button> }, //组件被销毁前 用的不多 beforeDestroy() { console.log('组件销毁前'); //点按钮“创建和销毁” 没有用keep-alive,性能不好 }, //组件被销毁后 用的不多 destroyed() { console.log('组件销毁后'); //点按钮“创建和销毁” 没有用keep-alive,性能不好 }, //组件被激活后 要用就用这个 activated() { console.log('组件被激活了'); //点按钮“创建和销毁” 用keep-alive,性能好 }, //组件被停用后 要用就用这个 deactivated() { console.log('组件被停用了'); //点按钮“创建和销毁” 用keep-alive,性能好 } }; var App={ data(){ return { isShow:true, } }, //使用keep-alive将DOM缓存,性能好一些 template:`<div id="app"> <keep-alive><Test v-if="isShow" /></keep-alive> <button type="button" @click="isShow=!isShow">创建和销毁</button> </div>`, components:{ Test }, }; new Vue({ el: '#main', template:'', components:{ App } }); </script> </body>
组件的生命周期:
说明:虚拟DOM渲染速度比jQuery的DOM快,所以现在都使用js框架,而不使用jQuery
四十一、使用$refs获取DOM元素
<body> <div id="main"> <App /> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var Test = { template:`<div id="test"></div>` }; var App={ template:`<div id="app"> <Test ref="test"/> <button ref="btn">按钮</button> </div>`, beforeCreate() { console.log(this.$refs.btn); //undefined }, created() { console.log(this.$refs.btn); //undefined }, beforeMount() { console.log(this.$refs.btn); //undefined }, mounted() { //可以通过ref属性获取按钮的DOM对象 console.log(this.$refs.btn); //<button>按钮</button> console.log(this.$refs.test); //给组件绑定ref属性,得到组件的Vue对象 VueComponent {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} }, components:{ Test }, }; new Vue({ el: '#main', template:'', components:{ App } }); </script> </body>
四十二、使用$nextTick的特殊情况
this的属性说明:
$refs:获取组件内的元素
$parent:获取当前组件的父组件
$children:获取当前组件的子组件
$root:获取new Vue的实例化对象
$el:获取组件对象的DOM元素
如果要获取数据更新导致的DOM更新后的新DOM对象需要使用$nextTick回调
<body> <div id="main"> <App /> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var App={ data(){ return{ isShow:false } }, template:`<div id="app"> <input type="text" v-if="isShow" ref="fos"> </div>`, mounted() { this.isShow = true; // this.$refs.fos.focus(); //先更新DOM,然后直接这样写获取不了焦点。 // 因为实现相应式并不是数据发生变化后DOM立刻发生变化, //而是在$nextTick下次DOM更新结束之后的延迟回调,在回调函数中获取数据更新之后的DOM this.$nextTick(function () { this.$refs.fos.focus(); }) }, }; new Vue({ el: '#main', template:'', components:{ App } }); </script> </body>