Vue emmitting组件属性似乎跳过父

时间:2018-05-28 22:47:35

标签: vue.js vuejs2

我已经被困在这一段很长一段时间了,我在网上找不到与此问题类似的任何东西。

背景:简单的餐厅评论网站。

我的应用程序需要能够使用WebRTC拍摄网络摄像头照片或从存储中上传照片。我构建了一个名为AddImageDialog的组件,允许用户通过将图像URL存储在此组件的prop中然后发出它来选择网络摄像头或上传存储的图像。然后父母处理图像的放置位置。

我的程序的一部分需要这个是NewReview组件,它允许上传5张照片,所有这些都使用相同的AddImageComponent。

有一个页面供用户上传新餐馆他们也可能会在此页面上留下评论,因此带有Review的{​​{1}}组件会导入此页面。此页面还必须允许用户上传场地的官方照片,因此我在此页面上重复使用了我的AddImagedDialog。

问题...每当通过网络摄像头上传时,在上传评论照片(在新餐厅页面上)时,一切正常,但在上传存储的图像时,图像似乎被淡化,但跳过AddImageDialog父组件然后跳回祖父母 - NewReview

AddImageDialog.vue

NewRestaurant

很抱歉发布了这么多代码,但我完全不知道是什么导致了这个问题。

你会注意到我试图通过分配一个`photoData'变量并在它被改变时发出它来以同样的方式使网络摄像头和图像上传工作。我很困惑他们为什么表现不同。

NewReview.vue

(这是存储的图像上传被跳过的组件)

    <template>
  <div>
    <v-layout row justify-center>
      <v-dialog v-model="thisShowDialog" max-width="550px">
        <v-card height="350px">
          <v-card-title>
            Take a new photo or choose an existing one...
          </v-card-title>
          <v-card-text>
            <div>
              <!-- Add a new photo option -->
              <div class="clickBox left" @click="showCamera = true">
                <v-container fill-height>
                  <v-layout align-center>
                    <v-flex>
                      <v-icon size="40pt" class="enlarge">add_a_photo</v-icon>
                    </v-flex>
                  </v-layout>
                </v-container>
              </div>



              <!-- Add photo from library -->
              <div class="clickBox right" @click="uploadImage">
                <v-container fill-height>
                  <v-flex>
                    <input type="file" class="form-control" id="file-input" v-on:change="onFileChange"> 
                    <v-icon size="40pt" class="enlarge">photo_library</v-icon>
                  </v-flex>
                </v-container>
              </div>
            </div>
          </v-card-text>
        </v-card>
      </v-dialog>
    </v-layout>

    <Camera 
      :showCamera.sync="showCamera"
      :photoData.sync="thisPhotoData">
    </Camera>
  </div>
</template>


<script>
import Camera from '@/components/Camera'

export default {
  props: ['showDialog', 'photoData'],
  data () {
    return {
      thisShowDialog: false,
      showCamera: false,
      thisPhotoData: null
    }
  },
  methods: {
    uploadImage () {
      var fileUpload = document.getElementById('file-input') // createElement('input', {type: 'file'})
      fileUpload.click()
    },
    onFileChange (event) {
      let files = event.target.files || event.dataTransfer.files
      if (!files.length) {
        return
      }

      this.createImage(files[0])
      this.thisShowDialog = false

      this.thisShowDialog = false
    },
    createImage (file) {
      let reader = new FileReader()
      reader.onload = e => {
        alert('reader loaded')
        this.thisPhotoData = e.target.result
      }

      reader.readAsDataURL(file)
    }
  },
  watch: {
    showDialog () {
      this.thisShowDialog = this.showDialog
    },
    thisShowDialog () {
      this.$emit('update:showDialog', this.thisShowDialog)
    },

    showCamera () {
      // when hiding the camera, leave this component too.
      if (!this.showCamera) {
        this.thisShowDialog = false
      }
    },

    thisPhotoData () {
      alert('emmiting from add image comp')
      this.$emit('update:photoData', this.thisPhotoData)
    }
  },
  components: {
    Camera
  }
}
</script>

这可以通过为评论定义5个图像和5个字符串的数组来实现,然后根据选择的图像,通过观察照片数据将发送的图像从<template> <!-- LEAVE A REVIEW --> <v-expansion-panel class="my-4" popout> <v-expansion-panel-content expand-icon="mode_edit"> <div slot="header">Been here before? Leave a review...</div> <v-card class="px-3"> <v-alert :value="isLoggedIn" type="warning"> You are not logged in. <a href="/login">Log in.</a> </v-alert> <v-form v-model="validReview"> <!-- Title --> <v-text-field name="title" label="Review Title" v-model="thisReview.title" :rules="reviewTitleRules"> </v-text-field> <!-- Body --> <v-text-field name="body" label="Review Body" multi-line v-model="thisReview.reviewBody" :rules="reviewBodyRules"> </v-text-field> <v-card-actions> <!-- Submit --> <v-btn v-if="canSubmit" :disabled="!validReview" class="primary" @click="submitReview">Submit</v-btn> <!-- Select Rating --> <star-rating-input class="ratingSelectStyle" :star-size="25" active-color="#E53935" v-model="thisReview.reviewRating" :show-rating="false"> </star-rating-input> <v-spacer /> <!-- Add and View 5 review images --> <div v-for="i in 5" :key="i" @click="addImage(i-1)"> <review-image :photoData="reviewPhotos[i-1]" :id="i" ></review-image> </div> <!-- Add Images Component --> <AddImageDialog :showDialog.sync="showCamera" :photoData.sync="photoData" ></AddImageDialog> </v-card-actions> </v-form> </v-card> </v-expansion-panel-content> </v-expansion-panel> </template> <script> import RestaurantService from '../services/RestaurantService' import ReviewImage from '@/components/ReviewImage' import StarRatingInput from 'vue-star-rating' import {mapGetters} from 'vuex' import AddImageDialog from '@/components/AddImageDialog' export default { props: ['review', 'restaurantID'], data () { return { showCamera: false, photoData: '', reviewPhotos: ['', '', '', '', ''], currentReviewPhoto: 0, thisReview: this.review || { title: '', reviewBody: '', reviewRating: 5, user: 'Anon' }, validReview: true, reviewTitleRules: [ s => !!s || 'Title is required', s => s.length >= 5 || 'Title must be at least 5 characters' ], reviewBodyRules: [ s => !!s || 'Body is required', s => s.length >= 10 || 'Body must be at least 10 characters' ] } }, methods: { addImage (i) { this.currentReviewPhoto = i this.showCamera = true // the rest of this is handled by watching for photodata to be changed by the camera component. }, setName () { this.thisReview.user = this.$store.state.isLoggedIn ? this.$store.state.user.name : 'Anon' }, submitReview: async function () { try { await RestaurantService.submitReview(this.restaurantID, this.thisReview).then(res => { if (res.status === 200) { this.$store.dispatch('setNoticeText', 'Review Submitted') } }) } catch (err) { if (err.response.status === 404) { // console.log('404 - Failed to submit') this.$store.dispatch('setNoticeText', '404 - Failed to submit review') } else { this.$store.dispatch('setNoticeText', 'An unexpected problem has occured. [' + err.response.status + ']') } } } }, computed: { ...mapGetters({isLoaded: 'isLoaded'}), canSubmit () { if (this.restaurantID) { return true } else { return false } }, isLoggedIn () { if (this.isLoaded && !this.$store.state.isLoggedIn) { return true } else { return false } } }, watch: { thisReview: { handler () { this.$emit('update:review', this.thisReview) }, deep: true }, isLoaded () { if (this.isLoaded) { this.setName() } }, photoData () { if (this.photoData !== '') { this.reviewPhotos[this.currentReviewPhoto] = this.photoData this.photoData = '' } } }, components: { StarRatingInput, ReviewImage, AddImageDialog }, mounted () { this.setName() } } </script> 分配到适当的数组。如上所述,此观察器功能将与网络摄像头一起使用,但在上传图像时会被跳过。

我甚至不确定导致此问题的是否在此代码中,但任何建议都将非常感激:)

0 个答案:

没有答案