VueJ의 구성 요소 템플릿에서 Vuetify 대화 상자 열기s
VueJS Vuetify 프레임워크를 사용하고 있는데 다른 템플릿에서 구성 요소 템플릿으로 가져오는 대화 상자를 열어야 해.App.vue의 Menu 버튼을 클릭하면 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
로서 떠받치다.value
로v-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;
}
},
이건 내게 효과가 있다.
'IT이야기' 카테고리의 다른 글
왜 람다에서는 인쇄가 안 되는가? (0) | 2022.03.28 |
---|---|
gradlew assembly 실행 중 메모리 부족 오류릴리스 - react-native (0) | 2022.03.28 |
기본 반응, 정의되지 않은 인덱스에 대해 정의된 경로가 없음 (0) | 2022.03.28 |
vue 3.2에서 사용자 지정 요소 정의와 함께 vuex를 사용하는 방법 (0) | 2022.03.28 |
Vue - v-bind 및 소품을 사용한 선택 요소에 대한 양방향 바인딩 (0) | 2022.03.28 |