«Поддержка Jing» на основе практики одностраничных приложений Vue + Vuex.

Vue.js Vuex vue-router
«Поддержка Jing» на основе практики одностраничных приложений Vue + Vuex.

Получив запрос на проект «Jing Maintenance», я узнал, что это проект мобильного терминала, который используется в общедоступной учетной записи WeChat и приложении Jingdong. Благодаря связи с внутренним отделом исследований и разработок, серверный отдел предоставит все интерфейсы отображения данных, поэтому, наконец, было принято решение использовать технологию разделения внешнего и внутреннего интерфейса, и в качестве внешнего интерфейса она очень подходит. выбрать одностраничное приложение на основе webpack + Vue для достижения.

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

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

  1. Найдите «Jingdong Auto Supplies» в официальной учетной записи WeChat — следуйте официальной учетной записи — «Jing Maintenance» в строке меню, см. рис. 1;
  2. JD.com APP — My — My Car — JD Maintenance, см. рис. 2.

фигура 1

фигура 2

Если вы не можете найти запись «Мой автомобиль» в приложении, вы должны сначала перейти в приложение Jingdong — «Мой» — «Настройки» — «Добавить профиль» — «Мой автомобиль» — «Привязать свой автомобиль», и тогда будет вход.

Зачем использовать Vuex

Предварительный технический отбор, проект стартовал, и в процессе разработки выяснилось, что в проекте есть разные виды форм, требующие обмена большим объемом данных. Однако использование только одностраничного маршрута для передачи параметров не может удовлетворить требованиям, поскольку объем данных слишком велик, что делает параметры маршрутизации слишком сложными. Таким образом, технология Vuex внедряется в проект для реализации обмена данными.

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

  1. Заполнить номерной знак на странице привязанного автомобиля;
  2. Заполнить серию автомобиля, включая выбор марки, выбор серии автомобиля, выбор года выпуска;
  3. Вернитесь на страницу привязанного транспортного средства и продолжайте заполнять информацию о привязке транспортного средства.

Если описание не понятно, я также записал небольшое видео, нажмите для просмотра процесса взаимодействия:

Video Playerзагрузить файл

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

Использование Vuex

Существует несколько основных концепций для конкретного использования Vuex:

  1. state — определяет состояние хранения;
  2. Getter - фильтрация данных;
  3. мутация — единственный способ изменить состояние в хранилище Vuex — отправить мутацию;
  4. действие — аналогично мутации, за исключением того, что может содержать произвольные асинхронные операции;
  5. модули — если приложение слишком большое, вы можете использовать модули для разделения управления, чтобы магазин не сильно раздувался.

Конкретная реализация экземпляра магазина:

import Vuex from 'vuex';//引入
Vue.use(Vuex);//使用
export default new Vuex.Store({
    state: {
        formParams: {},
        address: {}
    },
actions: {
    GET_SERIES_LIST: function({ commit }, params) {
        axios.get(url, { params: data, withCredentials: true })
                .then(response => {
                    commit('setBrandsList', { data });
                });
   },
    },
    mutations: {
        setAddress: (state, data) => {
            state.address = data;
        }
    },
    getters: {},
    modules: {}
});

Пример использования:

Пример метода в дочернем компоненте, который считывает состояние:

computed: {
    address () {
        return store.state.address;
    }
}

Пример изменения состояния компонента через коммит:

this.$store.commit('setAddress',params);

Пример компонента, инициирующего вызов действия через диспетчеризацию:

this.$store.dispatch('GET_SHOPS_LIST',params);

Постоянное хранилище Vuex

Вышеупомянутый Vuex действительно очень удобен в использовании и решает проблему обмена данными между несколькими представлениями. Но процесс приложения приносит новую проблему, заключающуюся в том, что хранилище состояния Vuex не может быть постоянным. То есть, когда вы сохраняете данные в хранилище в Vuex, пока страница обновляется, данные будут потеряны.

Затем я быстро подумал об использовании sessionStorage или localStorage для решения этой проблемы. Решение состоит в том, чтобы сохранять значение хранилища при каждой мутации.Поскольку мутации — это единственный способ изменить состояние, нет проблем с сохранением значения хранилища для каждого изменения.

mutations: {
    setAddress: (state, data) => {
        state. address = data;
        window.localStorage.setItem(' address ',data);
    },
    //…
}

На самом деле описанный выше метод ручного доступа к localStorage можно сделать проще. То есть представить плагин vuex-persist, который является плагином для постоянного хранилища Vuex. Вам не нужно вручную обращаться к хранилищу, а сохраните состояние непосредственно в файле cookie или localStorage. Конкретное использование заключается в следующем:

import VuexPersistence from 'vuex-persist';//引入
const vuexLocal = new VuexPersistence({//配置
    storage: window.sessionStorage
});
export default new Vuex.Store({
    state: {
        formParams: {},
        address: {}
    },
    actions: {
    },
    mutations: {
        setAddress: (state, data) => {
            state.address = data;
        }
    },
    plugins: [vuexLocal.plugin]//添加插件
});

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

Междоменные проблемы запроса данных, с которыми сталкиваются локальные проекты разработки

Когда проект разрабатывается локально и не был развернут в тестовой среде, запросы данных проекта всегда являются междоменными.Хотя во многих статьях говорилось о том, как решить междоменную проблему, возникла новая проблема в этот проект. Поскольку серверная часть настроена с указанным разрешенным междоменным доменным именем (например, local.jd.com), не любое доменное имя может разрешить междоменный доступ после CORS Chrome (подробности об этом методе см. в статье.Одностраничная практика Jingdong E-Dimension на основе vue+webpack»).

Когда мы обычно разрабатываем локально, путь доступа к проекту — http://localhost:8080, а указанное доменное имя может быть доступно между доменами Нам нужно только локально настроить host: 127.0.0.1 local.jd.com, поэтому к которому вы можете использовать http://localhost:8080 для доступа. Однако после этой настройки интерфейс данных по-прежнему сообщает, что к нему нельзя получить доступ через домены. Позже было обнаружено, что конфигурация webpack-dev-server является именем хоста поиска по умолчанию. Добавление конфигурации disableHostCheck: true может изменить его поиск по умолчанию. поведения, и проблема решена.

Схема запроса данных и запрос JSONP

Поговорим о схеме запроса данных: раньше мы использовали vue-resource, но Vue официально отказался от него. Эван Ю, автор Vue, выразился так:

Недавно команда обсуждала, что сам Ajax не имеет какой-либо специальной интеграции с Vue.Такой же эффект может дать использование fetch polyfill или axios, суперагента и т. д. Ценность, предоставляемая vue-resource, не сравнивается со стоимостью его обслуживания. -эффективно, поэтому решил отменить официальную рекомендацию vue-resource в ближайшее время. Существующие пользователи могут продолжать использовать его, но vue-resource больше не будет использоваться в качестве официального решения ajax в будущем.

Здесь vue-ресурс можно удалить, а документацию переводить не нужно.

Связь:GitHub.com/v UE Fe/v UE JS…

Поэтому в проекте выбран axios для поддержки запросов данных, но axios не поддерживает запросы JSONP.В проекте есть несколько интерфейсов, которые должны использовать JSONP, поэтому вводится модуль JSONP для поддержки запросов данных JSONP. Пример вызова:

jsonp('//d.jd.com/xxxx?fid=1&callback=getAreaListCallBack');
window.getAreaListCallBack = function(r) {
    console.log(r);
};

Инкапсулируйте код, когда это необходимо

Поскольку проект продолжает развиваться, обнаружено, что действия в магазине накапливаются все больше и больше кода, а также много повторных кодов. Один из них перечислен ниже, остальные похожи:

actions: {
        //获取服务记录查询及记录列表
        GET_SERVICE_LIST: function({ commit }, params) {
            axios.get(this.state.host + '/xxxxxx', {
                params: params,
                withCredentials: true
            }).then((response) => {
                commit('setServiceList', { list: response.data.data });
                // params.success(response.data);
            }, (err) => {
                console.log(err)
            });
        }, 
        //…
}

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

xhr: function(apiskey, params, changeState) {
        let apis = this.apis;
        let url = debug ? host + apis[apiskey].url : apis[apiskey].url;
        let data = params.params || params || {};
        let type = apis[apiskey].type || 'get';
        if (type == 'post') {
            axios.post(url, data, {
                    withCredentials: true
                })
                .then(response => {
                    //…
                }, response => {
                    //…
                });
        } else {
            axios.get(url, { params: data, withCredentials: true })
                .then(response => {
                    //…
                }, response => {
                    //…
                });
        }
}

Внедрение сторонних файлов в компоненты Vue

В проекте есть отдельные представления (рисунок 3), которые должны отображать карту, а введение карты требует внедрения сторонней библиотеки карт, например Tencent или др. При входе в приложение сторонняя файлы на самом деле не требуется загружать напрямую, просто загружайте их, когда вам это нужно. Итак, в представлении, отображающем карту, я сделал следующее, чтобы сторонняя JS-библиотека карт загружалась только в этом представлении.

loadMap() {
    let self = this;
    return new Promise(function(resolve, reject) {
        window.initTheMap = function() {
            resolve(self.initMap());
        }
        var script = document.createElement('script')
        script.type = 'text/javascript'
        script.async = true
        script.src = '//map.qq.com/api/js?v=2.exp&callback=initTheMap&key=' + self.k
        script.onerror = reject
        document.head.appendChild(script);
    });
}

изображение 3

Извлечение компонентов

Все представления в проекте можно рассматривать как компоненты.Компоненты, которые необходимо извлечь здесь, относятся к модулям и функциям с высокой степенью повторного использования. Например: верхняя панель, всплывающее окно, тост-подсказка, бесконечная загрузка и другие функции извлекаются как отдельные компоненты. Извлечение компонентов может сделать вашу разработку более эффективной и в то же время упростить поддержку проекта. Поэтому в структуре проекта есть отдельная папка для хранения компонентов с высокой степенью повторного использования (рис. 4).

Рисунок 4

Конкретный метод вызова компонента, например, вызов верхней панели:

В компоненте основного вида вам нужно представить компоненты, которые вам нужно использовать:

import Header from '../component/header.vue';

Затем зарегистрируйте компонент:

components: {
    jHeader: Header
}

Используемый шаблон:

<j-header :title="title"></j-header>

Конкретное содержимое, на которое указывает верхняя панель, показано в области в красной рамке на рис. 5.

Рисунок 5

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

Области для улучшения в проекте

Без отложенной загрузки Vue размер JS-файла всего приложения этого проекта составляет около 200 КБ, что на данный момент приемлемо.Если содержимое проекта больше, могут быть JS-файлы большего размера, в результате в течение длительного времени ожидания первого приложения, поэтому в сложных проектах можно рассмотреть возможность добавления решения отложенной загрузки для загрузки JS по запросу.

напиши в конце

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

На этом статья заканчивается, если в вышеизложенном есть что-то неразумное, прошу меня поправить!