vue api

vue.nexttick

 

nextTick是全局vue的一个函数,在vue系统中,用于处理dom更新的操作。vue里面有一个watcher,用于观察数据的变化,然后更新dom,vue里面并不是每次数据改变都会触发更新dom,而是将这些操作都缓存在一个队列,在一个事件循环结束之后,刷新队列,统一执行dom更新操作。
通常情况下,我们不需要关心这个问题,而如果想在DOM状态更新后做点什么,则需要用到nextTick。在vue生命周期的created()钩子函数进行的DOM操作要放在Vue.nextTick()的回调函数中,因为created()钩子函数执行的时候DOM并未进行任何渲染,而此时进行DOM操作是徒劳的,所以此处一定要将DOM操作的JS代码放进Vue.nextTick()的回调函数中。而与之对应的mounted钩子函数,该钩子函数执行时所有的DOM挂载和渲染都已完成,此时该钩子函数进行任何DOM操作都不会有个问题。

var nextTick=(function () {
//存储需要触发的回调函数
var callbacks=[];
//是否正在等待的标志(false:允许触发在下次事件循环触发callbacks中的回调,
// true: 已经触发过,需要等到下次事件循环)
var pending=false;
//设置在下次事件循环触发callbacks的触发函数
var timerFunc;
//处理callbacks的函数
function nextTickHandler() {
// 可以触发timeFunc
pending=false;
//复制callback
var copies=callbacks.slice(0);
//清除callback
callbacks.length=0;
for(var i=0;i<copies.length;i++){
//触发callback的回调函数
copies[i]();
}
}
//如果支持promise,使用promise实现
if(typeof Promise !=='undefined' && isNative(promise)){
var p=Promise.resolve();
var logError=function (err) {
console.error(err);
};
timerFunc=function () {
p.then(nextTickHandler).catch(logError);
//iOS的webview下,需要强制刷新队列,执行上面的回调函数
if(isIOS) {setTimeout(noop);}
};
// 如果Promise不支持,但支持MutationObserver
// H5新特性,异步,当dom变动是触发,注意是所有的dom都改变结束后触发
} else if (typeof MutationObserver !=='undefined' && (
isNative(MutationObserver) ||
MutationObserver.toString()==='[object MutationObserverConstructor]')){
var counter = 1;
var observer=new MutationObserver(nextTickHandler);
var textNode=document.createTextNode(String(counter));
observer.observe(textNode,{
characterData:true
});
timerFunc=function () {
counter=(counter+1)%2;
textNode.data=String(counter);
};
} else {
//上面两种都不支持,用setTimeout
timerFunc=function () {
setTimeout(nextTickHandler,0);
};
}
//nextTick接收的函数,参数1:回调函数 参数2:回调函数的执行上下文
return function queueNextTick(cb,ctx) {
//用于接收触发Promise.then中回调的函数
//向回调函数中pushcallback
var _resolve;
callbacks.push(function () {
//如果有回调函数,执行回调函数
if(cb) {cb.call(ctx);}
//触发Promise的then回调
if(_resolve) {_resolve(ctx);}
});
//是否执行刷新callback队列
if(!pending){
pending=true;
timerFunc();
}
//如果没有传递回调函数,并且当前浏览器支持promise,使用promise实现
if(!cb && typeof Promise !=='undefined'){
return new Promise(function (resolve) {
_resolve=resolve;
})
}
}
})
vue.set

因为vue无法探测普通的新增属性(如:this.myObject.newProperty = 'hi'),当我们需要对表格等数据进行动态操作的时候就能用到它。vue.set(target,key,value) (target: 要改变的数据对象或数组,key: 改变前的数据,也就是要更改的具体数据,value: 改变后的数据),在methods中也可以写成this.$set()
vue.delete
参数:
{object | target} target
{string | number} key/index
用法:
删除对象的属性。如果是响应式的。确保删除能触发更新视图,这个方法主要用于避开vue不能检测到属性被删除的限制,这个方法很少使用
data: {
     namelist : {
          id : 1,
   name : ‘百里’
    }
      }
delete this.namelist.name; js的方法
vue.delete(this.namelist, 'name'); vue的方法
vue.mixin
为组件定义可复用的方法,可以在mixin对象里定义组件的任何属性,在组件使用mixin时,mixin中的属性会添加到组件属性中
组件内mixin
<template>
  <div class="mixins">
    <span>{{msg | uppercase}}</span>
  </div>
</template>

<script>
  const myMixin = {
    created(){
      this.hello();
    },
    methods: {
      hello(){
        window.console.log(this.msg)
      }
    }
  };
  export default {
    mixins: [myMixin],
    name: 'mixins',
    data () {
      return {
        msg: 'mixin',

      }
    }
  }
</script>
全局mixin(使用Vue.mixin()方法)
Vue.mixin({
  created(){
    console.log('global mixin')
  }
});
在定义全局mixin之创建的Vue实例都会将mixin对象里的属性添加到实例中new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
});
const Component = Vue.extend({
  template:'<span>121</span>'

});
Vue.mixin({
  created(){
    window.console.log('global mixin')
  }
});
const component=new Component();

这段代码中由于mixin是在App生成之后定义的,只会在创建Component实例的时候才会添加到实例属性中,created执行一次。
vue.watch
对应一个对象,键是观察表达式,值是对应回调。值也可以是方法名,或者是对象,包含选项。在实例化时为每个键调用 $watch() ;
<template>
  //观察数据为字符串或数组
   <input v-model="example0"/>
   <input v-model="example1"/>
  /当单观察数据examples2为对象时,如果键值发生变化,为了监听到数据变化,需要添加deep:true参数
   <input v-model="example2.inner0"/>
</template>
<script>
   export default {
      data(){
        return {
          example0:"",
          example1:"",
          example2:{
            inner0:1,
            innner1:2
          }
        }
      },
      watch:{
        example0(curVal,oldVal){
          console.log(curVal,oldVal);
        },
        example1:'a',//值可以为methods的方法名
        example2:{
         //注意:当观察的数据为对象或数组时,curVal和oldVal是相等的,因为这两个形参指向的是同一个数据对象
          handler(curVal,oldVal){
            console.log(curVal,oldVal)
          },
          deep:true
        }
      },
      methods:{
        a(curVal,oldVal){
          conosle.log(curVal,oldVal)
        }
      }
}
</script>

$children $parent

使用 this.$parent查找当前组件的父组件。
使用 this.$children查找当前组件的直接子组件,可以遍历全部子组件, 需要注意 $children 并不保证顺序,也不是响应式的。
使用 this.$root查找根组件,并可以配合$children遍历全部组件。
使用 this.$refs查找命名子组件。

父组件Game.vue

<template>
<div class="game">
    <h2>{{ msg }}</h2>
    <LOL ref="lol"></LOL>
    <DNF ref="dnf"></DNF>
</div>
</template>
<script>
import LOL from '@/components/game/LOL'
import DNF from '@/components/game/DNF'
export default {
    name: 'game',
    components: {
        LOL,
        DNF
    },
    data () {
        return {
            msg: 'Game',
            lolMsg:'Game->LOL',
            dnfMsg:'Game->DNF',
        }
    },
    methods: {
    
    },
    mounted(){ //注意 mounted
        
        //读取子组件数据,注意$children子组件的排序是不安全的
        console.log(this.$children[0].gameMsg);//LOL->Game
        
        //读取命名子组件数据
        console.log(this.$refs.dnf.gameMsg);//DNF->Game
        
        //从根组件查找组件数据
        console.log(this.$root.$children[0].msg); //APP
        console.log(this.$root.$children[0].$children[0].msg); //Game
        console.log(this.$root.$children[0].$children[0].$children[0].msg); //Game->LOL
        console.log(this.$root.$children[0].$children[0].$children[1].msg); //Game->DNF
    }
}
</script>
<style lang="css">
.game{
    border: 1px solid #00FF00;
    width: 200px;
}  
</style>
子组件LOL.vue
<template>
  <div class="lol">
    <h2>{{ msg }}</h2>
  </div>
</template>

<script>
export default {
    name: 'LOL',
    data () {
        return {
            msg: 'LOL',
            gameMsg:'LOL->Game',
        }
    },
    methods:{

    },
    created(){
        //读取父组件数据
        this.msg = this.$parent.lolMsg;
    }
}
</script>
子组件DNF.vue
<template>
  <div class="dnf">
    <h2>{{ msg }}</h2>
  </div>
</template>

<script>
import Bus from '../../utils/bus.js'
export default {
    name: 'DNF',
    data () {
        return {
            msg: 'DNF',
            gameMsg:'DNF->Game',
        }
    },
    methods:{

    },
    created(){
        //从根组件向下查找父组件数据
        this.msg = this.$root.$children[0].$children[0].dnfMsg;
    }
}
</script>

 
 
posted @ 2019-04-21 21:58  LYCCCCC  阅读(206)  评论(0)    收藏  举报