如何在保持引用函数外部变量的能力的同时从嵌套组件发出
How to emit from a nested component while maintaining ability to reference variables outside of function
我正在尝试构建一个图像上传应用程序,它将图像上传到 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
height="6"
: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,但是,完成的函数不是箭头函数,将快照函数改回非箭头并不能解决问题,只是停止了上传百分比跟踪器的工作。
我哪里做错了,我该如何解决这个问题?
是因为 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
}
)
}
我正在尝试构建一个图像上传应用程序,它将图像上传到 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
height="6"
: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,但是,完成的函数不是箭头函数,将快照函数改回非箭头并不能解决问题,只是停止了上传百分比跟踪器的工作。
我哪里做错了,我该如何解决这个问题?
是因为 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
}
)
}