IT이야기

VueJ의 구성 요소 템플릿에서 Vuetify 대화 상자 열기s

cyworld 2022. 3. 28. 21:29
반응형

VueJ의 구성 요소 템플릿에서 Vuetify 대화 상자 열기s

VueJS Vuetify 프레임워크를 사용하고 있는데 다른 템플릿에서 구성 요소 템플릿으로 가져오는 대화 상자를 열어야 해.App.vueMenu 버튼을 클릭하면 Modal이 열려야 한다.다음은 내 설정이다.

  • App.vue = 메뉴 단추가 있는 탐색 템플릿
  • Modal.vue = modal 템플릿, main.js에서 전역으로 가져오기

main.js.

import Modal from './components/Modal.vue'
Vue.component('modal', Modal)

Modal.vue 템플릿:

<template>
  <v-layout row justify-center>
    <v-btn color="primary" dark @click.native.stop="dialog = true">Open Dialog</v-btn>
    <v-dialog v-model="dialog" max-width="290">
      <v-card>
        <v-card-title class="headline">Use Google's location service?</v-card-title>
        <v-card-text>Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.</v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="green darken-1" flat="flat" @click.native="dialog = false">Disagree</v-btn>
          <v-btn color="green darken-1" flat="flat" @click.native="dialog = false">Agree</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-layout>
</template>
<script>
  export default {
    data () {
      return {
        dialog: false
      }
    }
  }
</script>

대화 상자를 여는 방법?

이벤트 버스 필요 없음 및 v-model

업데이트:

처음 이 대답을 했을 때, 나는 "해결책"이라고 글을 올렸는데, 그 당시에는 그것이 완전히 "맞다"고 느껴지지 않았고, 나는 Vue.js가 처음이었기 때문이다.v-model 지시어를 사용해서 대화 상자를 열거나 닫고 싶었지만, 갈 수가 없었다.잠시 후 입력 이벤트와 가치 속성을 사용하여 문서에서 이 작업을 수행하는 방법을 찾았는데, 이벤트 버스 없이 수행되어야 한다고 생각하는 방법은 다음과 같다.

상위 구성 요소:

<template>
   <v-btn color="accent" large @click.stop="showScheduleForm=true">    
   <ScheduleForm v-model="showScheduleForm" />
</template>

<script>
import ScheduleForm from '~/components/ScheduleForm'

export default {
  data () {
    return {
      showScheduleForm: false
    }
  },
  components: {
    ScheduleForm
  }
}
</script>

하위 구성 요소(ScheduleForm):

<template>
<v-dialog v-model="show" max-width="500px">
  <v-card>
    <v-card-actions>
      <v-btn color="primary" flat @click.stop="show=false">Close</v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>
</template>

<script>
export default {
  props: {
     value: Boolean
  },
  computed: {
    show: {
      get () {
        return this.value
      },
      set (value) {
         this.$emit('input', value)
      }
    }
  }
}
</script>

원본 답변:

나는 글로벌 이벤트 버스 없이도 이 문제를 해결할 수 있었다.

나는 게터, 세터 등과 함께 계산된 속성을 사용했다.부에가 부모 속성을 직접 변이하는 것에 대해 경고하기 때문에, 나는 단지 부모에게 이벤트를 내보냈다.

암호는 다음과 같다.

상위 구성 요소:

<template>
   <v-btn color="accent" large @click.stop="showScheduleForm=true"></v-btn>   
   <ScheduleForm :visible="showScheduleForm" @close="showScheduleForm=false" />
</template>

<script>
import ScheduleForm from '~/components/ScheduleForm'

export default {
  data () {
    return {
      showScheduleForm: false
    }
  },
  components: {
    ScheduleForm
  }
}
</script>

하위 구성 요소(ScheduleForm):

<template>
<v-dialog v-model="show" max-width="500px">
  <v-card>
    <v-card-actions>
      <v-btn color="primary" flat @click.stop="show=false">Close</v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>
</template>

<script>
export default {
  props: ['visible'],
  computed: {
    show: {
      get () {
        return this.visible
      },
      set (value) {
        if (!value) {
          this.$emit('close')
        }
      }
    }
  }
}
</script>

Vuex, Event Bus, Propes 등 다양한 방법으로 모달의 개봉 여부를 관리할 수 있다.내가 가장 좋아하는 방법을 너에게 보여줄게..sync수식어:

먼저 너의 질문을 단순화하겠다(코드 파트)

상위 구성요소

<template>
   <div>
     <button @click="dialog=true">Open Dialog</button>
     <Child :dialog.sync="dialog" />
   </div>
</template>

<script>
import Child from './Child.vue'
export default {
    components: {
      Child
    },
    data: {
      return {
        dialog: false
      }
   }
}
</script>

자식(대화 상자) 성분

<template>
  <v-layout row justify-center>
    <v-dialog v-model="dialog" persistent max-width="290">
      <v-card>
        <v-card-title class="headline">Use Google's location service?</v-card-title>
        <v-card-text>Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.</v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="green darken-1" flat @click.native="close">Close</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-layout>
</template>

<script>

  export default {
    props: {
        dialog: {
        default: false
      }
    },
    methods: {
        close() {
        this.$emit('update:dialog', false)
      }
    }
  }

</script>

간단한 최소 작업 예제

코데펜

통과하다value로서 떠받치다.valuev-dialog구성 요소, 하위 대화 상자에서 방출input이벤트 닫기를 원할 때마다 이벤트:

//CustomDialog.vue
<v-dialog :value="value" @input="$emit('input', $event)">
  <v-btn color="red" @click.native="$emit('input', false)">Close</v-btn>
</v-dialog>
...
props:['value']

v-model을 부모에 추가하십시오.

//Parent.vue
<custom-dialog v-model="dialog">

그래서 맞춤형 이벤트 버스도 없고, 안 돼.data아니요.watch아니요.computed.

사용자 지정 이벤트와 비 부모-자녀 통신에 이벤트 버스를 사용하여 대화 상자를 열 수 있다.

애플리케이션이 좀 더 복잡해진다면 Vuex를 사용하여 상태를 관리하십시오.


이벤트 버스 솔루션:

main.js 또는 새 파일에서 새 Vue 인스턴스를 생성 및 내보내기:

export const bus = new Vue()

app.vue에서 가져오기bus이벤트를 내보내는 방법:

<template>
  <div>
    <button @click.prevent="openMyDialog()">my button</button>
  </div>
</template>

<script>
  import {bus} from '../main' // import the bus from main.js or new file
  export default {
    methods: {
      openMyDialog () {
        bus.$emit('dialog', true) // emit the event to the bus
      }
    }
  }
</script>

모달로.vue는 또한 버스를 가져와 생성된 후크에서 이벤트를 청취한다.

<script>
  import {bus} from '../main'    
  export default {
    created () {
      var vm = this
      bus.$on('dialog', function (value) {
        vm.dialog = value
      })
    }
  }
</script>

내가 발견한 가장 간단한 방법은 다음과 같다.

구성 요소의 데이터에서 속성을 반환하십시오. 예를 들어, 대화 상자.

구성 요소를 포함할 때 구성 요소 태그에 대한 참조를 설정할 수 있다.예:

import Edit from '../payment/edit.vue';

<edit ref="edit_reference"></edit>

그리고 나서, 내 컴포넌트 안에서, 나는 다음과 같은 방법을 설정했다.

        open: function () {
            var vm = this;

            vm.dialog = true;
        }

마지막으로, 부모로부터 다음과 같이 전화를 받을 수 있다.

  editar(item)
  {
      var vm = this;

      vm.$refs.edit_reference.open();
  }

당신 안에App.vue template이것을 덧붙이다

<modal></model>

그것이 당신의 현재를 보여줄 것이다.Modal.vue을 템플릿으로 만들다.v-btn그리고v-dialog

이제 그 안에 하나가 있을 것이다.button-Open Dialog네가 그 모달 을 클릭하면 열릴 것이다.

나는 이것을 사용하는 것이 더 좋다:

DialogConfirm.부에를 하다

<template>
  <v-dialog :value="visible" max-width="450">
    <v-card>
      <v-card-title v-text="title" />
      <v-card-text v-text="message" />
      <v-card-actions v-if="visible">
        <template v-for="action in value">
          <v-spacer :key="action.label" v-if="typeof action == 'string'" />
          <v-btn
            v-else
            text
            :key="action.label"
            v-text="action.label"
            @click="doAction(action.action)"
            :color="action.color"
          />
        </template>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component';
import { Prop, Watch } from 'vue-property-decorator';

@Component
export default class DialogConfirm extends Vue {

  @Prop({ type: String, default: "Confirm" })
  title: string

  @Prop({ type: String, default: "Are you sure?" })
  message: string

  @Prop({ type: Array, default: undefined })
  value: { label: string, action: () => boolean, color: string }[]

  get visible() {
    return Array.isArray(this.value) && this.value.length > 0
  }

  doAction(action: () => boolean) {
    if ('undefined' == typeof action || action() !== false) {
      this.$emit('input', null)
    }
  }
}
</script>

사용 예제

/** Disable AP Mode */
  setApMode(enable: boolean) {
    const action = () => {
      Api.get('wifi', {
        params: {
          ap: enable
        }
      }).then(response => this.$store.dispatch('status'))
    }
    if (enable == true) {
      // No confirmation
      return action();
    }
    this.dialogTitle = 'Are you sure?'
    this.dialogMessage = "you may lost connection to this device.";
    this.dialogActions = [
      {
        label: 'Cancel',
        color: 'success'
      },
      'spacer',
      {
        label: "OK, Disable it",
        color: "error",
        action
      }
    ]
  }

methods: {
  openDialog(e) {
    this.dialog = true;
  }
},

이건 내게 효과가 있다.

참조URL: https://stackoverflow.com/questions/48035310/open-a-vuetify-dialog-from-a-component-template-in-vuejs

반응형