Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vue.js - change text within a button after an event

I'm playing with vue.js for learning purposes consisting of different components, one of them being a classic to do list. For now, everything is within one component.

I want to change the text of a button after it is clicked to hide an element from "hide" to "show" - I'm going about this by setting a text data object and then changing it in a function.

See below:

<div id="app">
  <ul>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ul>

  <input type="text" id="list-input">
  <input type="submit" id="list-submit" v-on:click="addItem">
  <span id="error" style="color: red; display: none;">Please Enter Text</span>

  <ul>
    <todoitem></todoitem>
    <todoitem></todoitem>
    <todoitem></todoitem>
  </ul>

  <h2 v-if="seen">SEEN</h2>
  <button id="hide-seen" v-on:click="toggleSeen">{{ button.text }}</button>
</div> 

<script type="text/javascript">
// components
Vue.component('todoitem', {
  template: "<li>Test Item</li>"
})

// app code
var app = new Vue({
  el: '#app',
  data: {
    todos: [
      { text: 'Sample Item 1' },
      { text: 'Sample Item 2' },
      { text: 'Sample Item 3' }
    ],
    button: [
      { text: 'Hide'}
    ],
    seen: true
  },
  methods: {
    addItem: function() {
      let item = document.getElementById("list-input").value;
      let error = document.getElementById("error");
      if (item == "") {
        error.style.display = "block";
      } else {
        app.todos.push({ text: item });
        error.style.display = "none";
      }
    },
    toggleSeen: function() {
      app.seen = false
      app.button.push({ text: 'Show' });
    }
  }
})


</script>

Unexpectedly, the button is blank on both hide and show states. Being new to vue, this seems like a strange way to go about doing it. Is changing data in this context bad practice? I don't understand how to fix this, as I have no errors in my console.

like image 866
kawnah Avatar asked Oct 04 '17 14:10

kawnah


People also ask

How do you call a component on button click Vue?

Simply use @click (v-on:click) to toggle Bool. The v-model simply means that it doesn't show if it's false and it does if it's true.

What does data () do in Vue?

data # A function that returns the initial reactive state for the component instance. The function is expected to return a plain JavaScript object, which will be made reactive by Vue. After the instance is created, the reactive data object can be accessed as this.

Does Vue have reusable components?

Create reusable components in VueWe will learn to build a reusable component in Vue, which will be used to reuse it in Create or Edit or anywhere that requires the same code and functionality. Reusing a component or code helps us avoid writing the same code and functionality multiple times.

Can we pass component as a prop in Vue?

Data in props can only flow one way – from the top, or parent component, to the bottom, or child components. This simply means you cannot pass data from a child to a parent.


2 Answers

Here you have your code in a snipplet.

I change your button by a plain object instead of an array and small adaptation in method toggleSeen.

// components
Vue.component('todoitem', {
  template: "<li>Test Item</li>"
})

// app code
var app = new Vue({
  el: '#app',
  data: {
    todos: [
      { text: 'Sample Item 1' },
      { text: 'Sample Item 2' },
      { text: 'Sample Item 3' }
    ],
    button: {
      text: 'Hide'
    },
    seen: true
  },
  methods: {
    addItem: function() {
      let item = document.getElementById("list-input").value;
      let error = document.getElementById("error");
      if (item == "") {
        error.style.display = "block";
      } else {
        app.todos.push({ text: item });
        error.style.display = "none";
      }
    },
    toggleSeen: function() {
      app.seen = !app.seen;
      app.button.text = app.seen ? 'Hide' : 'Show';
    }
  }
});
<script src="https://vuejs.org/js/vue.min.js"></script>

<div id="app">
  <ul>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ul>

  <input type="text" id="list-input">
  <input type="submit" id="list-submit" v-on:click="addItem">
  <span id="error" style="color: red; display: none;">Please Enter Text</span>

  <ul>
    <todoitem></todoitem>
    <todoitem></todoitem>
    <todoitem></todoitem>
  </ul>

  <h2 v-if="seen">SEEN</h2>
  <button id="hide-seen" v-on:click="toggleSeen">{{ button.text }}</button>
</div>
like image 70
Camille Avatar answered Sep 18 '22 18:09

Camille


You can achieve this by using refs in vuejs:

<body>
    <div id = 'app'>
        <button @click="changeState" ref="btnToggle">Hide</button>
        <div v-show="show">
            <h1>1 to 100</h1>
            <p v-for="i in 100">{{i}}</p>
        </div>
    </div>
    <script>
        const app = new Vue({
            el:'#app',
            data: function(){
                return{
                    show: true
                }
            },
            methods: {
                changeState: function(){
                    this.show = !this.show;
                    this.$refs.btnToggle.innerText = this.show?'Hide':'Show';

                }
            },
        });
    </script>
</body>
like image 36
Lord Avatar answered Sep 16 '22 18:09

Lord