Vue mounted 钩子内的函数未触发

新手上路,请多包涵
  1. 使用vue 及best scroll做轮播图,其中slider.vue 引用dom.js 的方法, recommend.vue 组件引用slider.vue 组件;slider.vue 下的mounted 内的两个方法未被正常使用,本应该实现为slider下的div增加slider-item的class(如recommend.vue DOM结构的 注释部分),并可以有轮播的功能;
  2. 在slider.vue 下的mounted 内可以alert出内容;在mounted 内的两个方法中增加alert 也可以弹出内容..
  3. 推测可能是因为recommend.vue 中异步获取的图片在展示出来之前,mounted 内的方法已经被调用完了,但是不知道要如何在图片展示后,再次调用slider.vue 下的dom 方法...

代码如下:

recommend.vue

<template>
      <div class="slider-wrapper" v-if="recommends.length !== 0">
        <slider>
          <div v-for="item in recommends"  <!--class="slider-item"-->>
            <a :href="item.linkUrl">
              <img :src="item.picUrl" alt="">
            </a>
          </div>
        </slider>
      </div>
</template>

<script type="text/ecmascript-6">
  import Slider from 'base/slider/slider'
  import { getRecommend } from 'api/recommend'
  import { ERR_OK } from 'api/config'

  export default {
    data () {
      return {
        recommends: []
      }
    },
    created () {
      this._getRecommend()
    },
    methods: {
      _getRecommend () {
        getRecommend().then((res) => {
          if (res.code === ERR_OK) {
            console.log(res.data.slider)
            this.recommends = res.data.slider
          }
        })
      }
    },
    components: {
      Slider
    }
  }
</script>

slider.vue

<template>
  <div class="slider" ref="slider">
    <div class="slider-group" ref="sliderGroup">
      <slot>
      </slot>
    </div>
  </div>
</template>

<script type="text/ecmascript-6">
  import { addClass } from 'common/js/dom'
  import BScroll from 'better-scroll'

  export default {
    mounted () {
      this.$nextTick(() => {
        setTimeout(() => {
//          alert(11)
          this._setSlideWidth()
          this._initDots()
          this._initSlider()
        }, 10)
      })
    },
    methods: {
      _setSlideWidth () {
        this.children = this.$refs.sliderGroup.children
        let width = 0
        let sliderWidth = this.$refs.slider.clientWidth
        for (let i = 0; i < this.children.length; i++) {
          let child = this.children[i]
          addClass(child, 'slider-item')
          child.style.width = sliderWidth + 'px'
          width += sliderWidth
        }
        if (this.loop) {
          width += 2 * sliderWidth
        }
        this.$refs.sliderGroup.style.width = width + 'px'
      },
      _initSlider () {
        console.log(11)
        this.slider = new BScroll(this.$refs.slider, {
          scrollX: true,
          scrollY: false,
          momentum: false,
          snap: true,
          snapLoop: this.loop,
          snapThreshold: 0.3,
          snapSpeed: 400
        })
      }
    }
  }
</script>

dom.js

export function addClass(el, className) {
  if (hasClass(el, className)) {
    return
  }

  let newClass = el.className.split(' ')
  newClass.push(className)
  el.className = newClass.join(' ')
}
export function hasClass(el, className) {
  let reg = new RegExp('(^|\\s)' + className + '(\\s|$)')
  return reg.test(el.className)
}
阅读 6.8k
2 个回答

我一般是这么做的:

//父组件定义一个onload值
onload:false
//父组件获取数据
getData(){
    this.onload = false;
    _api.get(xxx).then(res=>{
    this.onload = true;
    this.data = res.data;
})
}
//把onload传给子组件

<child :onload="onload"></child>

//子组件接收
props:['onload']

//子组件监听
watch:{
    onload(val){
    if(val){
    this.getChildData();
    }
}

}

mounted里的$nextTick是不会被触发的,mounted是表示这个组件已经挂载到dom上了,这个时候你注册了一个$nextTick,那就只有等下一次dom被更新的时候才会被执行到

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题