Настоящие сухие товары, поделитесь с твоим сердцем!
Как стать хорошим тайм-менеджером? lzx говорит нам, что если вы спите на несколько часов меньше каждый день, у вас появляется больше времени для занятий спортом.
Для программистов меньше времени каждый день писать бизнес, больше времени заниматься (хуа) оптимизацией (хуа) (шуй).
Сегодня мы говорим о том, как более гибко инкапсулировать бизнес-компоненты в Vue, чтобы удвоить эффективность. потому чтоCtrl + c
ДобавитьCtrl + v
Этого недостаточно, чтобы удовлетворить нас, и нам нужно многое изменить, когда мы переедем. Так что делать?CV工程师
Более быстрая карьера?
Ответ - да! мы называем его配置工程师
, просто и бездумно!
Навыки упаковки компонентов Vue
По сути, основная идея этого метода — инкапсуляция. Но способ упаковки другой, и использование тоже очень разное. Как создать гибкий и простой в использовании пакет — основная цель обсуждения в этой статье.
$attrs
Какой самый простой пакет? Это добавление еще одного слоя к исходному компоненту и сохранение всех функций всего компонента. Затем расширяйте собственный функционал.
сценарий реального случая
Предположим, у нас есть компонентx-button
, к сожалению, этот компонент не поддерживает состояние загрузки! Итак, что же делать? Для удобства пользователя мы должны добавить к нему состояние загрузки. Итак, мы инкапсулируемy-button
:
<template>
<x-button>
<i v-if="loading" class="font-loading"></i>
<slot></slot>
</x-button>
</template>
export default {
name: 'YButton',
props: {
loading: {
type: Boolean,
default: false,
}
}
};
Таким образом, нашy-button
просто поддержитеloading
! Но подождите, если бы мы дали оригиналx-button
Как насчет передачи атрибутов? Простой!
<template>
<x-button :size="size">
<i v-if="loading" class="font-loading"></i>
<slot></slot>
</x-button>
</template>
export default {
props: {
loading: {
type: Boolean,
default: false,
},
size: {
type: String,
default: undefined,
}
}
};
Да все просто, атрибуты оригинального компонента, один плюс один!
Такой уставший! ! ! Мы не можем этого сделать, это слишком неэлегантно. К счастью, Vue предоставляет$attrs
может решить эту проблему.
Так$attrs
Что это такое?
$attrs содержит привязки атрибутов (кроме класса и стиля), которые не распознаются (и не получаются) как реквизиты в родительской области.
Проще говоря, не хочу, я тебе все брошу. Тогда давайте перепишем.
<template>
<x-button v-bind="$attrs">
<i v-if="loading" class="font-loading"></i>
<slot></slot>
</x-button>
</template>
export default {
props: {
loading: {
type: Boolean,
default: false,
}
}
};
Написано так, когда мы передаем свойство вy-button
, Кромеloading
, все остальные атрибуты будут прозрачно переданы вx-button
. Это$attrs
эффект.
Конфигурация + Шаблон
Это ключевой шаг в этой статье, и именно он обеспечивает наибольшую эффективность. Подумайте о том, каково это, когда вы шаг за шагом пишете конфигурацию страницы по схеме прототипа, и страница настроена.
сценарий реального случая
Мы используем самые и самые распространенные в повседневной жизни компоненты: таблица + пейджинг! Серьезно, формы действительно повсюду!
Есть много хороших табличных компонентов, но они действительно сложны в написании и содержат много повторяющегося кода. Время закругляться! мы начинаем сel-table
как базовый компонент.
Примитивные операции ElTable
первый,el-table
используется так:
<template>
<el-table :data="tableData">
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
</template>
export default {
data() {
return {
tableData: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
}
]
};
}
};
Конфигурация столбца
Теперь мы начинаем преобразовывать этот компонент и инкапсулироватьf-table
! Сначала мы будемel-table-column
все сделано.
<template>
<div>
<el-table>
<el-table-column v-for="(col, i) in cols" :key="i" v-bind="col"> </el-table-column>
</el-table>
</div>
</template>
export default {
props: {
cols: {
type: Array,
default: () => []
}
}
};
Итак, когда мы используем это так:
<template>
<div>
<f-table cols=""></f-table>
</div>
</template>
export default {
data() {
return {
cols: [
{
prop: "date",
label: "日期",
width: "180",
formatter: dateFormatter
}
]
};
}
};
Метод сбора данных
Мы знаем по самому примитивному призывуel-table
через
<el-table :data="tableData">
data
свойства для передачи данных. Мы могли бы просто пройти через массив данных напрямую, но мы этого не делаем, потому что здесь мы можем сделать больше.Мы не передаем данные напрямую, а передаем метод для получения данных.
<template>
<div>
<el-table :data="tableData">
<!-- ... -->
</el-table>
</div>
</template>
export default {
props: {
// ...
fetch: {
type: Function,
default: () => Promise.resolve({ rows: [] })
}
},
data() {
return {
loading: false,
tableData: []
};
},
created() {
this.fetchData()
},
methods: {
async fetchData() {
this.loading = true;
try {
const { rows } = await this.fetch();
this.tableData = rows;
} catch (error) {
console.error(error);
} finally {
this.loading = false;
}
}
}!
};
Вы можете видеть, что мы можем установить состояние загрузки таблицы и обрабатывать ошибки при выборке данных. Здесь мы также можем интегрировать пейджинг, но об этом позже. Это экономит нам много работы!
Давайте еще раз посмотрим на код вызова компонента:
<template>
<div>
<f-table :cols="cols" :fetch="fetchUsers"></f-table>
</div>
</template>
export default {
data() {
return {
cols: [
{
prop: "date",
label: "日期",
width: "180"
}
]
};
},
methods: {
fetchUsers() {
return {
rows: [{ name: "xxx", date: "xx" }]
};
}
}
};
Нам нужно только заботиться о том, как получить данные и какие данные отображать. Ушел!
нумерация страниц
OK! Ниже мы решаем проблему пагинации попутно, мы используемel-pagination
.
Примитивная операция ElPagination
<template>
<div>
<el-pagination :current-page.sync="currentPage" :total="total"> </el-pagination>
</div>
</template>
export default {
data() {
return {
currentPage: 1,
total: 0
};
}
};
Интеграция в FTable
<template>
<div>
<el-table :data="tableData">
<!-- -->
</el-table>
<el-pagination @current-change="fetchData" :current-page.sync="currentPage" :total="total">
</el-pagination>
</div>
</template>
export default {
// ...
data() {
return {
// ...
currentPage: 1,
total: 0
};
},
methods: {
async fetchData() {
// ...
const { rows, total } = await this.fetch(this.currentPage);
this.tableData = rows;
this.total = total;
}
}
};
Давайте посмотрим, что мы добавили:
- существует
fetch
пора возвращатьсяtotal
Указывает общие данные для легкой разбивки на страницы - существует
fetch
При передаче текущего номера страницы в функцию - Обновлять данные при изменении номера страницы
И наш код вызова компонента просто добавил несколько строк:
<f-table :cols="cols" :fetch="fetchUsers"></f-table>
methods: {
async fetchUsers(currentPage) {
const query = {
page: currentPage
};
const { rows, total } = await api.getUsers(query);
return { rows, total };
}
}
Таким образом инкапсулируется табличный компонент с автоматическим листанием страниц, и его очень просто использовать.
Конечно, это не отвечает всем вашим потребностям, которые я знаю. Например, если вы хотите использовать самую примитивную форму таблицыel-table-column
, добавьте кнопку в столбец таблицы, добавьте поле ввода или что-то в этом роде.
именованный слот
Если вы хотите настроить контент, использование слота является наиболее подходящим. Но как добавить к нашемуf-table
А внутри?
Помните, мы использовалиcols
настроитьel-table-column
. нам просто нужно показать, чтоcol
этоslot
Достаточно.
<template>
<div>
<el-table :data="tableData">
<template v-for="(col, i) in cols">
<slot v-if="col.slot" :name="col.slot" />
<el-table-column v-else :key="i" v-bind="col"> </el-table-column>
</template>
</el-table>
</div>
</template>
Инструкции:
<template>
<div>
<f-table :cols="cols" :fetch="fetchUsers">
<template slot="action">
<el-table-column>使用原生ElTableColumn的用法</el-table-column>
</template>
</f-table>
</div>
</template>
export default {
data() {
return {
cols: [
{
slot: 'operation'
},
{
prop: "date",
label: "日期",
width: "180"
}
]
};
}
}
резюме
Как только вы привыкнете к этому методу, добавьте различныеformatter
, реально безмозгло писать страничку, поэтому чуть не переделал на перетаскивание (ты что-нибудь нюхал)!
Писать не просто, прошу всех пошевелить пальчиками, обратить внимание и поставить лайк!