[Vuejs]-Dynamically changing props

1👍

Fixed event name and prop name then it should work.

  1. As Vue Guide: Custom EventName says, Vue recommend always use kebab-case for event names.
    so you should use this.$emit('start-upload'), then in the template, uses <upload-button @start-upload="upload"> </upload-button>

  2. As Vue Guide: Props says,

HTML attribute names are case-insensitive, so browsers will interpret
any uppercase characters as lowercase. That means when you’re using
in-DOM templates, camelCased prop names need to use their kebab-cased
(hyphen-delimited) equivalents

so change :uploadComplete="uploadCompleteBoolean" to :upload-complete="uploadCompleteBoolean"

Edit: Just noticed you mentioned data property=uploadingComplete.

It is easy fix, add one watch for props=uploadComplete.

Below is one simple demo:

Vue.config.productionTip = false
Vue.component('upload-button', {
  template: `<div>  <button @click="onClick">Upload for Data: {{uploadingComplete}} Props: {{uploadComplete}}</button>
         </div>`,
  props: {
    uploadComplete: {
      type: Boolean
    }
  },
  data() {
    return {
      uploadingComplete: this.uploadComplete
    }
  },
  watch: { // watch prop=uploadComplete, if change, sync to data property=uploadingComplete
    uploadComplete: function (newVal) {
      this.uploadingComplete = newVal
    }
  },
  methods: {
    onClick() {
      this.uploadingComplete = false
      this.$emit('start-upload')
    }
  }
})

new Vue({
  el: '#app',
  data() {
    return {
      uploadCompleteBoolean: true
    }
  },

  methods: {
    upload() {
      this.uploadCompleteBoolean = false
      // do stuff to upload, then when finished,
      this.uploadCompleteBoolean = true
    },
    changeStatus() {
      this.uploadCompleteBoolean = !this.uploadCompleteBoolean
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <button @click="changeStatus()">Toggle Status {{uploadCompleteBoolean}}</button>
  <p>Status: {{uploadCompleteBoolean}}</p>
  <upload-button :upload-complete="uploadCompleteBoolean" @start-upload="upload">
  </upload-button>
</div>
👤Sphinx

1👍

The UploadButton component shouldn’t have uploadingComplete as local state (data); this just complicates the component since you’re trying to mix the uploadComplete prop and uploadingComplete data.

The visibility of the spinner should be driven by the parent component through the prop, the button itself should not be responsible for controlling the visibility of the spinner through local state in response to clicks of the button.

Just do something like this:

Vue.component('upload-button', {
  template: '#upload-button',
  props: ['uploading'],
});

new Vue({
  el: '#app',
  data: {
    uploading1: false,
    uploading2: false,
  },
  methods: {
    upload1() {
      this.uploading1 = true;
      setTimeout(() => this.uploading1 = false, Math.random() * 1000);
    },
    upload2() {
      this.uploading2 = true;
      setTimeout(() => this.uploading2 = false, Math.random() * 1000);
    },
  },
});
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>

<div id="app">
  <upload-button :uploading="uploading1" @click="upload1">Upload 1</upload-button>
  <upload-button :uploading="uploading2" @click="upload2">Upload 2</upload-button>
</div>

<template id="upload-button">
  <button @click="$emit('click')">
    <template v-if="uploading">Uploading...</template>
    <slot v-else></slot>
  </button>
</template>

1👍

Your question seems little bit ambiguë, You can use watch in that props object inside the child component like this:

watch:{
    uploadComplete:{
        handler(val){
            //val gives you the updated value 
        }, deep:true
     },
}

by adding deep to true it will watch for nested properties in that object, if one of properties changed you ll receive the new prop from val variable
for more information : https://v2.vuejs.org/v2/api/#vm-watch

if not what you wanted, i made a real quick example,
check it out hope this helps : https://jsfiddle.net/K_Younes/64d8mbs1/

Leave a comment