❝Светящаяся чаша вина и винограда, если вы хотите пить продукты Pipa. Лорд Мрачный на месте заказчика, сколько людей было похоронено в древности?
❞
В последнее время я занимаюсь разработкой системы управления фоном.Я повторяю формы,таблицы,формы и стандартные резюме день за днем.Мне так скучно.Как мне улучшить себя в этом скучном процессе разработки?wave newVue
Практические боевые навыки, эти навыки, если они вам не нужны, потрясающие. Вы также можете нажать на ссылку ниже, чтобы прочитать наши последние статьи.
Практические навыки, Vue тоже умеет так писать1700+ лайков
Смотрите заработало! Перечитывая руководство по стилю vue 2.0, я сформулировал эти ключевые правила.Понравилось 120+
Слот, я собираюсь просверлить твои руки
Слоты, доверяйте всемVue
Все они были использованы, но как лучше понять слот и как настроить слот, сегодня Xiaobian предлагает вам более яркое описание.
слот по умолчанию
Я просто пошел работать после окончания колледжа, и я был бедным парнем. Я думал, что должен платить арендную плату каждый месяц за аренду дома, поэтому я решил купить квартиру с одной спальней. Я занял кучу долгов, и наконец-то набрали достаточно первоначального взноса и купили маленькую квартирку.грубый дом. Мы можем рассматривать этот однокомнатный грубый дом как составную часть.Тип дома, площадь и этаж - все фиксировано, но как украсить интерьер и какую мебель поставить - решать вам. слот, позволяющий пользователям настраивать контент.
1. Застройщик наконец-то завершил разработку однокомнатной квартиры и сдал дом
<template>
<!--这是一个一居室-->
<div class="one-bedroom">
<!--添加一个默认插槽,用户可以在外部随意定义这个一居室的内容-->
<slot></slot>
</div>
</template>
2. Я собираюсь начать украшать
<template>
<!--这里一居室-->
<one-bedroom>
<!--将家具放到房间里面,组件内部就是上面提供的默认插槽的空间-->
<span>先放一个小床,反正没有女朋友</span>
<span>再放一个电脑桌,在家还要加班写bug</span>
</one-bedroom>
</template>
<script>
import OneBedroom from '../components/one-bedroom'
export default {
components: {
OneBedroom
}
}
</script>
именованный слот
Через несколько лет у редактора появилась девушка, и он собирался жениться. Однокомнатная комната точно не подошла бы. Свекровь считала ее слишком маленькой, поэтому мне ничего не оставалось, как наскрести деньги на покупку. большой дом и двухкомнатная (бедная принудительная), поскольку это двухкомнатная, есть разница между главной спальней и второй спальней.Не может ли украшение сделать главную спальню и вторую спальню точно то же самое, поэтому его нужно различать. Думайте о доме как о компоненте, тогда у компонента есть два слота, и его нужно назвать, чтобы его можно было отличить.
1. Застройщик наконец-то завершил разработку и сдал дом
<template>
<div class="two-bedroom">
<!--这是主卧-->
<div class="master-bedroom">
<!---主卧使用默认插槽-->
<slot></slot>
</div>
<!--这是次卧-->
<div class="secondary-bedroom">
<!--次卧使用具名插槽-->
<slot name="secondard"></slot>
</div>
</div>
</template>
2. Редактор собирается продать кровь, чтобы сэкономить на украшении
<template>
<two-bedroom>
<!--主卧使用默认插槽-->
<div>
<span>放一个大床,要结婚了,嘿嘿嘿</span>
<span>放一个衣柜,老婆的衣服太多了</span>
<span>算了,还是放一个电脑桌吧,还要写bug</span>
</div>
<!--次卧,通过v-slot:secondard 可以指定使用哪一个具名插槽, v-slot:secondard 也可以简写为 #secondard-->
<template v-slot:secondard>
<div>
<span>父母要住,放一个硬一点的床,软床对腰不好</span>
<span>放一个衣柜</span>
</div>
</template>
</two-bedroom>
</template>
<script>
import TwoBedroom from '../components/slot/two-bedroom'
export default {
components: {
TwoBedroom
}
}
</script>
слот с прицелом
Во время ремонта мастер по ремонту спросил меня, где разместить стиральную машину: в ванной или на балконе, в обычных условиях застройщик резервирует место для стиральной машины. И эту позицию можно понимать как параметр, передаваемый слотом, это слот области видимости.
1. Посмотрите параметры, переданные в слот туалета
<template>
<div class="two-bedroom">
<!--其他内容省略-->
<div class="toilet">
<!--通过v-bind 可以向外传递参数, 告诉外面卫生间可以放洗衣机-->
<slot name="toilet" v-bind="{ washer: true }"></slot>
</div>
</div>
</template>
2. Поставьте стиральную машину в ванной
<template>
<two-bedroom>
<!--其他省略-->
<!--卫生间插槽,通过v-slot="scope"可以获取组件内部通过v-bind传的值-->
<template v-slot:toilet="scope">
<!--判断是否可以放洗衣机-->
<span v-if="scope.washer">这里放洗衣机</span>
</template>
</two-bedroom>
</template>
слот по умолчанию
Мой коллега не хотел ждать недостроенный дом, поэтому купил подержанный дом.Предыдущий владелец подержанного дома был отремонтирован и может заселиться напрямую. Конечно, он также может быть отремонтирован.Следующее представляет собой подержанный дом, купленный коллегой.
1. Это отремонтированный подержанный дом.
<template>
<div class="second-hand-house">
<div class="master-bedroom">
<!--插槽可以指定默认值,如果外部调用组件时没有修改插槽内容,则使用默认插槽-->
<slot>
<span>这里有一张水床,玩的够嗨</span>
<span>还有一个衣柜,有点旧了</span>
</slot>
</div>
<!--这是次卧-->
<div class="secondary-bedroom">
<!--次卧使用具名插槽-->
<slot name="secondard">
<span>这里有一张婴儿床</span>
</slot>
</div>
</div>
</template>
2. Мой коллега решил сначала отремонтировать главную спальню, а потом использовать ее для свадьбы.
<second-hand-house>
<!--主卧使用默认插槽,只装修主卧-->
<div>
<span>放一个大床,要结婚了,嘿嘿嘿</span>
<span>放一个衣柜,老婆的衣服太多了</span>
<span>算了,还是放一个电脑桌吧,还要写bug</span>
</div>
</second-hand-house>
Понимание стратегии слияния опций, функция крюка пользовательского жизненного цикла
когда вы используетеVue
изmixins
Когда, есть ли открытие, если смешанноеmethods
Метод внутри имеет то же имя, что и метод компонента, и он будет перезаписан методом компонента, но если функция жизненного цикла имеет такое же имя, будет выполняться смешанный и сам компонент, а порядок выполнения смешанный. в и сам во-первых, как это делается??
1. ПонятьVue
Стратегия слияния
существуетVue
, разные варианты имеют разные стратегии слияния, напримерdata
,props
,methods
Свойства с одним и тем же именем переопределяются и объединяются, другие объединяются напрямую, а функция ловушки жизненного цикла состоит в том, чтобы поместить функции с тем же именем в массив и вызывать их по очереди при вызове. к статье перед редактором.Абсолютно сухой материал~! Изучите эти советы Vue, вы сможете уйти с работы пораньше и встречаться с богиней
существуетVue
, обеспечиваетapi
, Vue.config.optionMergeStrategies
, Вы можете использовать этот API для настройки стратегии слияния параметров.
печатать в коде
console.log(Vue.config.optionMergeStrategies)
Это видно из приведенного выше рисункаVue
Для функции стратегии слияния всех опций мы можем настроить функцию стратегии слияния, переопределив вышеуказанный метод, но обычно он не используется.
2. Настройте функцию жизненного цикла с помощью стратегии слияния.
задний план
Недавно клиент сообщил руководителю, что наша система использовалась в течение определенного периода времени, и браузер немного завис, я не знаю, почему. Проблема вышла, я хотел свалить вину на серверную часть, но проблема с браузером, я не могу свалить вину, так что давайте разбираться.
Позже я обнаружил, что на странице много таймеров,ajax
Анимации есть и в опросе.Открыть вкладку браузера не проблема.Если открыть слишком много, браузер зависнет.На этот раз я подумал,что если можно остановить их,когда пользователь переключает вкладки,то он решиться в ближайшее время. . Искал вдоль и поперёк в Baidu и нашёл событиеvisibilitychange
, который можно использовать для определения того, отображается ли вкладка браузера.
Есть способ, напиши
export default {
created() {
window.addEventListener('visibilitychange', this.$_hanldeVisiblityChange)
// 此处用了hookEvent,可以参考小编前一篇文章
this.$on('hook:beforeDestroy', () => {
window.removeEventListener(
'visibilitychange',
this.$_hanldeVisiblityChange
)
})
},
methods: {
$_hanldeVisiblityChange() {
if (document.visibilityState === 'hidden') {
// 停掉那一堆东西
}
if (document.visibilityState === 'visible') {
// 开启那一堆东西
}
}
}
}
По приведенному выше коду видно, что в каждом файле, который необходимо отслеживать и обрабатывать, необходимо прописать кучу событий мониторинга, чтобы судить о том, отображается страница или нет.По прихоти определите страницу для отображения скрытого жизненного цикла крючки, и инкапсулировать эти суждения.Там, где вам нужно щелкнуть, так просто (считывающая машина запоминает плату за рекламу).
Пользовательская функция хука жизненного цикла
Определение функций жизненного циклаpageHidden
иpageVisible
import Vue from 'vue'
// 通知所有组件页面状态发生了变化
const notifyVisibilityChange = (lifeCycleName, vm) => {
// 生命周期函数会存在$options中,通过$options[lifeCycleName]获取生命周期
const lifeCycles = vm.$options[lifeCycleName]
// 因为使用了created的合并策略,所以是一个数组
if (lifeCycles && lifeCycles.length) {
// 遍历 lifeCycleName对应的生命周期函数列表,依次执行
lifeCycles.forEach(lifecycle => {
lifecycle.call(vm)
})
}
// 遍历所有的子组件,然后依次递归执行
if (vm.$children && vm.$children.length) {
vm.$children.forEach(child => {
notifyVisibilityChange(lifeCycleName, child)
})
}
}
/**
* 添加生命周期钩子函数
* @param {*} rootVm vue 根实例,在页面显示隐藏时候,通过root向下通知
*/
export function init() {
const optionMergeStrategies = Vue.config.optionMergeStrategies
/*
定义了两个生命周期函数 pageVisible, pageHidden
为什么要赋值为 optionMergeStrategies.created呢
这个相当于指定 pageVisible, pageHidden 的合并策略与 created的相同(其他生命周期函数都一样)
*/
optionMergeStrategies.pageVisible = optionMergeStrategies.beforeCreate
optionMergeStrategies.pageHidden = optionMergeStrategies.created
}
/**
* 将事件变化绑定到根节点上面
* @param {*} rootVm
*/
export function bind(rootVm) {
window.addEventListener('visibilitychange', () => {
// 判断调用哪个生命周期函数
let lifeCycleName = undefined
if (document.visibilityState === 'hidden') {
lifeCycleName = 'pageHidden'
} else if (document.visibilityState === 'visible') {
lifeCycleName = 'pageVisible'
}
if (lifeCycleName) {
// 通过所有组件生命周期发生变化了
notifyVisibilityChange(lifeCycleName, rootVm)
}
})
}
применение
- существует
main.js
Импорт файла основной записи
import { init, bind } from './utils/custom-life-cycle'
// 初始化生命周期函数, 必须在Vue实例化之前确定合并策略
init()
const vm = new Vue({
router,
render: h => h(App)
}).$mount('#app')
// 将rootVm 绑定到生命周期函数监听里面
bind(vm)
- Прислушивайтесь к функциям жизненного цикла там, где это необходимо
export default {
pageVisible() {
console.log('页面显示出来了')
},
pageHidden() {
console.log('页面隐藏了')
}
}
provide
иinject
, не только отец и сын передают значение, но и значение предка также может быть передано
Vue
Релевантные интервью часто задают интервьюеры,Vue
Каковы пути передачи ценностей между отцом и сыном, обычно мы ответим,props
проходное значение,$emit
значение прохода события,vuex
передать по значению иeventbus
Передача по значению и т. д., добавьте сегодня еще одинprovide
иinject
передать по значениюoffer
На шаг ближе. (Да, в следующем разделе есть еще один)
использовалReact
студенты знают, что вReact
имеет контекстContext
, компонент может пройтиContext
передать значение любому потомку, в то время какVue
изprovide
иinject
действующий наContext
в основном то же самое
Позвольте мне привести Вам пример
использовалelemment-ui
Учащиеся должны быть знакомы со следующим кодом
<template>
<el-form :model="formData" size="small">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" />
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input-number v-model="formData.age" />
</el-form-item>
<el-button>提交</el-button>
</el-form>
</template>
<script>
export default {
data() {
return {
formData: {
name: '',
age: 0
}
}
}
}
</script>
После прочтения приведенного выше кода кажется, что в этом нет ничего особенного, пишите его каждый день. существуетel-form
Выше мы указали свойствоsize="small"
, а потом нашли все элементы формы и кнопки в формеsize
сталsmall
, это как это сделать? Далее смоделируем форму почерком
рукописная форма
теперь мы подражаемelement-ui
форму, настройте ее самостоятельно, каталог файлов выглядит следующим образом
пользовательская формаcustom-form.vue
<template>
<form class="custom-form">
<slot></slot>
</form>
</template>
<script>
export default {
props: {
// 控制表单元素的大小
size: {
type: String,
default: 'default',
// size 只能是下面的四个值
validator(value) {
return ['default', 'large', 'small', 'mini'].includes(value)
}
},
// 控制表单元素的禁用状态
disabled: {
type: Boolean,
default: false
}
},
// 通过provide将当前表单实例传递到所有后代组件中
provide() {
return {
customForm: this
}
}
}
</script>
В приведенном выше коде мы передаемprovide
Передать экземпляр текущего компонента компонентам-потомкам,provide
это функция, которая возвращает объект
пользовательский элемент формыcustom-form-item.vue
Ничего особенного, просто добавилlabel
,element-ui
сложнее
<template>
<div class="custom-form-item">
<label class="custom-form-item__label">{{ label }}</label>
<div class="custom-form-item__content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
label: {
type: String,
default: ''
}
}
}
</script>
пользовательское поле вводаcustom-input.vue
<template>
<div
class="custom-input"
:class="[
`custom-input--${getSize}`,
getDisabled && `custom-input--disabled`
]"
>
<input class="custom-input__input" :value="value" @input="$_handleChange" />
</div>
</template>
<script>
/* eslint-disable vue/require-default-prop */
export default {
props: {
// 这里用了自定义v-model
value: {
type: String,
default: ''
},
size: {
type: String
},
disabled: {
type: Boolean
}
},
// 通过inject 将form组件注入的实例添加进来
inject: ['customForm'],
computed: {
// 通过计算组件获取组件的size, 如果当前组件传入,则使用当前组件的,否则是否form组件的
getSize() {
return this.size || this.customForm.size
},
// 组件是否禁用
getDisabled() {
const { disabled } = this
if (disabled !== undefined) {
return disabled
}
return this.customForm.disabled
}
},
methods: {
// 自定义v-model
$_handleChange(e) {
this.$emit('input', e.target.value)
}
}
}
</script>
существуетform
, мы проходимprovide
возвращает объект, вinput
, мы можем пройтиinject
Получатьform
Возвращает элементы в объекте в приведенном выше кодеinject:['customForm']
показано, то вы можете пройтиthis.customForm
перечислитьform
Свойства и методы экземпляра
**В приведенном выше коде мы использовали пользовательскийv-model
, о пользовательскихv-model
Вы можете прочитать мою предыдущую статьюАбсолютно сухой материал~! Изучите эти советы Vue, вы сможете уйти с работы пораньше и встречаться с богиней **
использовать в проекте
<template>
<custom-form size="small">
<custom-form-item label="姓名">
<custom-input v-model="formData.name" />
</custom-form-item>
</custom-form>
</template>
<script>
import CustomForm from '../components/custom-form'
import CustomFormItem from '../components/custom-form-item'
import CustomInput from '../components/custom-input'
export default {
components: {
CustomForm,
CustomFormItem,
CustomInput
},
data() {
return {
formData: {
name: '',
age: 0
}
}
}
}
</script>
Выполните приведенный выше код, и результат:
<form class="custom-form">
<div class="custom-form-item">
<label class="custom-form-item__label">姓名</label>
<div class="custom-form-item__content">
<!--size=small已经添加到指定的位置了-->
<div class="custom-input custom-input--small">
<input class="custom-input__input">
</div>
</div>
</div>
</form>
Как видно из приведенного выше кода,input
Компонент установил стиль компонента наcustom-input--small
охватывать
inject
описание формата
В дополнение к тому, что используется в приведенном выше кодеinject:['customForm']
Помимо письма,inject
Также может быть объектом. и может указать значения по умолчанию
Измените приведенный выше пример, еслиcustom-input
нет внешнегоcustom-form
, он не будет вводитьcustomForm
, в это время дляcustomForm
Укажите значение по умолчанию
{
inject: {
customForm: {
// 对于非原始值,和props一样,需要提供一个工厂方法
default: () => ({
size: 'default'
})
}
}
}
если мы хотимinject
Имя входящего свойства не называетсяcustomForm
, но называетсяparentForm
, следующий код
inject: {
// 注入的属性名称
parentForm: {
// 通过 from 指定从哪个属性注入
from: 'customForm',
default: () => ({
size: 'default'
})
}
},
computed: {
// 通过计算组件获取组件的size, 如果当前组件传入,则使用当前组件的,否则是否form组件的
getSize() {
return this.size || this.parentForm.size
}
}
ограничения на использование
-
provide
иinject
Привязки не реактивны. Однако, если вы передаете прослушиваемый объект, как показано вышеcustomForm: this
, то свойства его объекта по-прежнему реагируют. -
Vue
Предложение официального сайтаprovide
иinject
В основном используется при разработке высокоуровневых библиотек плагинов/компонентов. Не рекомендуется использовать в обычном коде приложения. так какprovide
иinject
В коде не прослеживается (ctrl+f можно поискать), рекомендуется использоватьVuex
заменять. Однако это не означает, что его нельзя использовать, и иногда он дает относительно большой эффект при использовании в локальных функциях.
диспетчеризация и широковещательная передача, исторический способ передачи компонентов
$dispatch
и$broadcast
Это исторический способ связи компонентов, зачем история, потому что ониVue1.0
обеспечить способVue2.0
Заброшенный. Но устаревшее не означает, что мы не можем реализовать его вручную, как многие библиотеки пользовательского интерфейса имеют внутренние реализации. Эта статья начинается сelement-ui
Реализация основана на введении. Одновременно прочитав этот раздел, вы будете иметь хорошее представление о компонентах$parent
,$children
,$options
понимать.
Введение метода
$dispatch
: $dispatch
Событие будет инициировано вверх, и в то же время будут переданы имя и параметры запускаемого компонента-предка. распространение прекратится.
$broadcast
: $broadcast
Событие будет распространено на все компоненты-потомки, и будут переданы имя и параметры запускаемого компонента-потомка. остановится (потому что передача вниз древовидная, поэтому будет остановлена только одна из ветвей листьев).
$dispatch
Реализация и применение
1. Реализация кода
/**
* 向上传播事件
* @param {*} eventName 事件名称
* @param {*} componentName 接收事件的组件名称
* @param {...any} params 传递的参数,可以有多个
*/
function dispatch(eventName, componentName, ...params) {
// 如果没有$parent, 则取$root
let parent = this.$parent || this.$root
while (parent) {
// 组件的name存储在组件的$options.componentName 上面
const name = parent.$options.name
// 如果接收事件的组件是当前组件
if (name === componentName) {
// 通过当前组件上面的$emit触发事件,同事传递事件名称与参数
parent.$emit.apply(parent, [eventName, ...params])
break
} else {
// 否则继续向上判断
parent = parent.$parent
}
}
}
// 导出一个对象,然后在需要用到的地方通过混入添加
export default {
methods: {
$dispatch: dispatch
}
}
2. Применение кода
передать дочерний компонент$dispatch
вызвать событие вверх
import emitter from '../mixins/emitter'
export default {
name: 'Chart',
// 通过混入将$dispatch加入进来
mixins: [emitter],
mounted() {
// 在组件渲染完之后,将组件通过$dispatch将自己注册到Board组件上
this.$dispatch('register', 'Board', this)
}
}
существуетBoard
компонент через$on
Прослушивание событий, которые необходимо зарегистрировать
export default {
name: 'Board',
created() {
this.$on('register',(component) => {
// 处理注册逻辑
})
}
}
$broadcast
Реализация и применение
1. Реализация кода
/**
* 向下传播事件
* @param {*} eventName 事件名称
* @param {*} componentName 要触发组件的名称
* @param {...any} params 传递的参数
*/
function broadcast(eventName, componentName, ...params) {
this.$children.forEach(child => {
const name = child.$options.name
if (name === componentName) {
child.$emit.apply(child, [eventName, ...params])
} else {
broadcast.apply(child, [eventName, componentName, ...params])
}
})
}
// 导出一个对象,然后在需要用到的地方通过混入添加
export default {
methods: {
$broadcast: broadcast
}
}
2. Применение кода
передать родительский компонент$broadcast
инициировать событие вниз
import emitter from '../mixins/emitter'
export default {
name: 'Board',
// 通过混入将$dispatch加入进来
mixins: [emitter],
methods:{
//在需要的时候,刷新组件
$_refreshChildren(params) {
this.$broadcast('refresh', 'Chart', params)
}
}
}
передать компоненты-потомки$on
Прослушивание событий обновления
export default {
name: 'Chart',
created() {
this.$on('refresh',(params) => {
// 刷新事件
})
}
}
Суммировать
В приведенном выше примере учащиеся должны уметь$dispatch
и$broadcast
понимаю, но почемуVue2.0
Отказаться от этих двух методов? Официальное объяснение: «Поскольку метод потока событий, основанный на структуре дерева компонентов, действительно сложен для понимания, и он будет становиться все более и более хрупким в процессе расширения структуры компонентов. Этот метод событий действительно не очень хорош, мы также не хочу делать разработчиков слишком болезненными в будущем.$dispatch
и$broadcast
Это также не решает проблему связи между родственными компонентами. "
Действительно, как говорится на официальном сайте, этот метод потока событий действительно не прост для понимания, а стоимость обслуживания в более поздний период относительно высока. Однако, по мнению редактора, независимо от того, черная это кошка или белая кошка, это хорошая кошка, которая может ловить мышей.Во многих конкретных бизнес-сценариях, из-за сложности бизнеса, очень вероятно, что такие будет использоваться метод связи. Но использование принадлежит использованию, но им нельзя злоупотреблять Xiaobian использует его в проекте.
Эпилог
❝Не истощайте свое вдохновение и воображение, не будьте рабом своих моделей. - Винсент Ван Гог
❞
В этой статье используетсяmdniceнабор текста