Лучшие практики разработки Vue

Vue.js

Структура каталогов

Обзор

  • Каталог API используется для хранения запросов API, имя файла в основном такое же, как имя модели, в имени файла используется маленький верблюжий регистр, а имя метода соответствует внутреннему контроллеру покоя.

  • В каталоге enums хранятся константы, соответствующие каталогу констант бэкенда.

  • Каталог icons используется для хранения иконок.Иконок, предоставляемых element-ui, слишком мало.Поэтому я обычно использую иконный шрифт Али

  • Каталог lang хранит несколько языков

  • Каталог layouts хранит макеты

    • Выше показана фоновая система, пустая — это пустой макет. Он используется для страницы входа, а на других страницах используется макет по умолчанию. Макет не нуждается в особом представлении, и вы знакомы с лезвием laravel. макет здесь должен быть таким же, как vue-router с использованием
  • mixins похож на php-трайт, но он мощнее и полностью соответствует жизненному циклу компонентов vue.

  • В каталоге plugins хранятся конфигурации плагинов, такие как axios, vue-lazy и т. д. (это концепция, полученная от nuxt).

  • В каталоге маршрутизатора хранится конфигурация, связанная с внешней маршрутизацией, которая в целом аналогична уровню API laravel.

  • Каталог хранилища — это каталог vuex, аналогичный интерфейсной модели. Его файлы соответствуют внутренней модели и имеют название с небольшим регистром верблюда.

  • В каталоге utils хранятся вспомогательные функции.

  • views — это слой бизнес-представлений, я полагаю, что студенты, изучающие back-end, также знакомы с ним.

  • main.js — это запись приложения, аналогичная index.php бэкенда.

  • каталог компонентов, в котором хранятся компоненты.Обычно некоторые повторно используемые компоненты хранятся отдельно в этом каталоге

В целом очень естественно смотреть на современные front-end проекты с точки зрения back-end MVC: back-end модель соответствует front-end store, back-end router — front-end router, а back-end router — front-end router, внутренний контроллер + представления соответствуют внешним представлениям.

базовая спецификация

В настоящее время проект vue редко использует класс, поэтому файл .js обычно является модулем, поэтому имя файла именуется в форме маленького верблюжьего регистра.Если есть файл класса, файл класса именуется в виде из большого верблюжьего ящика.

Файлы .vue могут быть названы двумя способами: тире и горб.После ссылки на проект element/iview/nuxt рекомендуется использовать тире для именования.

Все имена папок едины с дефисом

При введении компонентов vue файл нужно преобразовать в большой горбimport 'TestTest' from '@/components/test-test'

По-прежнему используйте подчеркивание, когда используется шаблон

<test-test />

Другие соглашения, такие как соглашения об именах и использовании переменных, могут быть легко разрешены с помощью стандарта eslint.

Во внешнем интерфейсе есть много событий, таких как изменение/ввод/загрузка/сумма и т. д. Рекомендуется использовать дескриптор + имя события для соответствующей обработки, напримерhandleChange

Жизненный цикл

vue-router анализирует URL-адрес, введенный текущим пользователем, а затем сопоставляет соответствующий компонент представления для загрузки.

Сосредоточьтесь на моем понимании компонентов представления в каталоге представлений, измененный адрес является примером

Часть скрипта — это часть контроллера, которая запрашивает данные, а затем вводит их в представление, точно так же, как бэкенд mvc.Просто vue записывает vc в файл.Это более естественно для студентов, которые написали бэкэнд. конец.

Как контроллер получает данные?

В прошлых проектах vue мы могли видеть такой способ записи

// ... views/address/edit.vue
created () {
    axios.get('/addresses/1')
        .then((response) => {
             this.list = resposne.data              
        })
}

//...

Такой способ написания ничем не отличается от написания sql-операторов в контроллере на бэкенде, не рекомендуется в инженерной практике, для бэкенда более элегантно и естественно получать данные через модель. обе модели vuex, поэтому рекомендуется

Если вас смущает то, что я говорю, вы можете взглянуть на документацию vuex.Сейчас я описываю лучшие практики для фронтенд-проектов, используя концепции, знакомые с бэкендом.

// ... views/address/edit.vue 控制器+视图
computed: {
    address: () => this.$store.address.itemBy[1] // 从store模型中取出我们想要数据
}
// ...

// ... store/modules/address.js  数据源
export default {
    state: {
        itemBy: {}
    },
    actions: {
        ...
    },
    mutations: {
        ...
    }
}
// ...
Откуда берутся данные в магазине?

Разумеется, данные берутся из базы данных бэкенда, мы не можем позволить фронтенду напрямую обращаться к нашей базе данных, поэтому мы предоставим API для доступа фронтенда, в магазине есть место для инициирования запросов API. , а именно действия.

// ... store/modules/address.js  模型
export default {
    state: {
        itemBy: {}
    },
    actions: {
        async fetchItem({ commit, state }, { id }) {
             // 对axios和api进行了简单的封装,使api请求更加语义化
            cosnt { data } = await address.show(id)
            
            // action只能通过提交commit来修改state,具体原因请查看vuex文档 (其实我也忘了为啥 (╯﹏╰))
            commit('SET_ITEM', data) 
        }
    },
    mutations: {
        SET_ITEM: (state, item) => {
            state.itemBy[item.id] = item
        }
    }
}
// ...

Итак, у нас есть данные в нашей модели

когда звонитьfetchItemКак насчет запроса бэкенда?

router.v ue js.org/this/expensive/ad…Ответы на документацию vue-router

Не рекомендуется вызывать запрос на инициализацию в исходном жизненном цикле vue, что может привести к тому, что данные не были получены, а шаблон отрендерился, что вызовет некоторые исключения, что данные не существуют. Рекомендуется перейти в жизненный цикл vue-router, запросить данные

// ... views/address/edit.vue
async beforeRouteEnter (to, from, next) {
    // 等待模型数据加载完毕,才继续进行vue组件的生命周期
    await store.dispatch('fetchItem', to.params.id) 
    
    next()
}
created () {
    // 不推荐在这里调用 fetchItem
}

//...

Здесь вы можете обнаружить, что это немного отличается от vue, который вы обычно пишете, нет похожегоthis.data = response.dataЭтот вид операции. Этот вид операции на самом деле похож на операцию присваивания или называется побочным эффектом, который вводит понятие времени и усложняет управление данными. Интуитивный вариант заключается в том, что у нас может быть такой избыточныйif(data)судить.

Конечно, побочные эффекты неизбежны, но мы можем управлять ими единообразно. Код, подобный приведенному выше, представляет собой набор методов, которые я считаю неплохими. он был использован или нет.Загрузка завершена, и данные в хранилище не могут быть изменены представлением, то есть данные могут течь только в одном направлении

Еще одним преимуществом единого управления данными в магазине является удобство сохранения.

Как слой представления изменяет источник данных?

Приведенное выше описание на самом деле выражает модель публикации и подписки, поток данных из хранилища в представление является строго односторонним потоком данных.

Слою представления не разрешено напрямую изменять данные в хранилище, но слой представления может влиять на источник данных, отправляя действия.

Например, действие отправки во время инициализации и отправка, вызванная различными событиями.При изменении источника данных уровень представления в качестве подписчика будет перерисовываться очень естественным образом.

Этот дизайн похож на компоненты «родитель-потомок».В Vue дочерним компонентам не разрешено напрямую изменять данные реквизитов родительского компонента для дочерних компонентов, а только путем передачи события родительскому компоненту. Между просмотром и сохранением этот дизайн по-прежнему разумен. .

Это также означает, что все данные в приложении следуют одному и тому же жизненному циклу, что делает приложение более предсказуемым и понятным.

Диаграмма выше хорошо иллюстрирует эту модель разработки.GitHub.com/сорри копия/нет…

Слой просмотра становится глубже

Сценарная часть уровня представления, кроме того, что она выступает в качестве традиционного контроллера и инициализируется, на самом деле делает больше вещей.

Давайте начнем с части данных.Будут некоторые состояния, которые необходимо записать в слой просмотра, такие как раскрытие или свертывание меню, всплывающее окно и закрытие всплывающего окна.Для управления такими состояние, один из способов — сохранить его в части данных.

Некоторые люди также помещают все состояние в состояние обслуживания в хранилище.Состояние делится на два типа: состояние и данные.

Более важной частью скрипта слоя представления является то, что он действует как интерактивная обратная связь, аналогичная следующему коду.

<template>
	<button @click="handleSubmit"/>
</template>

<script>
    export default {
        data: {},
        methods: {
            handleSubmit() {
                
            }
        }
    }
</script>

Что касается части CSS, потому что я не знаю CSS, и я не знаю отраслевые спецификации CSS и лучших практик на Vue, я не буду внося это слишком много.

В заключение

В предыдущем введении каталоги store и api были связаны с данными, когда определяется база данных, эта часть также определяется.

представления/компоненты связаны с бизнесом (UI), и эта часть может быть определена только после определения эскиза проекта.

Слой проекта PS обычно представляет собой разделенную спецификацию компонента 😋

Между представлениями и магазином находится модель подписки и публикации.

два вопроса

Как должно быть организовано состояние в магазине?Для запросов API мы часто видим такие данные JSON

// post
{
    id: 1,
    title: xxxx,
    content: xxxx,
    user: {
        id: xxx,
        nickname: xxx,
        avatar: xxx,
    },
    comments: [
        {
            id: xxx,
            user_id: xxx,
            content: xxx,
            user: {
                // ...
            }
        },
        {
            //....
        }
    ]
}

Приведенная выше структура данных сложна и глубоко вложена. Если мы будем хранить их в состоянии публикации, данные будут слишком концентрированными и избыточными. Комментарии не могут обновляться независимо и т. Д. Это делает интерфейсную схему / форму и организацию данных нормализованной срочной. нужно

Но у vue нет хороших спецификаций и лучших практик в этом отношении React имеет относительно хорошую практику в этом отношении.GitHub.com/Paul проникновение руки RO…

Как разработать хорошие компоненты спецификации?

Дизайн компонентов очень важен на бизнес-уровне.В следующей статье я представлю некоторые из практик, которые я обобщил.