предисловие
Эта статья - чисто конспект некоторого личного опыта в обычном процессе практики. Это маленькая хитрость. Это не гениальная технология. Если она вам поможет, это будет честью.
Эта статья не охватывает罕见API
Методы использования и т. д. Большая часть контента основана на некоторой практике работы с Vue. Из-за предполагаемого оппортунизма это может привести к некоторым побочным эффектам, которые не соответствуют спецификациям, пожалуйста, используйте его в соответствии с требованиями проекта.
-
Метод, используемый несколькими страницами, помещается в
vue.prototype
На будет очень удобноновичок в
vue
Когда я сделал глупость, потому что инкапсулировал асинхронный интерфейс запросаpost
, вставитьpost.js
файл, а затем добавляйте его на каждую страницу, которая должна использовать асинхронные запросы.import port from './xxxx/xxxx/post'
Если это просто так, то ничего, мы можем написать страницу и скопировать ее позже, и мы можем убедиться, что каждая страница имеет приведенное выше утверждение. Но что, если каждый файл находится в другой иерархии каталогов?
// 假设正常是这样 import port from '../xxxx/xxxx/post' // 目录加深一级,就变成这样 import port from '../../xxxx/xxxx/post' // 再加深一级的样子 import port from '../../../xxxx/xxxx/post'
Конечно, в настоящее время мы можем использовать псевдонимы
@/xxxx/post
, но по-прежнему нужна ссылка на каждую страницу. Тогда давайте посмотрим, используяvue.prototype
Насколько это удобно? Во-первых, вы должныvue
входной файл (vue-cli
Для сгенерированного проекта по умолчанию/src/main.js
) и выполните следующие настройкиimport port from './xxxx/xxxx/post' vue.prototype.$post = post
Таким образом, мы можем иметь все
vue
Используется в компонентах (страницах)this.post()
метод, какvue
как собственный сынСовет: повесьте метод на
prototype
При подъеме лучше добавить$
префикс, чтобы избежать конфликтов с другими переменнымиеще раз: не устанавливайте слишком много методов для
prototype
, монтировать только некоторые очень часто используемые -
Данные, на которые необходимо ответить, должны быть установлены первыми при получении данных интерфейса.
Часто ли вы сталкивались с такой ситуацией?При зацикливании списка нам нужно присвоить элементу списка атрибут, управляющий отображением, например, можно ли его удалить, был ли он выбран и т. Интерфейс обычно не возвращает это поле, потому что оно принадлежит чисто внешнему отображению и не имеет ничего общего с бэк-эндом.Например, данные, выдаваемые бэкэндом, выглядят следующим образом
[ {name: 'abc', age: 18}, {name: 'def', age: 20}, {name: 'ghi', age: 22}, ]
Предположим, что приведенные выше данные представляют собой список студентов.
Затем нам нужно отобразить список и отобразить кнопку проверки после каждого элемента.Если пользователь ставит галочку, кнопка становится зеленой, а кнопка по умолчанию серой.На данный момент в приведенной выше таблице представлены данные, которые не соответствуют этому условию отображения. , и если мы добавим эти данные, когда пользователь поставит галочку, обычная практика не сможет ответить вовремя.
Если мы сначала добавим галочку к каждому элементу массива при получении данных, мы сможем решить эту проблему.Мы предполагаем, что данные, которые мы получаем,
res.list
res.list.map(item => { item.isTicked = false })
Основанием для этого является
vue
Не может реагировать на несуществующие свойства, поэтому при получении данных мы сначала добавляем нужные свойства, а затем присваиваем ихdata
, такdata
При получении данных этот атрибут уже существует, поэтому он ответит. Конечно, есть и другие способы сделать это. Но для обсессивно-компульсивного расстройства я все же предпочитаю этот подход. -
Инкапсулировать на глобальной основе
promise
Метод асинхронного запросаПрочитав исходный код многих проектов, я обнаружил, что большая часть асинхронных запросов используется напрямую.
axios
такие методы, какaxios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
Если есть перекрестный домен или нужно установить
http
Во-первых, необходимо добавить больше конфигураций, и эти конфигурации в основном одинаковы для одного и того же проекта, единственная разницаurl
В этом случае с параметрами, почему бы мне не инкапсулировать это как метод?function post (url,param) { return axios({ method: 'post', url: url, data: param ... axios 的其他配置 }) }
Совет: оказалось, что я использовал дополнительный слой обещания, чтобы обернуть его, что слишком много для простых нужд.Я чувствую, что пользователи Nuggets
@日月为易。
указатьВ сочетании с первым пунктом мы можем произвольно
vue
Пример использования вот такlet param = { firstName: 'Fred', lastName: 'Flintstone' } this.post('/user/12345',param) .then(...) .catch(...)
Он намного проще оригинала? если ваш проект поддерживает
async
await
, вы также можете использоватьlet param = { firstName: 'Fred', lastName: 'Flintstone' } let res = await this.post('/user/12345',param) console.log(res) // res 就是异步返回的数据
tip:
await
Ключевые слова должны быть в被 async 修饰的函数里面使用
-
Если вы чувствуете, что иногда вам действительно нужно разделить значение между родительским и дочерним компонентами, лучше попробовать передать ссылочный тип в прошлом.
vue
Существует множество способов передачи значений между родительским и дочерним компонентамиjavascript
Функция ссылочного типа также достигает другой цели передачи по значению.Предположим, есть такое требование, родительский компонент должен передать 3 значения дочернему компоненту, а затем после изменения в дочернем компоненте ему нужно сразу ответить родительскому компоненту.
this.$emit
Событие генерируется, а затем родительский компонент прослушивает соответствующее событие.Однако хорошо иметь дело с одним или двумя данными.Если данных слишком много, это будет утомительно. С тем же успехом мы могли бы обернуть передаваемые данные в объект/массив, а затем передать их дочернему компоненту.<subComponent :subData="subData"></subComponent>
data () { return { subData: { filed1: 'field1', filed2: 'field2', filed3: 'field3', filed4: 'field4', filed5: 'field5', } } }
Таким образом мы вносим изменения в дочерний компонент
subData
содержание, родительский компонент может ответить напрямую без необходимостиthis.$emit
илиvuex
И если есть другие одноуровневые компоненты, если они также привязаны к этомуsubData
, то в родственном компонентеsubData
так же своевременно отвечайтеСовет: во-первых, я лично считаю, что делать это немного не по спецификации.Если у вас не так много данных, просто послушно используйте их.
this.$emit
Ну, во-вторых, эти данные нужно строить при определенных условиях, что применимо далеко не во всех случаях. -
Параметры асинхронного запроса находятся в
data
Он хорошо сконструирован и завернут в объект, что будет намного удобнеесделали подобное
ERP
Студенты этого типа системы наверняка сталкивались с такой сценой, списком, с N условиями фильтра, в этот раз мы обычно связываем так<input type="text" v-model="field1"> <input type="text" v-model="field2"> <input type="text" v-model="field3"> .... <input type="text" v-model="fieldn">
data () { return { field1: 'value1', field2: 'value2', field3: 'value3', ... fieldn:'valuen' } }
Затем при отправке данных следующим образом:
var param = { backend_field1: this.field1, backend_field2: this.field2, backend_field3: this.field3, ... backend_fieldn: this.fieldn } this.post(url,param)
Как видите, каждый раз, когда вы отправляете интерфейс, вы должны создавать параметры, которые легко пропустить Мы могли бы также сделать это: сначала перейти к документу интерфейса, чтобы увидеть имена полей, требуемые бэкендом, а затем
<input type="text" v-model="queryParam.backend_field1"> <input type="text" v-model="queryParam.backend_field2"> <input type="text" v-model="queryParam.backend_field3"> .... <input type="text" v-model="queryParam.backend_fieldn"> ``` ```javascript data () { return { queryParam:{ backend_field1: 'value1' backend_field2: 'value2' backend_field3: 'value3' ... backend_fieldn: 'valuen' } } } ``` 然后提交数据的时候这样: ```javascript this.post(url,this.queryParam) ``` 是的,这样做也是有局限性的,比如你一个数据在 2 个地方共用,比如前端组件绑定的是一个数组,你需要提交给后端的是 2 个字符串(例:`element ui` 的时间控件),不过部分特殊问题稍微处理一下,也比重新构建一个参数简单不是吗?
-
data
Когда в нем много данных, добавляйте примечание к каждому из них, что сделает его понятным, когда вы будете оглядываться назад.Продолжая немного,
data
Когда в нем много данных, может быть очень понятно, когда вы его пишете.Ведь это то, что вы написали сами, но через десять дней с половиной месяцев, или другие смотрят на ваш код, поверьте, будь то это вы сами, Будь то кто-то другой, запутался (кроме тех, чья память выходит за рамки обычных людей), так что мы могли бы также добавить примечание к каждому даннымdata () { return { field1: 'value1', // 控制xxx显示 field2: 'value2', // 页面加载状态 field3: [], // 用户列表 ... fieldn: 'valuen' // XXXXXXXX } }
-
Для сложного логического контента попробуйте разбить его на компоненты.
Предположим, у нас есть такой сценарий:
<div> <div>姓名:{{user1.name}}</div> <div>性别:{{user1.sex}}</div> <div>年龄:{{user1.age}}</div> ...此处省略999个字段... <div>他隔壁邻居的阿姨家小狗的名字:{{user1.petName}}</div> </div> <-- 当然,显示中我们不会傻到不用 v-for,我们假设这种情况无法用v-for --> <div> <div>姓名:{{user2.name}}</div> <div>性别:{{user2.sex}}</div> <div>年龄:{{user2.age}}</div> ...此处省略999个字段... <div>他隔壁邻居的阿姨家小狗的名字:{{user2.petName}}</div> </div>
В этом случае мы могли бы также извлечь код [пользователя] в компонент: Предположим, следующий код в
comUserInfo.vue
<template> <div> <div>姓名:{{user.name}}</div> <div>性别:{{user.sex}}</div> <div>年龄:{{user.age}}</div> ...此处省略999个字段... <div>他隔壁邻居的阿姨家小狗的名字:{{user.petName}}</div> </div> </template> <script > export default { props:{ user:{ type:Object, default: () => {} } } } </script>
Затем исходную страницу можно изменить на эту (исключая компоненты импорта и регистрации, предполагая, что зарегистрированное имя
comUserInfo
):<comUserInfo :user="user1"/> <comUserInfo :user="user2"/>
Это намного понятнее? Вы можете догадаться, не глядя на комментарии.Это два модуля с информацией о пользователях.Еще одним преимуществом этого является то, что при возникновении ошибки вам будет легче найти неправильное местоположение.
-
Если вы меняете только одно значение родительского компонента в дочернем компоненте, попробуйте
$emit('input')
, изменится напрямуюv-model
Наша обычная связь между родительским и дочерним компонентами осуществляется через родительский компонент.
props
Передайте его дочернему компоненту, дочерний компонент передаетthis.$emit('eventName',value)
Уведомить родительский компонент о привязке@eventName
вышеуказанный метод для выполнения соответствующей обработки. Но здесь есть исключение,vue
По умолчанию он будет прослушивать компонентinput
событие и присвоить значение, переданное от подкомпонента к текущей привязке кv-model
значение наОбычное использование — родительский компонент
<template> <subComponent :data="param" @dataChange="dataChangeHandler"></subComponent> </template> <script > export default { data () { return { param:'xxxxxx' } }, methods:{ dataChangeHandler (newParam) { this.param = newParam } } } </script>
Обычное использование — дочерние компоненты
<script > export default { methods:{ updateData (newParam) { this.$emit('dataChange',newParam) } } } </script>
использовать значение по умолчанию
input
событие - родительский компонент<template> <subComponent v-model="param"></subComponent> </template>
использовать значение по умолчанию
input
События — дочерние компоненты<script > export default { methods:{ updateData (newParam) { this.$emit('input',newParam) } } } </script>
Таким образом, мы можем сохранить код обработки места в родительском компоненте,
vue
автоматически обработает это для вассовет: этот метод подходит только для изменения одного значения, а дочернему компоненту достаточно просто передать значение родительскому компоненту, и никаких других дополнительных операций (таких как обновление списка) не требуется.
добавить один
this.$emit('update:fidldName',value)
Метод (благодаря пользователям Nuggets@日月为易。
указал)Конкретное использование заключается в следующем:родительский компонент
<subComponent field1.sync="param1" field2.sync="param2"></subComponent>
Подсборка
<script > export default { methods:{ updateData1 (newValue) { this.$emit('update:field1',newValue) }, updateData2 (newValue) { this.$emit('update:field2',newValue) } } } </script>
Этот метод лично считаю более подходящим для обновления данных, которые не могут быть привязаны к
v-model
В случае, если данные для передачи в обоих направлениях больше 1 (1 тоже можно использовать, но лично я рекомендуюinput
кстати, это зависит от личных предпочтений), но не во многих случаях. -
conponents
помещатьVue options
вершинаЯ не знаю, есть ли у вас такой опыт: импорт компонентов, а затем их использование на странице, ок, сообщается об ошибке, почему? Забыли зарегистрировать компоненты, почему вы часто забываете регистрировать компоненты? потому что нормальный
vue
Структура экземпляра выглядит следующим образом:import xxx form 'xxx/xxx' export default { name: 'component-name', data () { return { // ...根据业务逻辑的复杂程度,这里省略若干行 } }, computed: { // ...根据业务逻辑的复杂程度,这里省略若干行 }, created () { // ...根据业务逻辑的复杂程度,这里省略若干行 }, mounted () { // ...根据业务逻辑的复杂程度,这里省略若干行 }, methods () { // ...根据业务逻辑的复杂程度,这里省略若干行 }, }
Я не знаю, нормально ли это для всех
components
В любом случае, где должен быть размещен атрибут, я помещал его внизу, и в результате часто совершаются вышеуказанные ошибки.позже я положил
components
настроиться на первуюimport xxx form 'xxx/xxx' export default { components: { xxx }, // 省略其他代码 }
С этого момента моей маме больше не нужно беспокоиться о том, что я забуду зарегистрировать компонент.Импорт и регистрация находятся в одном месте, и это трудно забыть.
-
В большинстве случаев в жизненном цикле не должно быть слишком много строк кода, которые можно инкапсулировать в методы и затем вызывать
Я видел много кода, в том числе свой собственный, и написал одну-две сотни строк кода в жизненном цикле, например: когда страница загружается, все вещи, которые должны быть сделаны, написаны на
created
Внутри весь код плохо читается, и вы понятия не имеете, что делали, когда загружалась страница, В настоящее время мы могли бы также инкапсулировать эту логику в методы, а затем вызывать их непосредственно в жизненном цикле:created () { // 获取用户信息 this.getUserInfo() // 获取系统信息 this.getSystemInfo() // 获取配置 this.getConfigInfo() }, methods:{ // 获取用户信息 getUserInfo () {...}, // 获取系统信息 getSystemInfo () {...}, // 获取配置 getConfigInfo () {...}, }
Позволяет ли это легко увидеть с первого взгляда, что вы делаете, когда страница загружается?
совет: Это следует рассматривать как общепринятую норму, но я думаю, что я больше читал и пишу так. Кроме того, я делал то же самое, когда был новичком, поэтому я это записал. Надеюсь, новые ученики смогут избежать этого проблема.
-
бесполезный
watch
, если вы думаете, что вам нужно использовать его во многих местахwatch
, то в девяти случаях из десяти вы правыvue
изAPI
недостаточно знаюvue
Это сама по себе структура, управляемая данными. Изменения в данных могут передаваться обратно в представление в режиме реального времени. Если вы хотите контролировать попытку на основе данных, сотрудничайте при нормальных обстоятельствах.computed
Взяв его, можно решить большинство проблем, а за изменениями в представлении мы вообще можем следитьinput
change
и другие события для достижения цели мониторинга в реальном времени, Так что очень мало нужно использоватьwatch
По крайней мере, я не использовал его в дюжине или около того проектов, в которых я был недавно.watch
Конечно, не тоwatch
однозначно бесполезен,vue
Должны быть его причины для предоставления этого API, и есть некоторые потребности, которые действительно нужно использовать, но я думаю, что его следует использовать редко.Если вы считаете, что вам нужно использовать его везде, тогда я думаюВ девяти случаях из десятитебе стоит познакомитьсяcomputed
а такжеvue
другойapi
охватывать
наконец
Адрес этой статьи на githubНе стесняйтесьstar,follow, и непроизвольноеissue
Кроме того,githubЕсть несколько других руководств и компонентов о внешнем интерфейсе на Заинтересованная детская обувь может посмотреть, ваша поддержка-моя самая большая мотивация.