1. Разделение параметров маршрутизации
Как правило, используя параметры маршрутизации внутри компонента, большинство людей делают следующее.
export default { methods: { getParamsId() { return this.$route.params.id } } }
Использование $route
в компоненте приводит к высокой степени связанности с соответствующими маршрутами, что ограничивает гибкость компонента, ограничивая его определенными URL-адресами.
Правильный подход - отделить его через props
const router = new VueRouter({ routes: [{ path: /user/:id , component: User, props: true }] })
После установки свойства props маршрута в true параметр params может быть получен внутри компонента через props.
export default { props: [ id ], methods: { getParamsId() { return this.id } } }
Вы также можете возвращать реквизиты через режим функций.
const router = new VueRouter({ routes: [{ path: /user/:id , component: User, props: (route) => ({ id: route.query.id }) }] })
2. Функциональный компонент
Функциональный компонент не имеет состояния, он не может быть создан и не имеет жизненного цикла или методов. Создавать функциональные компоненты также просто, достаточно добавить в шаблон функциональные объявления. Как правило, он подходит для компонентов, которые зависят только от изменений внешних данных, а производительность рендеринга повышается благодаря его небольшому весу.
Все, что нужно компоненту, передается через параметр контекста. Это объект контекста, см. документацию по конкретным свойствам. Здесь props — это объект, который содержит все связанные свойства.
<template functional> <div class="list"> <div class="item" v-for="item in props.list" :key="item.id" @click="props.itemClick(item)"> <p>{{item.title}}</p> <p>{{item.content}}</p> </div> </div> </template>
Родительский компонент использует
<template> <div> <List :list="list" :itemClick="item => (currentItem = item)" /> </div> </template> import List from @/components/List.vue export default { components: { List }, data() { return { list: [{ title: title , content: content }], currentItem: } } }
3. Область действия стиля
Обычно в процессе разработки изменяются стили сторонних компонентов, но из-за изоляции стилей атрибута области действия может потребоваться удалить область действия или запустить другой стиль. Эти методы имеют побочные эффекты (загрязнение стиля компонента, отсутствие элегантности), и проникновение стиля используется в препроцессоре css для достижения эффекта.
Мы можем использовать >>>
или /deep/
для решения этой проблемы:
<style scoped> Outer layer >>> .el-checkbox { display: block; font-size: 26px; .el-checkbox__label { font-size: 16px; } } </style> <style scoped> /deep/ .el-checkbox { display: block; font-size: 26px; .el-checkbox__label { font-size: 16px; } } </style>
4. Расширенное использование часов
watch запускается при изменении свойства слушателя, иногда мы хотим, чтобы watch выполнялся сразу после создания компонента.
Способ, который может прийти в голову, — это вызвать его один раз в жизненном цикле создания, но это не очень элегантный способ написать его, поэтому, возможно, мы могли бы использовать что-то вроде этого.
export default { data() { return { name: Joe } }, watch: { name: { handler: sayName , immediate: true } }, methods: { sayName() { console.log(this.name) } } }
Глубокое слушание
При прослушивании объекта часы не могут срабатывать при изменении свойств внутри объекта, поэтому мы можем установить для него глубокое прослушивание
export default { data: { studen: { name: Joe , skill: { run: { speed: fast } } } }, watch: { studen: { handler: sayName , deep: true } }, methods: { sayName() { console.log(this.studen) } } }
Запуск прослушивателя для выполнения нескольких методов
Используя массивы, вы можете установить несколько форм, включая строки, функции, объекты.
export default { data: { name: Joe }, watch: { name: [ sayName1 , function(newVal, oldVal) { this.sayName2() }, { handler: sayName3 , immaediate: true } ] }, methods: { sayName1() { console.log( sayName1==> , this.name) }, sayName2() { console.log( sayName2==> , this.name) }, sayName3() { console.log( sayName3==> , this.name) } } }
5. watch прослушивает несколько переменных
сами часы не могут прослушивать несколько переменных. Однако мы можем «прослушивать несколько переменных», возвращая объект с вычисленными свойствами, а затем прослушивая этот объект.
export default { data() { return { msg1: apple , msg2: banana } }, compouted: { msgObj() { const { msg1, msg2 } = this return { msg1, msg2 } } }, watch: { msgObj: { handler(newVal, oldVal) { if (newVal.msg1 != oldVal.msg1) { console.log( msg1 is change ) } if (newVal.msg2 != oldVal.msg2) { console.log( msg2 is change ) } }, deep: true } } }
6. Параметр события $event
$event
— это специальная переменная объекта события, которая в некоторых сценариях дает нам больше доступных параметров для реализации сложных функций.
Собственные события: ведет себя так же, как объект события по умолчанию в собственных событиях.
<template> <div> <input type="text" @input="inputHandler( hello , $event)" /> </div> </template> export default { methods: { inputHandler(msg, e) { console.log(e.target.value) } } }
Пользовательские события: представленные в пользовательских событиях как получение значения, выброшенного из дочернего компонента.
export default { methods: { customEvent() { this.$emit( custom-event , some value ) } } } <template> <div> <my-item v-for="(item, index) in list" @custom-event="customEvent(index, $event)"> </my-list> </div> </template> export default { methods: { customEvent(index, e) { console.log(e) // some value } } }
7. Программные прослушиватели событий
Например, определение таймера при монтировании страницы требует сброса таймера при уничтожении страницы. Это не похоже на проблему. Но при ближайшем рассмотрении единственная цель this.timer — получить номер таймера в beforeDestroy, и в остальном он бесполезен.
export default { mounted() { this.timer = setInterval(() => { console.log(Date.now()) }, 1000) }, beforeDestroy() { clearInterval(this.timer) } }
Лучше, если это возможно, иметь доступ только к хукам жизненного цикла. Это не серьезная проблема, но ее можно рассматривать как беспорядок.
Мы можем решить эту проблему, прослушивая уничтожение жизненного цикла страницы с помощью $on
или $once
:
export default { mounted() { this.creatInterval( hello ) this.creatInterval( world ) }, creatInterval(msg) { let timer = setInterval(() => { console.log(msg) }, 1000) this.$once( hook:beforeDestroy , function() { clearInterval(timer) }) } }
С помощью этого метода, даже если мы создадим несколько таймеров одновременно, это не повлияет на эффект. Это связано с тем, что они будут программно очищаться автономно после уничтожения страницы.
8. Прослушивание жизненного цикла компонентов
Обычно мы используем $emit для прослушивания жизненного цикла компонента, а родительский компонент получает события для уведомления.
Подкомпоненты
export default { mounted() { this.$emit( listenMounted ) } }
Родительский компонент
<template> <div> <List @listenMounted="listenMounted" /> </div> </template>
На самом деле, есть простой способ использовать @hook для прослушивания жизненного цикла компонента без внесения каких-либо изменений внутри компонента. Точно так же созданные, обновленные и т. д. также могут использовать этот метод.
<template> <List @hook:mounted="listenMounted" /> </template>