airyland / vux

Mobile UI Components based on Vue & WeUI
https://vux.li
MIT License
17.59k stars 3.71k forks source link

使用previewer时,如果组件放在v-for中,会报not a function的错误 #1352

Closed ghost closed 7 years ago

ghost commented 7 years ago

在template其他任意部位使用都是正常的,但在v-for循环中使用,则会出现

 Uncaught TypeError: this.$refs.previewer.show is not a function
airyland commented 7 years ago

用 v-for 之后每个组件用同个名字的 ref: ref="previewer" 能这样调用?

ghost commented 7 years ago

并没有用相同的ref,使用index作为ref的值

 <img class="previewer-demo-img" v-for="(item, index) in aaa" :src="item.src" width="100" @click="show(index)">
  <previewer :list="aaa" ref="index" :options="options"></previewer>

调用时

show (index) {
      this.$refs.0.show(index)
      this.$refs.1.show(index)
    },
ghost commented 7 years ago

还尝试了

  <div>
                    <img class="previewer-demo-img" v-for="(item, i) in aaa" :src="item.src" width="100" @click="show(i)">
                    <previewer :list="aaa" ref="'previewer'+index" :options="options"></previewer>
                  </div>       

 show (index) {
      this.$refs.previewer0.show(index);
      this.$refs.previewer1.show(index);
    }, 

请问在v-for中应该如何调用previewer呢?

ghost commented 7 years ago

已找到原因,调用时

<div>
                    <img class="previewer-demo-img" v-for="(img, index) in aaa" :src="img.src" width="100" @click="show(index,i)">
                    <previewer :list="aaa" ref="previewer" :options="options"></previewer>
                  </div>   
    show (index,i) {
      this.$refs.previewer[i].show(index)
    },
airyland commented 7 years ago

这是 js 的最基础问题:

this.$refs.0.show(index)

这是 vue 姿势错误,变量请加上冒号:

ref="'previewer'+index"

下次如果提 issue 麻烦带上代码,千万不要对自己写的代码有迷之自信。

ghost commented 7 years ago

ref="'previewer'+index"这种方式已尝试过,调用时用this.$refs.previewer0.show(index),报无法找到show方法的错误。 出现该问题的原因应该是因为this.refs取到的dom元素是数组,在使用v-for时不应该使用单个方式去调用

airyland commented 7 years ago

我上面说了你这是 Vue 错误姿势。

:ref="'previewer'+index"
ghost commented 7 years ago

不好意思,再次打扰

<div>
                     <img class="previewer-demo-img" v-for="(img, index) in item.imgList" :src="img.src" width="40" height="40" @click="show(index,i)">
                     <previewer :list="item.imgList" :ref="'previewer' +i" :options="options"></previewer>
                   </div>  

  show (index,i) {
      this.$refs.previewer0.show(index);
    },

依然报这个错误

this.$refs.previewer0.show is not a function
ghost commented 7 years ago

我尝试过不同方式的调用 还包括使用v-if 判断i = 0 时,ref=previewera,i=1时,ref=previewerb,调用时使用

$refs.previewera.show(index);
$refs.previewerb.show(index);

这些均会报show undefined或者not a function的错误 目前只有使用数组

 this.$refs.previewer[i].show(index)

这种方式调用表现正常

ghost commented 7 years ago

完整代码

<template>
  <div>
  <div v-for='(item,i) in bbb'>
     <img class="previewer-demo-img" v-for="(img, index) in list" :src="img.src" width="100" @click="show(index)">
    <previewer :list="list" :ref="'previewer'+i" :options="options"></previewer>
  </div>
  </div> 
</template>

<script>
import { Previewer } from 'vux'
export default {
  components: {
    Previewer
  },
  methods: {
    show (index) {
      this.$refs.previewer0.show(index)
      this.$refs.previewer1.show(index)
    }
  },
  data () {
    return {
      list: [{
        src: 'http://pic.xiami.net/images/album/img10/3110/21003372621469680510.jpg?x-oss-process=image/resize,limit_0,m_pad,w_185,h_185',
        w: 600,
        h: 400
      },
      {
        src: 'https://img.alicdn.com/tps/TB1Q5DVNpXXXXbjXVXXXXXXXXXX-185-100.png',
        w: 1200,
        h: 900
      }],
      bbb:[
        {name:111},
        {age:23}
      ],
      options: {
        getThumbBoundsFn (index) {
          // find thumbnail element
          let thumbnail = document.querySelectorAll('.previewer-demo-img')[index]
          // get window scroll Y
          let pageYScroll = window.pageYOffset || document.documentElement.scrollTop
          // optionally get horizontal scroll
          // get position of element relative to viewport
          let rect = thumbnail.getBoundingClientRect()
          // w = width
          return {x: rect.left, y: rect.top + pageYScroll, w: rect.width}
          // Good guide on how to get element coordinates:
          // http://javascript.info/tutorial/coordinates
        }
      }
    }
  }
}
</script>
ghost commented 7 years ago
<template>
  <div>
  <div v-for='(item,i) in bbb'>
  <div v-if='i==0'>
     <img class="previewer-demo-img" v-for="(img, index) in list" :src="img.src" width="100" @click="show(index)">
    <previewer :list="list" ref="previewera" :options="options"></previewer>
  </div>
  <div v-if='i==1'>
     <img class="previewer-demo-img" v-for="(img, index) in list" :src="img.src" width="100" @click="show(index)">
    <previewer :list="list" ref="previewerb" :options="options"></previewer>
  </div>
  </div>
  </div> 
</template>

<script>
import { Previewer } from 'vux'
export default {
  components: {
    Previewer
  },
  methods: {
    show (index) {
      this.$refs.previewera.show(index)
      this.$refs.previewerb.show(index)
    }
  },
  data () {
    return {
      list: [{
        src: 'http://pic.xiami.net/images/album/img10/3110/21003372621469680510.jpg?x-oss-process=image/resize,limit_0,m_pad,w_185,h_185',
        w: 600,
        h: 400
      },
      {
        src: 'https://img.alicdn.com/tps/TB1Q5DVNpXXXXbjXVXXXXXXXXXX-185-100.png',
        w: 1200,
        h: 900
      }],
      bbb:[
        {name:111},
        {age:23}
      ],
      options: {
        getThumbBoundsFn (index) {
          // find thumbnail element
          let thumbnail = document.querySelectorAll('.previewer-demo-img')[index]
          // get window scroll Y
          let pageYScroll = window.pageYOffset || document.documentElement.scrollTop
          // optionally get horizontal scroll
          // get position of element relative to viewport
          let rect = thumbnail.getBoundingClientRect()
          // w = width
          return {x: rect.left, y: rect.top + pageYScroll, w: rect.width}
          // Good guide on how to get element coordinates:
          // http://javascript.info/tutorial/coordinates
        }
      }
    }
  }
}
</script>
wangchaolonglls commented 7 years ago

好像还是不可以用吧?

wangchaolonglls commented 7 years ago

好像还是没解决吧`

`

ghost commented 7 years ago

因为并不好用,总是找不到正确的图片,所以我自己写了一个了。。。因此不知道这里要如何解决 @wangchaolonglls

pithyone commented 7 years ago

this.$refs 打印出来就知道怎么用啦,针对上面的代码

this.$refs.previewera.show(index);

修改为如下代码就好啦

this.$refs.previewera[0].show(index);