Резюме проекта VUE ElementUI

Vue.js

Описание Проекта

vue + axios + vue-router + vuex + ElementUI

vue

обновление данных vue, просмотр, а не обновление

Свойства, которые существуют в данных только при создании экземпляра, являются реактивными, Vue не может обнаружить добавление или удаление свойств объекта;
Реактивные свойства могут быть добавлены к вложенным объектам с помощью метода Vue.set(object, key, value)

Vue.set(vm.userProfile, 'age', 27)
this.$set(this.transportAddData.serviceOrderList[a].serviceOrderItems[i], 'deletePoundIds', [])

vue данные и методы
соображения об обнаружении изменений объекта vue

Vue не может обнаружить следующие изменяющиеся массивы:

  • Когда вы устанавливаете элемент напрямую с помощью индекса, например: vm.items[indexOfItem] = newValue
  • При изменении длины массива, например: vm.items.length = newLength

Обнаружение обновления массива vue

Оптимизация непрерывных триггерных событий

Непрерывный запуск события может использовать регулирование функции и защиту от сотрясений для оптимизации производительности.

//防抖
function(){  
    ...
    
    clearTimeout(timeoutId);

    timeoutId = setTimeout(function () {
      console.log('content', content);
      player(content.msgTypeId, comId)
    }, 500);
    
    ...
    
}

// 节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
    if(!canRun){
        // 判断是否已空闲,如果在执行中,则直接return
        return;
    }

    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);
};

Throttling (дросселирование) и Debouncing (анти-тряска) javaScript

nextTick

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



get() {
    this.$http.get('/api/article').then(function (res) {
        this.list = res.data.data.list
        // ref  list 引用了ul元素,我想把第一个li颜色变为红色
        document.querySelectorAll('li')[0].style.color = 'red'  //这里会报错-,因为还没有 li
        
        this.$nextTick( ()=> {
            document.querySelectorAll('li')[0].style.color = 'red'
        })
    })
},

Принцип и использование Vue.nextTick

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

Google Chrome (Chrome 66) ошибка автовоспроизведения звука

DOMException: play() failed because the user didn’t interact with the document first.

Решение: АудиоКонтекст

// Chrome
request.get('/baseConfig/messageAudio/play', {
    params: {
        "comId": Cookies.get('comId'),
        "msgTypeId": id
    },
    responseType: 'arraybuffer'   // 这里需要设置xhr response的格式为arraybuffer
    })
    .then(req => {
    
    ...
    
        let context = new (window.AudioContext || window.webkitAudioContext)();
        context.decodeAudioData(req.data, decode => play(context, decode));
                  
        function play (context, decodeBuffer) {
            sourceadio = context.createBufferSource();
            sourceadio.buffer = decodeBuffer;
            sourceadio.connect(context.destination);
            // 从0s开始播放
            sourceadio.start(0);
        }
    
    ...
    
})

Chrome 66 отключает звук после автозапуска
AudioContext
AudioContext.decodeAudioData()

vuex

Способ и разница с использованием Vuex для изменения состояния

  • Вы можете напрямую использовать это. $ Store.state.Variable = xxx;
  • this.store.dispatch(actionType, payload) 或者 this.store.commit(commitType, payload)

Та же самая точка: может изменять переменные в состоянии и реагировать (может запускать обновления представления)
Разница: если strict: true передается, когда Vue создает хранилище, включается строгий режим, то любая операция, которая изменяет состояние, пока она не проходит функция мутации, vue сообщит о следующей ошибке

throw error :    [vuex] Do not mutate vuex store state outside mutation handlers。

Преимущества использования фиксации для отправки на мутацию для изменения состояния: vuex может записывать каждую запись об изменении состояния, сохранять моментальные снимки состояния и реализовывать такие операции, как перемещение по времени/откат.

Разница между отправкой и фиксацией заключается в следующем:
Использование отправки — это асинхронная операция, фиксация — синхронная операция,
Поэтому в целом рекомендуется использовать фиксацию напрямую, то есть this.$store.commit(commitType, payload), чтобы предотвратить проблемы с задержкой, вызванные асинхронными операциями.

vuex strict
vuex Mutation
vuex actions

что такое векс

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

== Состояние в vuex по сути является скрытым компонентом vue без шаблона. ==

Подробное объяснение принципа работы vuex

axios

Проблемы совместимости

Почтовый запрос Edge 41.16299.15.0 будет автоматически преобразован для получения

microsoft-edge/platform/issues
Vue использует axios для отправки запросов в браузерах EDGE в запросы на получение.

отменить запрос

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

  • решение
    axios имеет собственный метод отмены cancelToken, а затем останавливает предыдущий запрос после скачка маршрутизации
// 请求拦截中 添加 cancelToken
axios.interceptors.request.use(config => {
    config.cancelToken = store.source.token
    return config
}, err => {
    return Promise.reject(err)
})
 
// 路由跳转中进行判断
router.beforeEach((to, from, next) => {
    const CancelToken = axios.CancelToken
    store.source.cancel && store.source.cancel()
    store.source = CancelToken.source()
    next()
})


//sort文件/
state: {
    source: {
      token: null,
      cancel: null
    }
  }

axios api
Используйте axios для отмены всех запросов при изменении маршрута
Перехватчик запроса Axios и отмена функции ожидающего запроса в проекте vue

Существует проблема: если всплывающее окно с запросом на истечение срока действия токена является вторым всплывающим окном подтверждения, и переход на страницу будет выполнен после повторного подтверждения, то предыдущий запрос на странице будет продолжен до нажатия кнопки «Подтвердить»;
Решение. Добавьте глобальное состояние во всплывающее окно и определите, нужно ли раскрывать всплывающее окно в соответствии с состоянием.

предварительный запрос

Перекрестный домен CORS
CORS требует поддержки как браузера, так и сервера. В настоящее время все браузеры поддерживают эту функцию, == Браузер IE не может быть ниже IE10. ==
Браузеры делят запросы CORS на две категории: простые запросы и не очень простые запросы.

  • простой запрос
  1. Метод запроса является одним из трех методов:
    HEAD
    GET
    POST
  2. Информация заголовка HTTP не превышает следующих полей: Принимать
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type: ограничено тремя значениями application/x-www-form-urlencoded, multipart/form-data, text/plain

Простые запросы не запускают предварительные запросы CORS.

  • не простой запрос

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

  1. Был использован любой из следующих методов HTTP:
    PUT
    DELETE
    CONNECT
    OPTIONS
    TRACE
    PATCH
  2. Искусственно задайте другие поля заголовка, отличные от поля заголовка CORS-safe. Коллекция: Принимать Accept-Language Язык содержания Content-Type (но обратите внимание на дополнительные требования ниже) ДНР Нисходящая линия Сохранить данные Viewport-Ширина Ширина
  3. Значение Content-Type не является одним из следующих:
    application/x-www-form-urlencoded
    multipart/form-data
    text/plain
  4. Объект XMLHttpRequestUpload в запросе имеет любое количество зарегистрированных прослушивателей событий.
  5. В запросе использовался объект ReadableStream.

HTTP-контроль доступа (CORS)

  • предварительный запрос

Для непростых запросов запрос запроса, инициированный методом HTTP OPTIONS, будет добавлен перед формальным общением, которое называется предварительным запросом. чтобы узнать, разрешает ли сервер фактический запрос. Использование «предварительного запроса» может предотвратить неожиданное влияние междоменных запросов на пользовательские данные сервера.
==Этот метод не повлияет на ресурсы сервера==

  • Оптимизация
Access-Control-Max-Age: <delta-seconds> //单位是秒。

Указывает, как долго может кэшироваться возвращаемый результат предварительного запроса (то есть информация, предоставленная методами Access-Control-Allow-Methods и Access-Control-Allow-Headers).

Vue Router

Разница между push и replace

push добавит новую запись в историю, а replace просто заменит исходную запись без добавления новой записи; Это приводит к тому, что страница, пропущенная методом замены, не может вернуться на предыдущую страницу (аналогично window.history).

Программная навигация vue Router

Отложенная загрузка маршрута

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

{
    path: '/iov/login',
    name: '登录',
    component: resolve => require(['@/views/login/login'], resolve),
},
{
    path:'/iov/organization',
    name:'组织管理',
    component:() => import('@/views/enterprise/organization')
}

Отложенная загрузка маршрутизации Vue Router
vue асинхронный компонент
vue + vue-router lazy load import/require+require

elementUI

Во всплывающем окне формы elementform очищает остаточный запрос проверки

Добавьте другую ссылку (REFNAME) в форму, если есть такая же ссылка, это приведет к тому, что запрос остаточного подтверждения не будет очищен.

    this.dialogTranspor = true
    //弹窗打开后 dom 没有生成,所有要用 this.$nextTick
   
    this.$nextTick(function () {
     
        this.$refs.REFNAME.resetFields();

      })

Количество страниц не может отображаться правильно

Сценарий: страница списка возвращается на страницу списка после перехода к сведениям или другим страницам, соответствующий номер страницы не может отображаться нормально (номер страницы помещается в состояние), но запрошенные данные в норме;

Решение: Количество страниц и общее количество страниц должны быть в одном объекте, иначе текущее количество страниц не может нормально отображаться

data() {
    return {
        //完成查询条件
        searchComplate: {        
        "comId": Cookies.get('comId'),
        "transportOrderCode": null,
        "orderCode": null,
        "customerId": null,
        "abnormal": 2,
        "startTime": null,
        "endTime": null,
        "pageNum": 1,
        "pageSize": 20,
        total: 0,
        currentRow: '',
        dataArea: ['', ''],
        activeName: '',
        expands: []
        },
    }
}

Динамическая многоуровневая проверка формы

<li v-for="(item,index) in transportAddData.serviceOrderList">
 
    <template v-for="(subItem,subIndex) in item.serviceOrderItems">
    
        <tr >
                    
            <td>
              <el-form-item :prop="'serviceOrderList.'+index+'.serviceOrderItems.' + subIndex + '.addressName'"
                            :rules="{required: true, message: '卸货地不能为空', trigger: 'blur'}">
                <el-input v-model="subItem.addressName" placeholder="地址"></el-input>
              </el-form-item>
            </td>
            <td>
              <el-form-item :prop="'serviceOrderList.'+index+'.serviceOrderItems.' + subIndex + '.planTonnage'"
                            :rules="[{required: true, message: '必填项', trigger: 'blur'},{pattern: /^((([1-9]+(\d+)?)(\.\d+)?)|(0\.\d+))$/, message: '必须为正数且不为0'}]">
                <el-input v-model="subItem.planTonnage"
                          placeholder="预卸吨数"></el-input>
              </el-form-item>
            </td>
            ...
            
        </tr>
        
    </template>

</li>