Резюме обучающего видеоролика проекта Imitation Qunar

Vue.js
Резюме обучающего видеоролика проекта Imitation Qunar

Эта статья не будет написана подробно, основываясь на всем проекте от начала до конца.Многие хорошо написанные боги в сообществе Nuggets написали статью, очень хорошо резюмирующую весь проект, например:Vue.js, разработанный автором Chrislinlin Qunar WebApp, и несколько хорошо написанных статей, я не буду перечислять их по одной.
Так что в этой статье записаны только некоторые моменты, которые я лично записал в блокнот для изучения проекта. Моя личная основная цель этой имитации проекта Qunar — понять, как разрабатывать приложение, как разрабатывать компоненты и как использовать Git для управления кодом (я полностью просмотрел обучающее видео по работе с Git, но я не могу просто смотреть это просто на бумаге, этот проект дал мне реальное понимание Git), и точки знаний vue, которые закрепляют обучение.

1. Каркасная схема проекта

Общий каркас показан на рисунке, а рисунок взят из:byChrislinlin

2. Строительство среды проекта

①узлы
②Управление кодом (в этом проекте используется облако кода) для создания нового хранилища проекта
③Git для загрузки Windows

Добавьте открытый ключ SSH и подключите компьютер к онлайн-репозиторию.
1. Сгенерируйте открытый ключ
2. Откройте Git Bash и введитеssh-keygen -t rsa -C "xxx@xxx.com"Нажмите Enter 3 раза, как будет предложено
3. Просмотрите и скопируйте только что сгенерированный открытый ключ.cat /.ssh/id_rsa.pub
4. Вставьте открытый ключ в офис управления складом git, чтобы установить соединение.
5. После успешного добавления введите в Git Bashssh -T git@gitee.comЕсли появится сообщение Привет ххх, но... значит соединение установлено успешно

⑤Клонируйте файл README.md, созданный онлайн, на локальный
1. Выберите SSH на кнопке клонирования/загрузки в правой части только что созданного репозитория проекта Code Cloud и скопируйте ссылку.
2. Откройте Git Bash и используйте cd, чтобы войти в новый каталог файлов проекта.
3. Вводgit clone+ ссылка просто скопирована
4. Таким образом, клонируйте проект, сгенерированный онлайн, во вновь созданный каталог файлов проекта локально.

Создайте каркас проекта vue в каталоге прямо сейчас (здесь с помощьюvue2.xверсия для примера)
1. Запустите cmd или powershell (или прямую или консоль терминала) в каталоге файла проекта.
2. Вводnpm install --global vue-cliВведите для подтверждения (установлена ​​версия 2.9.6)

3. Вводvue init webpack xxx(xxx) - это название проекта, которое здесь названо Travel.
А. СоветыxxxProject name xxx, нельзя называть название проекта заглавными буквами, вместо этого используйте travel
         b.Project description?Описание проекта, если описания нет, просто нажмите Enter
         c.Author Автор проекта заполняет
         d.Vue.build(Только Runtime+complier и Runtime) Обратите внимание на конкретную разницу между выбором Runtime+complierРазница между Runtime-Compiler и Runtime-Only
         e.Install vue-router?Установить ли маршрутизацию vue, Да
         f.Use ESlint to lint your code?YesСледует ли использовать ESlint для наложения ограничения нормализации на код
              Pick an ESlint prestвыберитеStandand
(Честно говоря, ESlint, если вы не использовали его раньше, время от времени будет предлагать вам сообщение об ошибке с волнистой линией и красной точкой при первом использовании. Иногда это действительно убивает обсессивно-компульсивное расстройство, но это ушло два-три дня, ах, мой код такой аккуратный и удобный, а теперь, если я наберу код без этой штуки, меня тошнит всего)
         g.Set up unit tests?Использовать ли модульное тестирование, этот проект не используется Нет
         h.Set up e2e tests with Nightwatch?Следует ли выполнять сквозное тестирование, то же самое Нет
i.npm yarn выбирает npm для управления пакетами всего проекта

⑦ Проверьте, успешно ли установлены леса и могут ли они работать правильно, введитеcd Travelповторно войтиnpm run devEnter для входа на начальную страницу порта
⑧ Синхронизируйте исходный код онлайн и офлайн
1. Щелкните правой кнопкой мыши каталог файла проекта и выберитеgit bash hereоткрыть git баш
2. Войдите первымgit statusчтобы увидеть, были ли изменения с момента вашего последнего коммита, и теперь все ветки, вы можете увидеть, что было добавлено много новых файлов
3. Вводgit add .добавить все файлы текущего проекта в локальный кеш
4. Вводgit commit -m 'xxxxx'Содержание xxx — это ваше описание измененного файла, представленного на этот раз.
5. Вводgit pushОтправьте файлы вышеуказанных операций в хранилище управления кодом облачного проекта.
После выполнения вышеперечисленных шагов (есть несколько простых и понятных шагов, которые я мог пропустить и не вписать), среда проекта настроена.Вышеизложенное является моим личным пониманием.В середине могут быть некоторые ошибки.Или пожалуйста указать неправильные места.

3. Введение исходного файла проекта

readme.md              //项目的说明文件
package.json         //第三方依赖包配置、项目开发依赖包、依赖环境信息
package.lock.json    //帮助我们去确定安装的第三方依赖包的具体的版本,保持团队编程的统一,锁住一些包的版本,保证程序在这些版本的包下运行是能够正常运行的
license             //开源协议的说明
index.html          //项目默认的首页模版文件
.postcssrc.js        //对 postcss 的配置项
.gitignore          //不需要上传到 git 上的文件管理 、忽略上传到云端的文件
.eslintrc.js        //对写的代码检测是否标准做一个检测、配置了对代码的规范
.eslintignore       //配置不需要 eslintrc 检测工具检测的文件
.editorconfig       //配置编辑器总风格统一的自动化格式的语法
.babelrc            //项目写的代码是 Vue 的大文件组件的代码的写法,所以需要通过 babel 这种语法解析器做一些语法上的转换,最终转换成浏览器能够编译执行的代码,babel 需要做额外配置时,就放在文件里面
static                  //static 目录放的是静态资源,要用到的静态图片啊或者后续需要模拟的 json 数据
node_modules                 //项目中需要用到的第三方 node 包
src                         //放的是项目的源代码
src/main.js                  //整个项目的入口文件
src/app.vue                 //整个项目最原始的根组件
src/router/index.js          //项目的路由放置位置
src/components               //项目中要用到的小组件
src/assets                  //项目中需要用到的图片
config                      //放置项目配置文件
config/index.js              //放基础配置
config/dev.ent.js            //开发环境配置信息
config/prod.ent.js           //线上环境配置信息
build                      //放置项目打包的 webpack 配置信息,vue-cli 会自动构建
build/webpack.base.conf.js   //基础的 webpack 配置信息
build/webpack.dev.conf.js    //开发环境的 webpack 配置信息
build/webpack.prod.conf.js   //线上环境的 webpack 配置信息

4. Заметки по проекту

4.1 Сравнение многостраничных приложений и одностраничных приложений

Многостраничное приложение: переход на страницу →вернуть HTML
Преимущества: быстрое первое экранное время, хороший SEO-эффект (хороший весовой эффект поисковой системы)
Недостаток: медленное переключение страниц
Одностраничное приложение: переход на страницу →JS-рендеринг
Плюсы: быстрое переключение страницы
Недостатки: первое время на экране немного медленнее, а SEO-эффект плохой.

4.2 Путь пользовательского ярлыка проекта

① (строительные леса vue2.x): вwebpack.base.conf.jsПрокрутите вниз и найдите псевдоним в разрешении, чтобы настроить путь быстрого доступа.

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'styles': resolve('src/assets/styles'),
      'common': resolve('src/common')
    }
  },

② (скаффолдинг vue3.0): интегрирован в файл vue.config.js и настроен следующим образом.

module.exports = {
    chainWebpack: (config) => {
      config.resolve.alias
        .set('styles', path.join(__dirname, './src/assets/styles'))
        .set('@', path.join(__dirname, './src/'))
        .set('common', path.join(__dirname, './src/common/'))
    }
}

4.3 Каждый раз, когда разрабатывается новая функция, серия операций Git

① Перейдите на онлайн-хранилище управления кодом, чтобы создать новую ветку функции (рекомендуется назвать имя компонента страницы для удобства управления)
②Войдите в локальный каталог проектаgit bash here,войтиgit pullВытащите онлайн-ветвь
③ Входgit checkout xxxxxxПереключитесь на новую ветку (xxxxxx — это имя вновь созданной ветки)
④Вводgit statusПроверьте ветку, в которой вы сейчас находитесь, подтвердите правильность и начните писать код.

4.4 Серия операций Git после завершения разработки новой функции

①Войдите в локальный каталог проекта и щелкните правой кнопкой мыши, чтобы выбратьgit bash hereоткрыть git баш
②Вводgit add .Добавить все измененные файлы в локальный кеш
③ Входgit commit -m 'xxxxxx'Отправьте и введите описание отправки онлайн (содержание xxxx — это описание отправки и изменений)
④Вводgit pushОтправьте код, отправленный выше, в хранилище управления кодом облачного проекта.
(После того, как вышеперечисленные шаги выполнены, это нехорошо. Мы только что отправили содержимое ветки в облако. Это еще не закончено. Нам нужно объединить ветку.)
⑤Вводgit checkout masterпереключиться на основную ветку
⑥Вводgit merge origin/xxxxxxСлияние ветвей (xxxxxx — вновь созданная ветвь) обычно используется на практике, после тестирования проверка не вызывает проблем, и ветвь объединяется перед выходом в сеть.
⑦Введите еще разgit pushОтправьте содержимое объединенной главной ветки в облако для синхронизации.

4.5 Добавьте фиксированный элемент div, чтобы страница не дрожала из-за проблем со скоростью загрузки сети.

Стиль шаблона этого фиксированного div выглядит следующим образом, показанным на примере данных css.

width:100%
height:0
overflow:hidden
padding-bottom:31.25%

Этот метод обработки используется во всем компоненте проекта, и у мелких партнеров, которые сделали этот проект, должны быть изображения ^_^

4.6 Хранить статические ресурсы под статическими

Для картинок в проекте я использовал некоторые картинки, которые сначала скачал сам, а потом поместил их в новый файл img в директории компонента проекта, но обнаружил, что страница не работает после ссылки, думал написал что-то не так Теперь я неоднократно проверял, есть ли проблема со ссылкой, на которую ссылается src.Проверив несколько раз, я проверил Интернет и обнаружил, что некоторые люди делают то же самое, а затем помещают его в файл в статическом каталоге, и страница будет действующей, поэтому эти статические ресурсы все равно должны быть помещены под статические.

4.7 Оптимизация проблемы остановки автоматического вращения после ручного скольжения изображения карусели (добавлено мной)

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

 swiperOption: {
        pagination: '.swiper-pagination',
        loop: true, //是否循环轮播
        speed: 5000, //滑动速度
        autoplay: {
          delay: 2200, //自动切换时间间隔
          stopOnLastSlide: false //是否切换到最后一幅图时停止自动切换
        },
        autoplayDisableOnInteraction: false// 避免手动滑了之后就停止自动轮播,去掉autoplay可以放入autoplay对象中
      }

4.8 Шаблон стиля css с многоточием автоматически отображается после того, как текст выходит за пределы поля

Чтобы сделать текст из коробки, он будет отображаться... Многоточие css code

overflow:hidden
white-space:nowrap
text-overflow:ellipsis

Если вы не можете, вы добавите Min-Width: 0 в контейнер последнего уровня: 0

4.9 Ли-1 пиксельная пограничная задача на мобильном телефоне

Потому что при написании 1 пикселя на мобильном телефоне вы действительно можете увидеть границу, которая не является 1 пикселем, так как же решить эту проблему? В этом проекте для решения этой проблемы представлен файл border.css, который уже является записанным файлом и может быть импортирован напрямую.После вступления, в том месте, где нужна граница в 1 пиксель, смотрите, где она нужна, вверху, внизу, слева и справа.Если сверху нужно, напишите class="border-top", а также напишите a class="border-bottom" внизу. Конкретный принцип можно найти в этой статьеПроблема с границей 1 пикселя на мобильном телефоне

4.10 Проблема обесцвечивания после кликов роутера

Поскольку у router-link также есть стиль гиперссылки, он изменит цвет после щелчка, поэтому вам нужно добавить фиксированный цвет в поле на этом слое. В противном случае цвет изменится после нажатия

4.11 С или без () и получение объекта источника события при привязке метода

Когда вы нажимаете список города в проекте, вам необходимо получить объект источника событий, при привязке метода@click="handlexxx"Не добавляйте кронштейны, автоматическую входящий исходный объект событий, напишите название метода при написании методовhandlexxx(e){}Таким образом, можно вызвать объект-источник события, например, получить текст под областью, по которой щелкнули, чтоe.target.innerTextможет быть получен.
если@click="handlexxx()"Если вы добавите эту скобку при привязке, вы не сможете получить ее при непосредственном использовании, вы должны добавить ее$event,Прямо сейчас@click="handlexxx($event)", так что вы можете вызвать объект источника события

4.12 Проблема передачи значений между компонентами: передача значений между родительским и дочерним компонентами (дочерний передает родительский, родительский передает дочерний), передача значений между родственными компонентами

Первоначально, на мой взгляд, это можно превратить в две проблемы.Процесс передачи значений между одноуровневыми компонентами на самом деле состоит в том, что ребенок A сначала передает отцу, а затем отец передает его ребенку B. , это не что иное, как то, что ребенок передает отцу, а отец передает его.Эти две проблемы, потому что этот метод также используется в проекте, но я позже проверил в Интернете, что на самом деле есть другой метод (Vuex - это не отдельный метод в этом, я должен знать все vue, которые я изучил) , все такие умные), есть еще один способ - передать данные между братьями с помощью машины событий.

①От отца к ребенку: дочерний компонент записывается наpropsПросто напишите тип (начальное значение) и можете его использовать: call
②От ребенка к отцу: дочерний компонент проходит$emitИнициировать пользовательское событие родительского компонента,this.$emit('xxx自定义事件名',附加参数)Дополнительные параметры, переданные прослушивателю обратного вызова, пример кода ниже конкретной ссылкизначение передачи родительского-дочернего компонента
Сборка:Родительский компонент:③ Передача значений между родственными компонентами через машину событий
1. Для передачи данных между братьями необходимо полагаться на машину событий для передачи данных посредством машины событий.
2. Создайте экземпляр Vue и разрешите всем братьям использовать один и тот же механизм событий.
3. Передайте партию данных, вызванную событиемbus.$emit(方法名,传递的数据)

4. Принимающая сторона черезmounted(){}триггер жизненного циклаbus.$on(方法名,function(接收数据的参数){用该组件的数据接收传递过来的数据}), на этот раз функция изменилась, вы можете использовать функцию стрелки
Пример следующий, мы можем создать отдельный js файл eventVue.js, содержимое будет следующим

import Vue from 'vue'

export default new Vue

Родительский компонент:

<template>
     <components-a></components-a>
     <components-b></components-b>
</template>

Подкомпонент а:

<template>
      <div class="components-a">
           <button @click="abtn">A按钮</button>
      </div>
</template>
<script>
import eventVue from '../../js/event.js'
export default {
      name: 'app',
      data () {
        return {
                'msg':"我是组件A"
        }
      },
      methods:{
           abtn:function(){
                   eventVue .$emit("myFun",this.msg)   //$emit这个方法会触发一个事件
           }
      }
}
</script>

Подкомпонент б:

<template>
     <div class="components-a">
         <div>{{btext}}</div>
     </div>
</template>
<script>
import eventVue from '../../js/event.js'
export default {
   name: 'app',
   data () {
        return {
           'btext':"我是B组件内容"
        }
   },
   created:function(){
       this.bbtn();
   },
   methods:{
       bbtn:function(){
            eventVue .$on("myFun",(message)=>{   //这里最好用箭头函数,不然this指向有问题
                 this.btext = message      
            })
       }
    }
}
</script>

4.13 Оптимизация списка перетаскивания города

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

handleTouchMove(e) {
    if (this.touchStartus) {
        const starY = this.$refs['A'][0].offsetTop
        const touchY = e.touches[0].clientY - 79
        const index = Math.floor((touchY - startY) / 20)
        if (index == 0 && index < this.letters.length){
            this.$emit('change', this.letters[index])
        }
    }
}

(1) startY будет вычисляться повторно, что приводит к потере производительности, поэтому нам нужно улучшить производительность на 1. уменьшение количества вычислений, метод заключается вconst starY = this.$refs['A'][0].offsetTopПоместите эту строку кода вupdated(){}В функции хука жизненного цикла, чтобы уменьшить количество вычислений, потому что только когда данные, переданные из другого компонента, изменяют страницу, повторный рендеринг страницы должен пересчитывать это значение.
(2) При перетаскивании алфавита города функция метода выполняется слишком часто, мы можем выполнять этот метод реже, поэтому мы можем улучшить производительность этой части за счет анти-дрожания. Сначала создайте новое значение в данныхtimer:null, а затем измените код следующим образом:

 handleTouchMove (e) {
      if (this.touchStatus) {
        if (this.timer) {
          clearTimeout(this.timer)
        }
        this.timer = setTimeout(() => {
          const touchY = e.touches[0].clientY - 79
          const index = Math.floor((touchY - this.startY) / 20)
          if (index >= 0 && index < this.letters.length) {
            this.$emit('change', this.letters[index])
          }
        }, 16)
      }
    },

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

4.14 Примечания по использованию localStorage

При использовании localStorage вы должны помнить об отлавливании исключений, поскольку некоторые пользователи закрывают локальное хранилище браузера или используют режим браузера в режиме инкогнито (анонимный режим), который напрямую вызывает генерацию исключений, поэтому используйте перехват исключений, чтобы избежать ненужных событий. в файлеmutations.js под магазином написано следующее

export default {
  changeCity (state, city) {
    state.city = city
    try {
      localStorage.city = city
    } catch (e) {}
  }
}

Напишите так под state.js

let defaultCity = '北京'
try {
  if (localStorage.city) {
    defaultCity = localStorage.city
  }
} catch (e) {}

export default { // 公用数据
  city: defaultCity
}

4.15 Функции Vuex Getters

Геттеры Vuex аналогичны вычисляемым и могут вычислять новые данные на основе статических данных в vuex, чтобы избежать избыточности данных.

4.16 Html5 решает проблему задержки клика в 300 мс

Для решения этой проблемы раньше ее решали введением пакета fastClick, а для Html5 добавить новую строчку прямо в html{ touch-action:manipulation }Это решаемо, так где же эта строчка кода используется в проекте? Сначала я думал, что это написано в html под файлом index.html, но поиском не нашел, а позже обнаружил, что это написано во введенииreset.cssВниз

4.17 Назначение значения имени в компоненте

①Используется для рекурсивного использования компонентов (таких как столбец тарифа на странице сведений о городе)
②Отменить выбор кеша для страницы (exclude="xxxxxxx组件")
③Вид разработки Vue

4.18 Устранение взаимодействия поведения прокрутки при переключении страниц

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

// 每次做路由切换的时候,始终回到最顶部
  scrollBehavior (to, form, savedPosition) {
    return {x: 0, y: 0}
  }

4.19 Проблема перетаскивания страницы на странице списка городов

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

4.20 Ошибка белого экрана при тестировании мобильного телефона

Некоторые мобильные телефоны не поддерживают Promise, что вызовет ошибку белого экрана, когда мобильный телефон войдет в тест локальной сети, поэтому для решения этой проблемы мы можем установить следующий пакет для ее решения.npm install babel-polyfill --saveИмпорт после установки


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

Домашняя страницаСтраница со списком городовСтраница сведений о городе