Vue-native: Dynamically created touchable-opacity are all pressed at the beginning

244 views Asked by At

When i create touchable-opacity or buttons using v-for loop, the on-press functions of all buttons are called even though i haven't touch any of them. But there isn't any problem with normal button using the same function as handler.

<view v-for="taskDay in buttons" :key="taskDay.id" class="task-day">
  <touchable-opacity  
    v-for="task in taskDay.next" 
    :key="task.id" 
    :on-press="handleTouch(task.id)" 
    class="task">
  </touchable-opacity>
</view>
methods: {
  handleTouch: function(id) {
    console.log(id);
  }
},

There isn't much on the internet about vue native. Can anyone help?

1

There are 1 answers

1
onestepp On BEST ANSWER

I am facing exactly the same issue....

UPDATE: I dived more deep in the topic, and it turned out is a known issue in native base. Checkbox is touchable opacity in react native, and button as well with a composition of views in some order, thats why you have problems in both cases.

See the native base issue in github: https://github.com/GeekyAnts/NativeBase/issues/3038

However, I could find a workaround. This is not exactly a checkbox, I use tick icon to display that the item is checked, and I iterate through a touchable opacity from native base. But with some styling you can create a checkbox I am sure.

<scroll-view
  :content-container-style="{
    contentContainer: {
      paddingVertical: 20
    }
  }"
>
  <touchable-opacity
    v-for="(item, index) in dataArray"
    :key="index"
    :onPress="
      () => {
        checkItem(index)
      }
    "
  >
    <text>{{ item.time }} - {{ item.name }}</text>
    <image
      :style="{ height: 15, width: 15, marginLeft: 15 }"
      :source="require('../../../assets/icons/done.png')"
      v-if="item.checked"
    />
  </touchable-opacity>
</scroll-view>

In the checkItem method I use splice and replace the item to preserve reactivity:

methods: {
    checkItem(index) {
      this.dataArray[index].checked = true
      this.dataArray.splice(index, 1, this.dataArray[index])
    }
  },

My dataArray is an array like that:

[{id: 1, name: 'Name', checked: true}, {id: 2, name: 'Name', checked: false}]

I hope it will help to resolve your problem.