Несколько советов по читабельности кода Vue | Награда за комментарии

внешний интерфейс Vue.js опрос

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

предисловие

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

1. Используйте компоненты, чтобы сделать код более организованным

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

Цель предоставления компонентов Vue заключается не только в повторном использовании, но и в разделении кода и даже в эффективном использовании компонентов для оптимизации рендеринга и скорости обновления страниц.Это связано с тем, что рендеринг страницы VUE обновляется для обновления компонентов на странице, если только данные, на которые ссылается компонент, не изменяются.

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

1.1. Извлечение компонентов пользовательского интерфейса

Как определить компоненты пользовательского интерфейса? Лично рекомендуется различать компоненты пользовательского интерфейса и бизнес-компоненты в зависимости от того, следует ли обрабатывать данные на стороне сервера. Например, всплывающие окна загрузки, всплывающие окна вторичного подтверждения, окна сообщений и т. д. относятся к компонентам взаимодействия с пользовательским интерфейсом.

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

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

this.$confirm(message, title, options)
  .then(res =>{})
  .catch(err =>{})

Таким образом, бизнес-код может быть написан в функции обратного вызова, а основной код реализации компонента выглядит следующим образом:

//confirm.vue
<template>
  <div v-show="show">
    //...
    <div @click="ok"></div>
    <div @click="cancel"></div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      show: false,
    }
  },
  methods: {
    ok() {
      this.show = false;
      this.resolve();
    },
    cancel() {
      this.show = false;
      this.resolve();
    },
  }
}
</script>
//index.js
import Vue from 'vue';
import options from './confirm.vue';
const Confirm = Vue.extend(options);
let confirm = undefined;
const ConfirmInit = (options = {}) => {
  return new Promise((resolve, reject) => {
    options.resolve = resolve;
    options.reject = reject;
    confirm = new Confirm({
      el: document.createElement('div'),
      data: options
    })
    document.body.appendChild(confirm.$el);
    Vue.nextTick(() => {
      if (confirm) confirm.show = true;
    })
    return confirm;
  })
}
Vue.prototype.$confirm = ConfirmInit;
//main.js
import 'components/confirm/index.js';//全局注册二次确认弹窗confirm组件

1.2 Извлечение бизнес-компонентов по модулям

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

1.3 Извлечение функциональных компонентов по функциям

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

Функции большие и маленькие, и есть несколько принципов, на которые следует обратить внимание при извлечении:

  • Слишком простые функции не извлекаются

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

  • Функция должна быть одиночной, а функциональный компонент занимается только одним бизнесом.

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

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

    Правильный способ — настроить событие на метке компонента.on-fileOpen-success,использоватьhandleFileOpenSuccessфункция прослушивания этого события.

    <fileReader 
      @on-fileOpen-success="handleFileOpenSuccess"
    >
    </fileReader>
    

    Выполнить в методе, который прослушивает успешное открытие файла в компонентеthis.$emit('on-fileOpen-success',data)запускает это событие, гдеdataИнформация о файле может быть передана вhandleFileOpenSuccessФункции для обработки бизнес-взаимодействий, таких как коллекции или добавление исторических записей, а затем коллекций. Эта практика делает компонент чтения файлов монолитным.

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

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

    //upload.vue
    <template>
      <div>
        <slot name="icon"></slot>
      </div>
    </template>
    
    //index.vue
    <template>
      <div>
        <upload>
          <template #icon>
            //上传图标
          </template>
        </upload>
      </div>
    </template>
    

2. Используйте v-bind, чтобы сделать свойства компонента более читабельными

Если вы хотите иметь все свойства объекта какpropПередайте компонент componentA, вы можете использовать его без параметровv-bind. Например, для данного объектаparams:

params: {
  id: 1,
  name: 'vue'
}

До оптимизации

<componentA :id="params.id" :name="params.name"></componentA>

Оптимизировано

<componentA v-bind="params"></componentA>

3. Используйтеattrsа такжеатрибуты спрослушиватели для инкапсуляции сторонних компонентов

1. $атрибуты

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

Например, инкапсулируйте компонент поля ввода ввода myInput в компонент elementUi.При вводе неправильного содержимого под полем ввода будет отображаться сообщение об ошибке.

Код компонента myInput выглядит следующим образом:

<template>
  <div>
    <el-input v-model="input"></el-input>
    <div>{{errorTip}}</div>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: String,
      default: '',
    },
    errorTip: {
      type: String,
      default: '',
    }
  },
  data() {
    return {
    }
  },
  computed: {
    input: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit('input', val)
      }
    }
  }
}
</script>

Компонент myInput вызывается так, гдеerrorTipВведите неправильную подсказку для поля ввода.

<myInput v-model="input" :errorTip="errorTip"></myInput>

Если вы хотите добавить компонент myInputdisabledатрибут, чтобы отключить поле ввода, как этого добиться? обычные школьники так делают

<template>
  <div>
    <el-input v-model="input"
      :disabled="disabled"></el-input>
    <div>{{errorTip}}</div>
  </div>
</template>
<script>
export default {
  props: {
    //...
    disabled: {
      type: Boolean,
      default: false
    }
  },
  //...
}
</script>

Через некоторое время я добавлю другие свойства компонента el-input в компонент myInput.Всего компонентов el-input более 27, так что мне делать?Передавать их с реквизитами, что не только плохо читаемый, но и громоздкий. ,Можно использовать$attrsШаг за шагом, давайте сначала посмотримattrsОпределение.

$attrs: Содержит родительский объем не такpropПривязка признанного (и полученного) атрибута (кроме класса и стиля). Когда компонент не объявляет никакихprop, все привязки родительской области (кроме класса и стиля) включены сюда, и к ним можно получить доступ черезv-bind="$attrs"Пропустить внутренние компоненты

<template>
  <div>
    <el-input v-model="input"
      v-bind="$attrs"></el-input>
    <div>{{errorTip}}</div>
  </div>
</template>

Этого недостаточно, мы должныinheritAttrsпараметры установлены наfalse, почему, посмотримinheritAttrsОпределение опционов понятно.

Привязки атрибутов родительской области, которые по умолчанию не считаются реквизитами, будут «отступать» и применяться к корневому элементу дочернего компонента как обычные атрибуты HTML. Это может не всегда вести себя так, как ожидается, при написании компонентов, которые обертывают целевой элемент или другой компонент. установивinheritAttrsдляfalse, это поведение по умолчанию будет удалено. и через$attrsВы можете заставить эти атрибуты действовать, а можете передатьv-bindЯвно привязан к некорневым элементам. Примечание. Этот параметр не влияет на привязки классов и стилей.

Проще говоря, положитьinheritAttrsУстановить какfalse,v-bind="$attrs"вступить в силу.

<template>
  <div>
    <el-input v-model="input"
      v-bind="$attrs"></el-input>
    <div>{{errorTip}}</div>
  </div>
</template>
<script>
export default {
  inheritAttrs: false,
  props: {
    value: {
      type: String,
      default: '',
    },
    errorTip: {
      type: String,
      default: '',
    }
  },
  data() {
    return {
    }
  },
  computed: {
    input: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit('input', val)
      }
    }
  }
}
</script>

Таким образом, свойства компонента el-input можно четко отличить от свойств компонента myinput, а удобочитаемость параметра props компонента значительно улучшается.

2. $слушатели

Итак, как реализовать пользовательские события для компонента el-input в компоненте myIpput, возможно, ваша первая реакцияthis.$emit.

<template>
  <div>
    <el-input v-model="input"
      v-bind="$attrs"
      @blur="blur">
    </el-input>
    <div>{{errorTip}}</div>
  </div>
</template>
<script>
export default {
  //...
  methods: {
    blur() {
      this.$emit('blur')
    }
  }
}
</script>
<myInput 
  v-model="input"
  :errorTip="errorTip"
  @blur="handleBlur">
</myInput>

Компонент el-input имеет 4 пользовательских события, что не так уж и много.Если вы встретите сторонние компоненты с большим количеством пользовательских событий, что делать?Добавление их по одному не только добавит кучу ненужных методов, но и Плохая читабельность может быть легко перепутана с собственными методами myInput. На самом деле вы можете использовать$listenersШаг за шагом, давайте сначала посмотрим$listenersОпределение.

$listeners: содержит прослушиватель событий v-on в родительской области (без декоратора .native). Его можно передать внутренним компонентам через v-on="$listeners" .

<template>
  <div>
    <el-input v-model="input"
      v-bind="$attrs"
      v-on="$listeners">
    </el-input>
    <div>{{errorTip}}</div>
  </div>
</template>
<script>
export default {
  //...
}
</script>
<myInput 
  v-model="input"
  :errorTip="errorTip"
  @blur="handleBlur">
</myInput>

В компоненте myInput просто добавьте компонент el-inputv-on="$listeners", вы можете использовать пользовательские события компонента el-input в компоненте myInput.

метод лотереи

Помещение:

  • С 10 сентября, если в области комментариев взаимодействуют более 10 человек (за исключением самого автора), автор может нарисовать 2 значка Nuggets от своего имени (официальное обязательство Nuggets).

  • Комментатор не может быть мелким аккаунтом, типа LV0, без исторических новостей, или только лайкать аккаунт определенного автора;

  • В комментариях не должно быть слов «не нравится», «поддерживаю», «добро пожаловать, не нравится» и т. д. или подобные комментарии;

Метод рисования:

Все подходящие комментаторы будут выбраны случайным образом 2.

Инструменты розыгрыша:

choujiang.wiicha.com/

Время розыгрыша:

10 сентября 2021 г. 21:00