Перед Vue3.0 просмотрите использование новых функций Vue2.0.

внешний интерфейс

1. Селектор действия глубины ( >>> )

Строго говоря, это должна быть функция vue-loader. "vue-загрузчик": "^12.2.0"

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

Селектор действия по глубине (оператор >>>) может вам помочь.

<template>
<div>
  <h1 class="child-title">
    如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作   
  </h1>
</div>
</template>
<script>
export default {
  name: 'child',
  data() {
    return {}
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.child-title {
  font-size: 12px;
}
</style>

В дочернем компоненте выше.child-titleОбласть CSS устанавливает размер шрифта 12 пикселей, и теперь я хочу настроить его в родительском компоненте на размер 20 пикселей и красный цвет.

<template>
<div>
  <child class="parent-custom"></child>
</div>
</template>
<script>
import Child from './child'
export default {
  name: 'parent',
  components: {
    Child
  },
  data() {
    return {}
  }
}
</script>
<style>
.parent-custom  >>> .child-title {
  font-size:20px;
  color: red;
}
</style>

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

<style lang="less">
.parent-custom {
  >>> .child-title {
    font-size:20px;
    color: red;
  }
}
</style>
ERROR in ./~/css-loader!./~/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-960c5412","scoped":false,"hasInlineConfig":false}!./~/postcss-loader!./~/less-loader!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/components/parent.vue
Module build failed: Unrecognised input
 @ /src/components/parent.vue (line 22, column 6)
 near lines:
   .parent-custom {
     >>> .child-title {
       font-size:20px;

Решение состоит в том, чтобы использовать менее выходящие (лопаты) и переменную интерполяцию (переменная интерполяция)

<style lang="less">
@deep: ~'>>>';
.parent-custom {
  @{deep} .child-title {
    font-size:20px;
    color: red;
  }
}
</style>

2.4.0 Новый

Все мы знаем, что если мы передаем три реквизита a, b и c при использовании подкомпонентов, а подкомпонентыpropsПараметр объявляет только a и b, тогда c будет отображаться в корневом элементе дочернего компонента как пользовательский атрибут html после рендеринга.

Если вы этого не хотите, вы можете установить элемент конфигурации подкомпонентаinheritAttrs:falseКорневой элемент будет намного чище.

<script>
export default {
  name: 'child',
  props: ['a','b'],
  inheritAttrs: false
}
</script>

$attrsа также$listeners

Первый взглядvm.$attrs

vm.$attrs

Тип: {[KEY: String]: String}

только чтение

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

Его можно свести к двум пунктам:

vm.$attrsЭто встроенное свойство компонента, а значением являются все значения, переданные родительским компонентом.propне объявленный компонентом вprop(кроме класса и стиля).

Или перед примерами дочерних компонентов

// parent.vue
<template>
  <div>
    <child 
      class="parent-custom" 
      a="a" 
      b="b" 
      c="c">
    </child>
  </div>
</template>
// child.vue
<script>
export default {
  name: 'child',
  props: ['a','b'],
  inheritAttrs: false,
  mounted() {
    // 控制台输出:
    // child:$attrs: {c: "c"}
    console.log('child:$attrs:', this.$attrs)
  }
}
</script>

Компоненты могут использоваться в своих собственных подкомпонентах.v-bind='attrs', а затем передать значение своим дочерним компонентам. То есть дочерний компонент будетattrsзначение, переданное вpropразберитесь с этим, соблюдая при этом правила пункта 1.

// parent.vue
<template>
  <div>
    <child 
      a="a" 
      b="b" 
      c="c">
    </child>
  </div>
</template>
// child.vue
<template>
  <div>
    <grand-child 
      v-bind="$attrs" 
      d="d">
    </grand-child>
  </div>
</template>
<script>
export default {
  name: 'child',
  props: ['a','b'],
  inheritAttrs: false
}
</script>
// grandchild.vue
<script>
export default {
  name: 'grandchild',
  props: [],
  // props: ['c'],
  inheritAttrs: false,
  mounted() {
    // 控制台输出:
    // grandchild:$attrs: {d: "d", c: "c"}
    console.log('grandchild:$attrs:', this.$attrs)
​
    // 如果props: ['c']
    // 控制台输出:
    // grandchild:$attrs: {d: "d"}
  }
}
</script>

vm.$listeners

Тип: { [ключ: строка]: функция | массив }

только чтение

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

Его можно свести к двум пунктам:

  1. vm.$listenersявляется встроенным свойством компонента, а его значением является родительский компонент (исключая.nativeдекоратор) прослушиватель событий v-on.

  2. Компоненты могут использоваться в своих собственных подкомпонентах.v-on='$listeners', а затем передать значение своим дочерним компонентам. Если дочерний компонент уже привязанlistenerСлушатель с таким же именем, две функции прослушивателя будут выполняться в пути.

// parent.vue
<template>
  <div>
    <child @update="onParentUpdate"></child>
  </div>
</template>
<script>
export default {
  name: 'parent',
  components: {
    Child
  },
  methods: {
    onParentUpdate() {
      console.log('parent.vue:onParentUpdate')
    }
  }
}
</script>
// child.vue
<template>
  <div>
    <grand-child 
      @update="onChildUpdate" 
      v-on="$listeners">
    </grand-child>
  </div>
</template>
<script>
export default {
  name: 'child',
  components: {
    GrandChild
  },
  methods:{
    onChildUpdate() {
      console.log('child.vue:onChildUpdate')
    }
  }
}
</script>
// grandchild.vue
<script>
export default {
  name: 'grandchild',
  mounted() {
    // 控制台输出:
    // grandchild:$listeners: {update: ƒ}
    console.log('grandchild:$listeners:',this.$listeners);
​
    // 控制台输出:
    // child.vue:onChildUpdate
    // parent.vue:onParentUpdate
    this.$listeners.update()
  }
} 
</script>

3. Параметры компонента обеспечивают/вводят

2.2.0 NEW

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

//parent.vue
<template>
  <div>
    <child></child>
  </div>
</template>
<script>
export default {
  name: 'parent',
  provide: {
    data: 'I am parent.vue'
  },
  components: {
    Child
  }
}
</script>
// child.vue
<template>
  <div>
    <grand-child></grand-child>
  </div>
</template>
<script>
export default {
  name: 'child',
  components: {
    GrandChild
  }
}
</script>
// grandchild.vue
<script>
export default {
  name: 'grandchild',
  inject: ['data'],
  mounted() {
    // 控制台输出:
    // grandchild:inject: I am parent.vue
    console.log('grandchild:inject:',this.data);
  }
}
</script>

provide 选项应该是一个对象或返回一个对象的函数。 Этот объект содержит свойства, которые можно внедрить в его потомков.

Параметр INJECT должен быть строковым массивом или объектом, представляющим имя локального имени привязки, а Value — ключом к значению Value.

В версии 2.5.0+, когда параметр inject является объектом, вы также можете указать from для представления исходного атрибута и по умолчанию указать значение по умолчанию (если это не примитивное значение, следует использовать фабричный метод).

const Child = {
  inject: {
    foo: {
      from: 'bar',
      default: 'foo'
      //default: () => [1, 2, 3]
    }
  }
}

В-четвертых, прицел слот слот-прицел

2.1.0 Новый

В версии 2.5.0+ slot-scope больше не ограничивается элементами шаблона, а может использоваться для любого элемента или компонента внутри слота.

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

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

// data-show.vue
<template>
<div>
  <ul>
    <li v-for="item in list">
      <span>{{item.title}}</span>
      <slot v-bind:item="item">
      </slot>
    </li>
  </ul>
</div>
</template>
// list.vue
<template>
<p>列表页</p>
  <data-show :list="list">
    <template slot-scope="slotProps">
      <span v-if="slotProps.item.complete">✓</span>
      <span v-else>x</span>
    </template>
  </data-show>
</template>
// edit.vue
<template>
<p>编辑页</p>
<data-show :list="list">
  <template slot-scope="slotProps">
    <a v-if="slotProps.item.complete">查看</a>
    <a v-else>修改</a>
  </template>
</data-show>
</template>

Пять, захват ошибок Vue

Настройте errorHandler глобально

С 2.2.0 этот крюк будет захватывать крючок жизненного цикла компонента по ошибке.

Начиная с версии 2.4.0, этот хук будет захватывать обработку пользовательских событий Vue внутри ошибки функции.

Более подробное описание можно найти в документации errorHandler.

Ошибка хука жизненного цикла.

2.5.0+ Новый

Более подробное описание можно найти в документации errorCaptured

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

Vue.component('ErrorBoundary', {
  data: () => ({ error: null }),
  errorCaptured (err, vm, info) {
    this.error = `${err.stack}\n\nfound in ${info} of component`
    return false
  },
  render (h) {
    if (this.error) {
      return h('pre', { style: { color: 'red' }}, this.error)
    }
    // ignoring edge cases for the sake of demonstration
    return this.$slots.default[0]
  }
})
<error-boundary>
  <another-component/>
</error-boundary>

Следует подчеркнуть, что errorCaptured не фиксирует собственные ошибки и асинхронные ошибки (например, ошибки, генерируемые сетевыми запросами, событиями мыши и т. д.).

In 2.5 we introduce the new errorCaptured hook. A component with this hook captures all errors (excluding those fired in async callbacks) from its child component tree (excluding itself).

Ссылаться на