如何从嵌套组件发出,同时保持引用函数外部变量的能力
Posted
技术标签:
【中文标题】如何从嵌套组件发出,同时保持引用函数外部变量的能力【英文标题】:How to emit from a nested component while maintaining ability to reference variables outside of function 【发布时间】:2020-01-07 08:59:44 【问题描述】:我正在尝试构建一个图像上传应用程序,该应用程序将图像上传到 Firebase 存储,一路跟踪上传百分比,并在上传时更新图库以显示所有图像,包括新上传的图像。
我开始构建用于上传和跟踪上传进度的组件。但是,它不起作用,因为 onUpload() 方法无法更改 this.uploadPercentage 的值。
<template>
<v-container style="height: 100%;">
<v-row
align-content="center"
justify="center"
>
<h1>Image Uploader</h1>
</v-row>
<v-row
align-content="center"
justify="center"
>
<v-col cols="6">
<v-progress-linear
color="deep-purple accent-4"
rounded
:value="uploadPercentage"
id="uploader"
></v-progress-linear>
</v-col>
</v-row>
<v-row
align-content="center"
justify="center"
>
<v-col
class="align-content-center"
cols="4"
>
<v-file-input
v-model="file"
accept="image/*"
label="choose an image"
outlined
@change="onFileChange"
></v-file-input>
</v-col>
<v-col
class="align-content-center mt-2"
cols="2"
>
<v-btn
@click="onUpload"
>
Upload
<v-icon right dark>mdi-cloud-upload</v-icon>
</v-btn>
</v-col>
</v-row>
</v-container>
</template>
<script>
import firebase from '@/firebase/init'
export default
data: () => (
file: null,
imageURL: null,
uploadPercentage: 0
),
methods:
onFileChange ()
let reader = new FileReader()
reader.onload = () =>
reader.imagUrl = reader.result
reader.readAsDataURL(this.file)
,
onUpload ()
// create a firebase storage ref
var storageRef = firebase.storage().ref('public_wall/' + this.file.name)
// upload file
var task = storageRef.put(this.file)
// update progress bar
task.on('state_changed',
function (snapshot)
console.log('uploading')
var percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
this.uploadPercentage = percentage
,
function error (err)
console.log(err)
,
function completed ()
console.log('upload complete')
)
</script>
我发现这是因为函数的范围,将 task.on() 中的快照函数更改为箭头函数我能够解决这个问题。
task.on('state_changed',
snapshot =>
console.log('uploading')
var percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
this.uploadPercentage = percentage
,
但是,我希望这个组件是一个嵌套组件,并在上传完成时发出一个信号。为此,我尝试将 task.on() 中的已完成函数更改为以下内容:
function completed ()
console.log('upload complete function')
this.$emit('upload-complete', 'hello')
这会引发错误:TypeError: this.$emit is not a function。
通过一些研究,我发现您不能在箭头函数中引用 this.$emit,但是,完成的函数不是箭头函数,将快照函数改回非箭头函数并不能解决问题,只会停止上传百分比跟踪器的工作。
我做错了什么,我该如何解决这个问题?
【问题讨论】:
【参考方案1】:它是因为 This 指的是已完成函数中的其他内容。你可以这样做
onUpload ()
let _self = this // saving reference to this
// create a firebase storage ref
var storageRef = firebase.storage().ref('public_wall/' + this.file.name)
// upload file
var task = storageRef.put(this.file)
// update progress bar
task.on('state_changed',
function (snapshot)
console.log('uploading')
var percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
this.uploadPercentage = percentage
,
function error (err)
console.log(err)
,
function completed ()
_self.$emit('upload-complete', 'hello')
// accessing that reference using closure
)
【讨论】:
以上是关于如何从嵌套组件发出,同时保持引用函数外部变量的能力的主要内容,如果未能解决你的问题,请参考以下文章
如何从另一个组件调用一个函数,同时保持另一个组件在 Angular 中的通用性?