N
N
nastya_zholudeva2018-05-11 12:28:17
Vue.js
nastya_zholudeva, 2018-05-11 12:28:17

How to make it so that the modal is called from the desired component, and not from App.vue?

There is a modal component Modal.vue

// Modal.vue
<template>
  <b-modal :class="className" v-model="modal" @ok="okModal" @cancel="okModal" :ok-variant="okButton">
    {{modalContent}}
  </b-modal>
</template>

<script>
  import { bus } from '../../bus'
  export default {
    name: 'Modal',
    props: {
      className: {
        type: String,
        default: 'modal-primary'
      },
      modalContent: {
        type: String,
        default: ''
      },
      okButton: {
        type: String,
        default: 'primary'
      }
    },
    data () {
      return {
        modal: false
      }
    },
    methods: {
      okModal () {
        this.modal = false
        this.$emit('click')
      }
    },
    mounted () {
      bus.$on('modalWindow', (val) => {
        console.log('123val', val)
        this.modal = val
      })
    },
    beforeDestroy () {
      bus.$off('modalWindow')
    }
  }
</script>

I connect it as in some components
//Component.vue
</template>
//code
<Modal :modalContent="'Блок успешно сохранен'" @click="ok"/>
  </b-form>
</template>

<script>
import Modal from './Modal'
import { bus } from '../../bus'

export default {
  name: 'TextBlockForm',
  components: {
    Modal
  },
  props: {
    success: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    success (oldValue, newValue) {
      if (oldValue) {
        bus.$emit('modalWindow', true)
      }
    }
  },
  methods: {
    sendData () {
      ///////code
      if (this.success) {
        bus.$emit('modalWindow', true)
      }
    },
    ok () {
      bus.$emit('modalWindow', false)
      this.$emit('clickOnOk')
    }
  }
  }
}
</script>

success = true - passed from the parent component when the request was successful
Same with App.vue as I need to track down the 403 error that can pop up on any request.
//api конфиг файл 

axios.interceptors.response.use((response) => {
    return response
  }, (error) => {
    if (error.response.status == 403) {
      bus.$emit('modalWindow', true)
    }
    return Promise.reject(error)
  })

//App.vue
<template>
  <div>
    <router-view></router-view>
    <Modal :className="'modal-danger'" :modalContent="'Доступ запрещен'" :okButton="'danger'" @click="okModal"/>
  </div>
</template>



<script>
  import { bus } from '../bus'

  import Modal from '../src/components/Modal'
  export default {
    name: 'app',
    components: {Modal},
    methods: {
      okModal () {
        bus.$emit('modalWindow', false)
        this.$router.go(-1)
      }
    }
  }
</script>

The problem arises in the fact that for any outcome (there is a 403 error or not), the modal from app.vue is called and overrides the desired modal from the component. In fact, if you are on a page where component.vue is connected, a successful request passes and success = true for some reason, the modal from app.vue is called first.
How can I defeat this?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey Sergeev, 2018-05-11
@nastya_zholudeva

Xs, how to do local events using the global bus. It seems to me that the approach is wrong.
Alternatively, you can add a name to the modal via ref
add open method

// Modal.vue

...
    methods: {
      okModal () {
        this.modal = false
        this.$emit('click')
      },
      open (val) {
        this.modal = val        
      },
    },
...

and instead of calling
this.$refs.yourModalNameRef.open();

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question