В последнее время у компании есть back-end бизнес, хотя он тоже написан в существующей back-end системе, но будет вытащен для этого бизнеса для создания новой back-end системы, поэтому библиотека компонентов vue в существующей серверную систему использовать нельзя (поскольку я не знаю, на какой библиотеке компонентов будет основана будущая система, на случай, если это создаст проблемы для будущих проектов трансплантации), в этот раз я столкнулся с функцией всплывающего окна, поэтому Я могу написать только один вручную (хотя компонент всплывающего окна очень прост, я также хочу обобщить его сам, и, пожалуйста, укажите, что не так.) В начале я использовал традиционные реквизиты, $emit, но я чувствовал что логика получения двух обратных вызовов для отмены и подтверждения была разбросана, поэтому я использовал два обратных вызова обещания, Способ написания двух обратных вызовов вместе не обязательно хорош, но дает идею.
1. Обзор
Сначала посмотрите на последний звонок
props $emit方式
<chat-modal ref="chat-modal" v-model="showModal" cancelText="取消" sureText="确认" title="弹窗标题" small @on-ok="onOK" @on-cancel="onCancel">
<div>slot的东西,想向弹窗中添加自定义的内容</div>
</chat-modal>
methods: {
display() {
this.showModal = true;//交互点击手动触发显示弹窗
},
onOK() {},//点击确认的回调
onCancel() {}//点击取消的回调
}
promise的回调方式
<chat-modal ref="chat-modal"></chat-modal>
methods: {
display() {
this.$refs["chat-modal"].openModal({
title: "弹窗标题",
sureText: "确认",
cancelText: "取消"
}).then(res => {
//点击确认的回调
}, res => {
//点击取消的回调
})
}
}
Второй способ - принести пользу все логику сосредоточенность в одном случае.
2. Посмотрите исходный код компонента
совет: стиль немного гнилой...
<template>
<div>
<div class="shadow" v-show="showModal"></div>
<div class="modal" :class="{'smSize': otherText.small || small}" v-show="showModal">
<div class="header">{{ otherText.title || title}}</div>
<div class="body">
<slot></slot>
</div>
<div class="footer">
<div class="item success" id="sure" ref="sure" @click="makeSure" v-show="otherText.sureText || sureText">{{ otherText.sureText || sureText }}</div>
<div class="item red" id="cancel" ref="cancel" @click="makeCancel" v-show="otherText.cancelText || cancelText">{{ otherText.cancelText || cancelText }}</div>
</div>
</div>
</div>
</template>
<script>
//此组件提供两种调用方法,可以在组件上v-model一个表示是否显示弹窗的对话框,然后需要的一些值通过props传入,然后$emit在组件上@监听做回调
//第二中方法所有的传值回调都只需要在组件内部的一个方法调用然后在组件外部this.$refs[xxx].open调用然后.then触发回调,比上一种方便些
var initOtherText = {
sureText: "",
cancelText: "",
title: "",
small: false
};
export default {
props: {
title: {
type: String
},
sureText: {
type: String
},
cancelText: {
type: String
},
value: {
type: Boolean
},
small: {
type: Boolean
}
},
watch: {
value(newVal) {
this.showModal = newVal;
}
},
data() {
return {
otherText: JSON.parse(JSON.stringify(initOtherText)),
showModal: this.value
};
},
methods: {
makeSure() {
this.$emit("on-ok");
this.$emit("input", false);
},
makeCancel() {
this.$emit("on-cancel");
this.$emit("input", false);
},
openModal(otherText) {
this.otherText = { ...otherText };
this.showModal = true;
var pms = new Promise((resolve, reject) => {
this.$refs["sure"].addEventListener("click", () => {
this.showModal = false;
resolve("点击了确定");
});
this.$refs["cancel"].addEventListener("click", () => {
this.showModal = false;
reject("点击了取消");
});
});
return pms;
}
}
};
</script>
<style lang="scss" scoped>
.shadow {
background-color: rgba(0, 0, 0, 0.5);
display: table;
height: 100%;
left: 0;
position: fixed;
top: 0;
transition: opacity 0.3s ease;
width: 100%;
z-index: 50;
}
.modal {
display: table-cell;
vertical-align: middle;
overflow-x: hidden;
position: fixed;
background-color: white;
box-shadow: rgba(0, 0, 0, 0.33) 0px 2px 8px;
border-radius: 5px;
outline: 0px;
overflow: hidden;
transition: all 0.3s ease;
width: 600px;
height: 400px;
top: 50%;
left: 50%;
margin-top: -200px;
margin-left: -300px;
}
.header {
align-items: center;
background-color: #62a39e;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.16);
color: #fff;
font-weight: bold;
display: -ms-flexbox;
display: flex;
height: 3.5rem;
padding: 0 1.5rem;
position: relative;
z-index: 1;
}
.body {
align-items: center;
padding: 1.5rem;
}
.footer {
justify-content: flex-end;
padding: 1.5rem;
position: absolute;
bottom: 0;
width: 100%;
float: right;
}
.item {
color: white;
text-align: center;
border-radius: 5px;
padding: 10px;
cursor: pointer;
display: inline-block;
}
.info {
background-color: #2196f3;
}
.success {
background-color: #62a39e;
}
.red {
background-color: #e95358;
}
.smSize {
height: 200px;
}
</style>
Сначала проанализируйте первый метод:
Вызывающий должен связать переменную (showModal в этом примере) с v-моделью вне компонента, чтобы указать, отображается ли всплывающее окно.Когда оно отображается, его необходимо вручную установить вне компонента.this.showModal = true
, внутренние реквизиты компонента определяют свойство для получения этого значенияvalue: {type: Boolean}
, при объявлении переменной внутри компонента для синхронизации значения реквизита, переданного извне默认值为 showModal: this.value
(Значение, объявленное внутри, также называется ShowModal), прослушайте часы для синхронизацииwatch: { value(newVal) { this.showModal = newVal } }
Затем свяжите значение ShowModal внутри компонента к элементу DOM, который должен быть показан или скрыт. Когда событие выброшено, это когда нажата кнопки ОК и закрытия внутри компонента
makeSure() {
this.$emit("on-ok");
this.$emit("input", false);
},
makeCancel() {
this.$emit("on-cancel");
this.$emit("input", false);
}
this.$emit("on-ok");this.$emit("on-cancel");
Эти два предложения предназначены для того, чтобы выбрасывать события из компонента @ и затем писать нужную вам функцию обратного вызова. В это время можно реализовать отображение и скрытие всплывающего окна.Вы можете обнаружить, что нет кода для установки this.showModal = false, всплывающее окно скрыто. В основном из-за этих нескольких строк кодаv-model = 'showModal'
и внутри компонентаprops: {value: {type: Boolean}} this.$emit("input", false)
. v-model на самом деле является синтаксическим сахаром для vue,<chat-modal v-model="showModal">
На самом деле это можно записать как<chat-modal :value="showModal" @input="showModal = arguments[0]">
Поэтому требуется, чтобы мы указали, что имя реквизита должно быть значением внутри компонента,
Затем запустите его внутри компонента, когда внутри компонента запускается OK или отмена.this.$emit("input", false)
Это позволяет постоянному скрывать всплывающее окно, не мешая пользователю и позволит пользователю вручную устанавливать ShowModal в False за пределами компонента.
Затем посмотрите на путь обетования: Значения, переданные первым способом, все получены через свойства, Таким образом, внутри компонента определяется другой объект для получения входящих значений.
var initOtherText = {
sureText: "",
cancelText: "",
title: "",
small: false
};
otherText: JSON.parse(JSON.stringify(initOtherText)),
Затем в ментодах определяется метод с именем openModal, а затем ряд переданных параметров назначается объекту внутри компонента.this.otherText = { ...otherText }; this.showModal = true;
И установите для showModal значение true, а затем создайте новый объект обещания каждый раз, когда он запускается.Асинхронные события в нем — это два события щелчка: нажмите OK и отмена.Здесь нам нужно манипулировать DOM.
this.$refs["sure"].addEventListener("click", () => {
this.showModal = false;
resolve("点击了确定");
});
Получите событие привязки элемента DOM кнопки OK, установите для showModal значение false в обратном вызове и разрешите,
this.$refs["cancel"].addEventListener("click", () => {
this.showModal = false;
reject("点击了取消");
});
Получите событие щелчка привязки DOM для кнопки отмены и отклоните его.
яма столкнулась
Раньше я столкнулся с яме, потому что событие CLICK было впервые связано, а разрешение и отклонение потерпят неудачу во второй раз. Я хотел отменить событие для привязки, но потому что все всплывающее окно V-Show = " ShowModal "Причина в том, что отображается весь дом: нет; нет необходимости вручную развивать его. Во-вторых, о использовании V-iF или V-шоу, чтобы скрыть всплывающее окно. Я использовал V-если в начале, но нашел, что на этом шаге
this.showModal = true;
var pms = new Promise((resolve, reject) => {
this.$refs["sure"].addEventListener.xxx//省略
});
return pms;
Когда ShowModal установлен в True, затем перейдите к связывающим событиям. Еще нет домо. ;
по приоритетным вопросам
Если значение (название, sureText и т. д.) передается компоненту с реквизитом, например<chat-modal" title="xx" sureText="xxx"></chat-modal>
также передается в методе
this.$refs["chat-modal"].openModal({
title: "服务小结",
sureText: "提交并结束",
cancelText: "取消"
}).then();
Приоритет метода выше, и приоритет устанавливается с помощью || в элементе DOM внутри компонента, например<div class="header popModal">{{ otherText.title || title}}</div>
Значение метода принимает значение метода, а значение реквизита не берется.
Ожидание плохого или неправильного места