Независимо от того, какой веб-сайт в конечном итоге будет реализован, состояние «Загрузка» является важной частью, дающей пользователю возможность передышки, а серверу — время для доставки ответа.
Начните с того, как использовать
Независимо от того, начиная с 0 для записи или прямой загрузки из подключаемого модуля загрузки, он будет абстрагироваться как загрузка компонента Загрузка при использовании или выполняется показ или скрытие вручную через API.
<wait>
</wait>
...
this.$wait.show()
await fetch('http://example.org')
this.$wait.hide()
Или переключайтесь между компонентами через состояние загрузки
<loader v-if="isLoading">
</loader>
<Main v-else>
</Main>
. Для регистрации в качестве глобального состояния также необходимо добавить в пакет сетевых запросов класса axiosперехватчик, а затем задайте глобальное состояние загрузки. Каждый раз, когда поступает сетевой запрос или в соответствии с установленным URL-адресом, состояние загрузки устанавливается нанагрузка, установлен вЗаканчивать.
Зарегистрируйте перехватчик axios:
let loadingUrls = [
`${apiUrl}/loading/`,
`${apiUrl}/index/`,
`${apiUrl}/comments/`,
...
]
axios.interceptors.request.use((config) => {
let url = config.url
if (loadingUrls.indexOf('url') !== -1) {
store.loading.isLoading = true
}
})
axios.interceptors.response.use((response) => {
let url = response.config.url
if (loadingUrls.indexOf('url') !== -1) {
store.loading.isLoading = false
}
})
При использовании получите статус загрузки для каждого компонента, а затем решите, когда отображать загрузку, а когда отображать реальный компонент.
<template>
<div>
<loader v-if="isLoading">
</loader>
<Main v-else>
</Main>
</div>
</template>
<script>
...
components: {
loader
},
computed: {
isLoading: this.$store.loading.isLoading
},
async getMainContent () {
// 实际情况下State仅能通过mutations改变.
this.$sotre.loading.isLoading = false
await axios.get('...')
this.$sotre.loading.isLoading = false
},
async getMain () {
await getMainContent()
}
...
</script>
Он хорошо работает, когда на текущей странице нужно загрузить только одно состояние, но если на одной и той же странице есть несколько разных компонентов, которые необходимо загрузить, вам также необходимо пометить разные компоненты, чтобы загруженные компоненты выполнялись. не вводить повторно Статус загрузки... Поскольку бизнес продолжает расти, повторяющихся суждений о загрузке достаточно, чтобы вызвать у людей раздражение...
Организуйте идеи
Суть загрузки очень проста, т.При запросе сервераЗагрузка должна отображаться,запрос завершенЧтобы восстановить его снова, эту идею не сложно реализовать, но способ использования не может избежать вышеизложенного.явный вызовПуть. По идее, места, где можно установить Loading, это:
- Установите глобальный перехват, установите статус до начала запросанагрузка.
- Установите глобальный перехват и установите статус после завершения запроса.Заканчивать.
- Перехват в функции, которая запускает запрос, установлен нанагрузка, установлен вЗаканчивать.
- Определяем, не пусты ли данные после запроса, если нет, то устанавливаемЗаканчивать
В случае, когда это может быть окончательно реализовано, глобальные настройки перехвата, а затем и локальные суждения проще всего придумать и проще всего реализовать. Устанавливается для каждой запущенной функцииbeforeа такжеafterВыглядит здорово, но это катастрофа для реализации, мы неbeforeа такжеafterЭти две функции перехватывают функцию, чтобы сообщить нам, когда звонить и завершать вызов, многое из этого, чтобы понять свою яму, а не только для того, чтобы понять, что в исходной функции не было статистики использования.по одномузаписывать. Судя только данные очень ограничены, шанс только один.
Так как это plug-and-play подключаемый модуль, он должен быть прост в использовании.Основная идея заключается в использовании глобального перехвата, но локальное суждение немного отличается от обычного, используя привязку данных (конечно, глобальный перехват ответа также можно использовать снова) , давайте сделаем это~.
стиль
Загрузка, у вас должен быть круг, который будет называться Загрузка. Стиль не самая важная часть этого плагина. Здесь мы напрямую используем CSS для достижения простой в реализации и не очень грубой:
<template>
<div class="loading">
</div>
</template>
...
<style scoped>
.loading {
width: 50px;
height: 50px;
border: 4px solid rgba(0,0,0,0.1);
border-radius: 50%;
border-left-color: red;
animation: loading 1s infinite linear;
}
@keyframes loading {
0% { transform: rotate(0deg) }
100% { transform: rotate(360deg) }
}
</style>
Для квадрата фиксированного размера 50 пикселей используйтеborder-radiusСделай его круглее,borderУстановите базу индикатора выполнения,border-left-colorУстановите его как индикатор выполнения.
Привязать данные к URL
Обеспечить внешний интерфейс использования
Как было сказано в приведенной выше идее, этот плагин сделан с глобальным перехватом и привязкой данных:
- Предоставьте исходное свойство, чтобы получить данные, которые будут привязаны к используемому компоненту.
- Предоставьте свойство urls, чтобы получить URL-адрес, который нужно перехватить из используемого компонента.
<template>
...
</template>
<script>
export default {
props: {
source: {
require: true
},
urls: {
type: Array,
default: () => { new Array() }
}
},
data () {
return { isLoading: true }
},
watch: {
source: function () {
if (this.source) {
this.isLoading = false
}
}
}
}
</script>
<style scoped>
....
</style>
Неважно, какой тип данных является источником, нам просто нужно отслеживать его и установить состояние загрузки наЗаканчиватьВот и все, URL-адреса мы улучшим позже.
Настроить перехватчик запросов
Операция, необходимая в перехватчике, состоит в том, чтобы помещать каждый URL-адрес во время запроса в контейнер, а затем удалять его после запроса.
Vue.prototype.__loader_checks = []
Vue.prototype.$__loadingHTTP = new Proxy({}, {
set: function (target, key, value, receiver) {
let oldValue = target[key]
if (!oldValue) {
Vue.prototype.__loader_checks.forEach((func) => {
func(key, value)
})
}
return Reflect.set(target, key, value, receiver)
}
})
axios.interceptors.request.use(config => {
Vue.prototype.$__loadingHTTP[config.url] = config
return config
})
axios.interceptors.response.use(response => {
delete Vue.prototype.$__loadingHTTP[response.config.url]
return response
})
Смонтируйте его на экземпляре Vue, чтобы мы могли вызвать его позже.Конечно, Vuex тоже можно использовать, но этому плагину нужно выделять на одну зависимость меньше, так что Vuex все равно не нужен.
Данные, напрямую смонтированные на Vue, не могут пройтиcomputedилиwatchДля отслеживания изменений данных мы используемProxyперехват проксиsetметод, который что-то делает всякий раз, когда URL-адрес запроса отправляется.Vue.prototype.__loader_checksИспользуется для хранения экземпляров компонентовподпискаКогда запрашивается URL-адрес, выполняется событие загрузки, так что каждый раз, когда URL-адрес нажимается,ProxyДля распространения на подписанный экземпляр компонента Loading.
Подписаться на события URL
<template>
...
</template>
<script>
export default {
props: {
source: {
require: true
},
urls: {
type: Array,
default: () => { new Array() }
}
},
data () {
return { isLoading: true }
},
watch: {
source: function () {
if (this.source) {
this.isLoading = false
}
}
},
mounted: function () {
if (this.urls) {
this.__loader_checks.push((url, config) => {
if (this.urls.indexOf(url) !== -1) {
this.isLoading = true
}
})
}
}
}
</script>
<style scoped>
....
</style>
Каждый из них является совершенно новым экземпляром, поэтому вы можете подписаться на событие URL непосредственно в смонтированном, если есть входящийurls, правильно__loader_checksкаждыйподпискаобъектвыпускать, экземпляр Loader после получения релиза определит, соответствует ли URL-адрес его собственной регистрации, и если да, то установит свое состояние обратно внагрузка, после того, как запрос URL обязательно приведет к обновлению данных, мы отслеживаем вышеуказанноеsourceбуду работатьнагрузкастатус восстановленЗаканчивать.
Используйте слоты для установки оригинальных компонентов
После написания вышеизложенного у вас могут возникнуть сомнения, как скрыть части, которые не должны отображаться при загрузке? Ответ заключается в использовании слотов для адаптации,
<template>
<div>
<div class="loading" v-if="isLoading" :key="'loading'">
</div>
<slot v-else>
</slot>
</div>
</template>
<script>
export default {
props: {
source: {
require: true
},
urls: {
type: Array,
default: () => { new Array() }
}
},
data () {
return { isLoading: true }
},
watch: {
source: function () {
if (this.source) {
this.isLoading = false
}
}
},
mounted: function () {
if (this.urls) {
this.__loader_checks.push((url, config) => {
if (this.urls.indexOf(url) !== -1) {
this.isLoading = true
}
})
}
}
}
</script>
<style scoped>
....
</style>
или черезisLoadingсудить, еслинагрузкаЭто показывает круг, в противном случае он показывает слот, переданный в родительском компоненте,
Обратите внимание, что то, что написано здесь, Vue имеетстранная ошибка,
<div class="loading" v-if="isLoading" :key="'loading'">
</div>
<slot v-else>
</slot>
Там<slot>, если метки одного уровня появляются одновременноv-ifа такжеCSS选择器и стильscoped, затем используйтеCSS选择器Заданный стиль будет потерян,<div class="loading" v-if="isLoading" :key="'loading'">Если не установленоkeyЭто.loadingСтили будут потеряны, кроме установкиkeyВы также можете сделать его вложенным<div v-if="isLoading"> <div class="loading"></div> </div>.
Зарегистрируйтесь как плагин
Плагин в Vue имеетЧетыре способа регистрации, используется здесьmixinбыть смешанным с каждым экземпляром для простоты использования, и мы также зарегистрировали вышеупомянутый перехватчик axios здесь.
import axios
import Loader from './loader.vue'
export default {
install (Vue, options) {
Vue.prototype.__loader_checks = []
Vue.prototype.$__loadingHTTP = new Proxy({}, {
set: function (target, key, value, receiver) {
let oldValue = target[key]
if (!oldValue) {
Vue.prototype.__loader_checks.forEach((func) => {
func(key, value)
})
}
return Reflect.set(target, key, value, receiver)
}
})
axios.interceptors.request.use(config => {
Vue.prototype.$__loadingHTTP[config.url] = config
return config
})
axios.interceptors.response.use(response => {
delete Vue.prototype.$__loadingHTTP[response.config.url]
return response
})
Vue.mixin({
beforeCreate () {
Vue.component('v-loader', Loader)
}
})
}
}
использовать
Использование плагинов в входных файлах
import Loader from './plugins/loader/index.js'
...
Vue.use(Loader)
...
Может использоваться в любом компоненте без импорта
<v-loader :source="msg" :urls="['/']">
<div @click="getRoot">{{ msg }}</div>
</v-loader>
Автоматически отображать и скрывать загрузку в соответствии с привязанными данными и привязанным URL-адресом без ручной настройкиisLoadingДолжен ли он быть скрыт, и нет необходимости звонитьshowа такжеhideПатч в запрошенном методе.
разное
Вышеупомянутое предназначено для определения того, был ли ответ получен путем привязки данных.Если данные после запроса не будут обновляться, вы также можете напрямую перехватить ответ в ответе аксиом для подписки и публикации.
наконец
Keke, пошел к Ян (Hou) SU (Ян), узнав (Wu) True (Chi) Звезды, ищущие ссылки и прикрепитеполный адрес проекта(Я не скажу вам, что код в тестовом адресе выше тоже полный, никогда!).