Javascript Vue2:将函数作为道具传递会触发道具已设置的警告

Javascript Vue2:将函数作为道具传递会触发道具已设置的警告,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,我是Vue的新手,到目前为止,我很喜欢单文件组件 在做我真正想做的东西之前,我想我会尝试一些小东西,看看我是否掌握了这个概念 因此,我开始制作一个组件,用于打开一个XMLHttpRequest,并带有一个进度条 这很有效 然而,在我的一生中,有几个小错误我无法理解: 我想定义一个传递给propsuccess的函数onSuccess,但这会从Vue抛出一个错误 statusTooltip的计算属性未得到更新 无论我如何尝试绑定,尝试设置automaticCloseQ都会导致默认值 e、 g

我是Vue的新手,到目前为止,我很喜欢单文件组件

在做我真正想做的东西之前,我想我会尝试一些小东西,看看我是否掌握了这个概念

因此,我开始制作一个组件,用于打开一个XMLHttpRequest,并带有一个进度条

这很有效

然而,在我的一生中,有几个小错误我无法理解:

  • 我想定义一个传递给prop
    success
    的函数
    onSuccess
    ,但这会从Vue抛出一个错误
  • statusTooltip
    的计算属性未得到更新
  • 无论我如何尝试绑定,尝试设置
    automaticCloseQ
    都会导致默认值
e、 g

var onSuccess=function(){console.log('here')}
我错过了什么?

希望这能有所帮助

我想在success上定义一个传递给prop success的函数,但这会从Vue抛出一个错误

您正在Vue之外定义
onSuccess
。它应该在Vue的
方法中定义


未更新statusTooltip的计算属性

在Javascript中,对象通过引用传递<代码>xhr
始终引用同一对象。这就是计算值不会更新的原因。看见解决此问题的一种方法是使用另一个名为
xhrStatus
的反应式数据,并在xhr的事件侦听器中手动更新此状态


无论我如何尝试绑定,尝试设置automaticCloseQ都会导致默认值


(我不知道这意味着什么…

因此,除非在Vue内部有相同的任意名称,否则无法将Vue外部定义的任意命名函数作为道具传递给Vue?那看起来很傻。。。如果我想要3个实例,其中包含函数
onSuccessCallback1
onSuccessCallback2
onSuccessCallback3
?那么我就不能概括我的组件了?我想为组件的行为添加一个切换开关
automaticCloseQ
,该开关可以在成功传输后自动删除元素(而不是vue实例),或者用关闭按钮显示vue实例。我用默认值false定义了一个布尔属性(这对于布尔值来说是正确的),然后尝试了
:automaticCloseQ=“true”
,无论发生什么情况(例如v-bind、no
:automaticCloseQ
等),我都无法将
设置为true
<template >
  <div  v-if="showQ">
    <div class="text-muted">
      <span>{{humanReadableLead}}</span>
      <span :class="'text-'+color">{{humanReadableMessage}}</span>
      <span>{{humanReadableEnd}}</span>
    </div>
    <div class="progress">
      <div
        class="progress-bar progress-bar-striped progress-bar-animated"
        :class="'bg-'+color"
        role="progressbar"
        :style="{width: String(percent)+'%'}"
        :aria-valuenow="percent"
        aria-valuemin="0"
        aria-valuemax="100"
      ></div>
    </div>

    <div class="text-right text-muted form-text text-small">
      <span class="float-left">{{xhrMessage}}</span>
      <span
        class="badge"
        :class="'badge-'+color"
        data-toggle="tooltip"
        data-placement="right"
        :title="readyStateTooltip"
        >
          {{xhr.readyState}}
        </span>
      <span
        class="badge"
        :class="'badge-'+color"
        data-toggle="tooltip"
        data-placement="right"
        :title="statusTooltip"
      >
        {{xhr.status}}
      </span>
      <span
        v-if="transferComplete"
        @click="goodbye"
        class="badge badge-secondary"
        data-toggle="tooltip"
        data-placement="right"
        title="Dismiss progress bar"
      >
        &times;
      </span>
    </div>
  </div>

</template>

<script>

import {httpStatusCodes, httpReadyStateCodes} from './http-responses';

export default {
  props: {
    method: {
      type: String,
      default: "GET",
      validator: function(value) {
        return ["GET", "POST", "PUT", "DELETE"].includes(value)
      }
    },
    url: {
      type: String,
      required: true
    },
    async: {
      type: Boolean,
      default: true
    },
    success: {
      type: Function,
      default: function() {
        console.log(this.xhr.response)
      }
    },
    readystatechange: {
      type: Function,
      default: function(event) {
      }
    },
    automaticCloseQ: {
      type: Boolean,
      default: false
    }
  },
  data: function() {
    return {
      xhr: new XMLHttpRequest(),
      httpStatusCodes:httpStatusCodes,
      httpReadyStateCodes:httpReadyStateCodes,
      color: "primary",
      percent: 0,
      humanReadableLead: "",
      humanReadableMessage: "",
      humanReadableEnd: "",
      xhrMessage: "",
      showQ: true,
      completeQ: false
    }
  },
  computed: {
    readyStateTooltip: function() {
      var rs = this.xhr.readyState,
      rsc = httpReadyStateCodes[rs]
      return `Ready state ${rs}: ${rsc}`
    },
    statusTooltip: function() {
      var s = this.xhr.status
      // s = s == 0 ? 218 : s
      var sc = httpStatusCodes[s]
      return `Status ${s}: ${sc}`
    },
    transferComplete: function() {
      return this.completeQ
    }
  },
  methods: {
    open: function() {
      this.xhr.open(this.method, this.url, this.async)
    },
    send: function() {
      this.xhr.send()
    },
    goodbye: function() {
      this.showQ = false
    }
  },

  created: function() {
    var that = this
    that.open()

    that.xhr.addEventListener("error", function(event) {
      that.color = "danger"
      that.xhrMessage = "An error has occured."
    })

    this.xhr.addEventListener("progress", function(event) {
      if (event.lengthComputable) {
        var percentComplete = event.loaded / event.total * 100;
        that.percent = percentComplete
      } else {
        that.percent = 100
        that.xhrMessage = "Unable to compute progress information since the total size is unknown."
      }
    })

    that.xhr.addEventListener("abort", function(event) {
      that.color = "danger"
      that.xhrMessage = "The transfer has been canceled by the user."
    });

    that.xhr.addEventListener("load", function(event) {
      that.color = "success"
      that.xhrMessage = "Transfer complete."
      that.completeQ = true
      if (that.automaticCloseQ) { that.showQ = false }
      that.success()
    })

    that.xhr.addEventListener("readystatechange", function(event) {
      that.readystatechange(event)
    })

    that.send()
  }
}
</script>

<style scoped>
</style>
<div id="request" style="width:50%;" >
  <http-request :url="'./<some-file>'"/>
</div>
var progress = new Vue({
  el: '#request',
  components: { httpRequest }
})
var onSuccess = function() {console.log('here')}

<http-request :url="'./<some-file>'" :success="onSuccess" :automaticCloseQ="true"/>