如何在Vue中传递和更改数组的索引?

时间:2018-11-17 07:03:25

标签: vue.js vue-component

我有执行此操作的要旨,但是我是一名初学者,并且正在努力将其组合在一起。我需要Control.vue更新Exhibitor.vue中的索引。我知道我将在Control上发生一个$ emit事件,当我单击该按钮将索引数据传递给父级时,我将不得不使用props将数据从Exhibitor传递给其子级,但是如何?我不明白如何通过我的代码传递数组的索引。

Exhibitor.vue

<template>
  <div id="exhibitor">
  <section class="exhibitor_info">
    <h1 class="exhibitor_name">{{ exhibitors[index].firstName }} {{ exhibitors[index].lastName }}</h1>
    <h2>Tag Number: {{ exhibitors[index].tagNum }} <em>{{ exhibitors[index].species }}</em></h2>
  </section>
  <div class="frame"><img :src="getImgUrl(exhibitors[index].picture)" alt="Exhibitor-Picture" class="image"></div>
  </div>
</template>

<script>
export default {
  name: 'Exhibitor',
  data() {
    return {
    exhibitors: [],
    index: 0
    }
  },
  created: function() {
    this.fetchExhibitors();
  },
  methods: {
    fetchExhibitors() {
      let uri = 'http://localhost:8081/exhibitor'
      this.axios.get(uri).then(response => {
        this.exhibitors = response.data
      })
    },
    getImgUrl: function(pic) {
      return require('../assets/' + pic)
    }
  }
}
</script>

Display.vue

<template>
  <div id="display">
    <exhibitor></exhibitor>
    <buyer></buyer>
  </div>
</template>

<script>
import Exhibitor from './Exhibitor.vue';
import Buyer from './Buyer.vue';

export default {
  components: {
    'exhibitor': Exhibitor,
    'buyer': Buyer
  }
}
</script>

Control.vue

<template>
  <div id="control">
    <display></display>
      <button v-on:click="incrementLeft">Left</button>
      <button v-on:click="incrementRight">Right</button>
  </div>
</template>

<script>
import Exhibitor from './Exhibitor.vue';
import Display from './Display.vue';
export default{
  props: ['exhibitors', 'buyers', 'index'],
  data() {
    return {
      index: 0
    }
  },
  methods: {
    incrementRight: function() {
      // Note that '%' operator in JS is remainder and NOT modulo
      this.index = ++this.index % this.exhibitors.length
    },
    incrementLeft: function() {
      // Note that '%' operator in JS is remainder and NOT modulo
      if (this.index === 0) {
        this.index = this.exhibitors.length - 1
      } else {
        this.index = --this.index % this.exhibitors.length
      }
    }
  },
  components: {
    'display': Display
  }
}
</script>

1 个答案:

答案 0 :(得分:0)

所以您可以获得想要发生的事情,而我可以想到两种实现它的方法。首先,我将澄清与此相关的术语,因为您似乎错误地使用了它们。让我们来看一下这样的层结构:

Control.vue
  contains: Display.vue
    contains: Exhibitors.vue & Buyers.vue.

因此,Control.vue是Display.vue的父级,而Display.vue是Buyers.vue和Exhibitors.vue的父级。

无论如何,我们需要做的是控制参展商的阵列(我想是买家,但是您没有在代码中包括它们,所以我也照做),这是Control.Vue的Exhibitors.vue中的,即使他们没有直接的亲子关系。我所做的是设置一个传递到Display.vue的道具,该道具使用作用域范围的插槽从Exhibitors.Vue渲染参展商。因为左右按钮需要知道何时停止运行,所以我将数组长度从Exhibitors.vue发出到Display.vue,然后又发出到Control.vue。一切正常,所以这里有一些代码。

//Control.vue
<template>
    <div class="content">
        <display v-on:finalLength="setIndexLimit" :i="index"></display>
        <button @click="changeDown">Down</button>
        <button @click="changeUp">Up</button>
        <p>{{indLimit}}</p>
    </div>
</template>

<script>
import Display from '@/components/Display'
export default {
    components: {
        Display
    },
    data: () => ({
        index: 0,
        indLimit: 0
    }),
    methods: {
        changeUp() {
            if (this.indLimit === this.index+1) {
                this.index=0
            }
            else {
                this.index ++
            }
        },
        changeDown() {
            if (this.index === 0) {
                this.index = this.indLimit - 1
            }
            else {
                this.index --
            }
        },
        setIndexLimit(e) {
            this.indLimit = e
        }
    }
}
</script>

//Display.vue
<template>
  <div id="display">
      <p>From Display</p>
    <exhibitors v-on:ExLength="setLength">
        <p>{{i}}</p>
    </exhibitors>
    <exhibitors>
        <p slot-scope="{ exhibitors }">{{exhibitors[i].firstName}}</p>
    </exhibitors>
    <exhibitors>    
        <p slot-scope="{ exhibitors }">{{exhibitors[i].lastName}}</p>
    </exhibitors>
    <exhibitors> 
        <p slot-scope="{ exhibitors }">{{exhibitors[i].tagNum}}</p>
    </exhibitors>
    <exhibitors>     
        <p slot-scope="{ exhibitors }">{{exhibitors[i].species}}</p>
    </exhibitors>
  </div>
</template>

<script>
import Child from '@/components/admin/Exhibitors'

export default {
  components: {
    Exhibitors
  }, 
  props: [
      'i'
  ],
  data: () => ({
      exhibitLength: null
  }),
  methods: {
      setLength(e) {
          this.exhibitLength = e
          this.$emit('finalLength',e)
      }
  }

}
</script>

最后:

//Exhibitors.vue
<template>
  <div>
    <slot :exhibitors="exhibitors"><p>I'm the child component!</p></slot>
  </div>
</template>

<script>
export default {
  data: () => ({
    exhibitors: [
            {
                firstName: 'Joe',
                lastName: 'Burns',
                tagNum: 1,
                species: 'ant'
            },
            {
                firstName: 'Tom',
                lastName: 'Yorke',
                tagNum: 2,
                species: 'bee'
            },
            {
                firstName: 'Flit',
                lastName: 'Argmeno',
                tagNum: 3,
                species: 'giraffe'
            }
        ],
  }),
  mounted: function () {
    this.$nextTick(function () {
        let length = this.exhibitors.length
        this.$emit('ExLength', length)
    })
  }
}
</script>

因此,正如我所说的所有可行的那样,您可以单击按钮,它将遍历数组内容。您可以根据自己的喜好随意设置样式。但是,道具和槽位,发射物以及仅用于中继单个索引号的操作都有些混乱,在我看来,将 vuex存储存储为“ index”会更容易状态项,可以在任何地方使用和更改,而无需进行上述所有操作。