[Технический жир] Vue3.x Обучение с нуля — Компоненты второго сезона

JavaScript Vue.js

Прежде чем изучать это видео, вам необходимо изучить "Vue3.x с нуля - Эпизод 1 - Базовая грамматика". Второй сезон (это руководство) в основном объясняет некоторые знания о компонентах в Vue3, в том числе о том, что такое глобальные компоненты, локальные компоненты, как повторно использовать компоненты, перенос значений между компонентами, единый поток данных, свойства Non-Props, связь между родительскими и дочерними компонентами. , Двусторонняя привязка компонентов, использование слотов в компонентах, динамические компоненты и асинхронные компоненты также включены.

Но вам все равно нужно помнить, что вам все равно нужно знать основы, прежде чем проходить этот курс.

«Vue3.x Обучение с нуля — базовая грамматика первого сезона»

00. Список видео 2 сезона

01. [Компонент] Конфликт и замечания глобальных компонентов

02. [Компонент] Локальные компоненты в Vue3

03. [Компонент] Статическая и динамическая передача значений родительского и дочернего компонентов

03. [Компонент] Статическая и динамическая передача значений родительского и дочернего компонентов

04. [Компонент] Операция проверки, когда компоненты передают значения

05. [Компонент] Важный механизм в компоненте — единый поток данных

06. [Компонент] Советы по использованию не реквизита

07 [Компонент] Связь через события в компонентах

08. [Компонент] Использование слотов в компонентах Слот -1

09. [Компонент] Использование слотов в компонентах Слот-2

10. [Компонент] Сокращенное название слота и слот с ограниченной областью действия

11. [Компоненты] Динамические компоненты и сохранение состояния

12. [Компонент] Асинхронные компоненты и объяснение промисов

13. [Компонент] предоставляет и внедряет многоуровневые компоненты для передачи значений.

01. [Компонент] Глобальное определение компонента и объяснение повторного использования

Диаграмма для понимания концепции компонентов

Давайте сначала посмотрим на официальное изображение, предоставленное Vue 3. Благодаря изображению мы можем ясно понять некоторые подсказки о компонентах в Vue.

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39d61066fa654cd7b4202fdfb680a367~tplv-k3u1fbpfcp-zoom-1.image

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

Обобщенно следующим образом:

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

Объяснение корневых компонентов в Vue3

После изучения теории открываемVSCodeРедактор кода, напишите базовую структуру Vue3 (поскольку это первая часть видео этого сезона, поэтому я дам вам базовый код).

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app"></div>
</body>
</html>

С помощью этого кода напишите соответствующий код Vue. использоватьcreateApp( )Создайте экземпляр Vue, затем используйтеmount( )способ крепления кDOMна узле.

<script>
    const app=Vue.createApp({ })
    const vm=app.mount("#app")
</script>

В настоящее времяVue.createAppФактически создается экземпляр Vue, эквивалентный только что упомянутому первому.根组件. Вы можете определить определенные стили и методы корневого компонента в форме свойств объекта (фактически методы, принимающие параметры, реализованные объектом). Например, определите шаблон на корневом компоненте, а затем выведите его на страницу.JSPang.comэтот URL.

const app=Vue.createApp({
    template:`<h2>JSPang.com</h2>`
})

После написания зайдите в браузер на превью, его можно увидеть на страницеJSPang.comэтот URL.

На данный момент мы надеемся, что в компоненте есть еще одна строка слов, например добавление技术胖на китайском языке. Код можно написать так.


const app=Vue.createApp({
    template:`
        <h2>JSPang.com</h2>
        <div>技术胖的博客</div>
    `
})

Определение глобальных компонентов

Теперь на странице две части,<h2>JSPang.com</h2>а также<div>技术胖的博客</div>. Затем вы можете разделить эти две части на два глобальных компонента слова. код показывает, как показано ниже:

app.component('website',{
    template:` <h2>JSPang.com</h2>`
})
app.component('describe',{
    template:` <h2>技术胖的博客</h2>`
})

После определения компонента его можно использовать непосредственно в корневом компоненте.

const app=Vue.createApp({
    template:`
        <website />
        <describe />
    `
})

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

Объяснение возможности повторного использования компонентов

Теперь нужно определить новый计数组件-count, каждый раз, когда нажимается кнопка, в компонентеcountПеременная автоматически увеличивается на 1.

app.component('count',{
    data(){
        return{
            count:0
        }
    },
    
    template:`<div>{{count}}<button @click="count++">增加1</button></div>`
})

После написания компонента его можно повторно использовать в корневом компоненте, здесь можно добавить несколько<count />Компоненты, скажем, три.

const app=Vue.createApp({
    template:`
        <website />
        <describe />
        <count/>
				<count/>
				<count/>
    `
})

Затем просмотрите его в своем браузере, и вы найдете<count />Они не мешают друг другу, благодаря этой особенности компоненты Vue можно использовать повторно.

Недостатки глобальных компонентов

Глобальные компоненты действительно очень удобно писать.В то время, когда вы определяете глобальные компоненты, они будут занимать системные ресурсы. Он всегда рядом, и вы можете использовать этот глобальный компонент где угодно. Это неизбежно скажется на производительности.Например, в реальном проекте будут тысячи компонентов.Эти компоненты написаны разными людьми.Если все они будут глобальными компонентами, то скорость открытия приложения должна быть крайне низкой, а беглость будет также быть затронуты.

Резюме глобальных компонентов:Пока он определен, его можно использовать везде, производительность невысокая, но он прост в использовании.

Итак, подведем итоги: В этом уроке мы узнали, какие компоненты есть в Vue, как определить глобальные компоненты, объяснили повторное использование компонентов, а затем рассказали о недостатках компонентов. Здесь необходимо подчеркнуть, что компоненты очень важны для изучения Vue, поэтому я надеюсь, что друзья смогут обратить внимание на изучение и практику этой части контента.

02. [Компонент] Локальные компоненты в Vue3

Глобальному компоненту соответствует локальный компонент.Вы можете рассматривать локальный компонент как переменную, а затем зарегистрировать компонент, где он используется, прежде чем его можно будет использовать. Самым большим преимуществом локальных компонентов является то, что они потребляют системные ресурсы только тогда, когда они используются, в отличие от глобальных компонентов, которые существуют всегда. Возможно, сейчас вы не очень хорошо понимаете этот отрывок. Давайте воспользуемся кодом, чтобы объяснить, что такое локальный компонент.

готовый к использованию файл

ОткрытьVSCode, создайте новый файлDemo2.html, копировать напрямуюDemo1.htmlСодержание. Удалите бесполезный контент.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: `<h2>JSPang.com</h2>`
    })
    const vm = app.mount("#app")
</script>
</html>

В это время вы можете открыть браузер, чтобы увидеть, может ли отображаться нормальное содержимое. Если может нормально отображаться, значит все нормально. Далее вы можете написать локальный компонент.

Создание локальных компонентов

Регистрация местных компонентов, на самом деле, вы можете понять, что достижение состоит в том, чтобы объявить переменную, эта переменная является объектом, поэтому мы используем фигурные скобки (фигурные скобки) в внешнем слое, а затем используютVue.CreateApp( )Передаваемые параметры одинаковы.

const counter = {
    data() {
        return {
            count: 0
        }
    },
    template: `<div>{{count}}<button @click="count++">增加1</button></div>`
}

После регистрации компонента мы не можем использовать его напрямую, и если мы используем его напрямую, будет сообщено об ошибке. Что делать теперь, чтобыvue.CreateApp( )способ зарегистрироваться.

Сборка и тестирование локальных компонентов

Метод регистрации локальных компонентов очень прост, достаточно использоватьcomponentsимущество, чтобы объявить его.

const app = Vue.createApp({
    components: { counter },
    template: `
        <h2>JSPang.com</h2>
        <counter />
    `
})

Но это всего лишь сокращенный метод, правильный способ его написания должен быть components: { counter:counter },, по сути, это дать компоненту имя, можно даже назвать егоjspang.

const app = Vue.createApp({
        components: { jspang: counter },
        template: `
        <h2>JSPang.com</h2>
        <jspang />

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

Есть некоторые неписаные неписаные правила приготовления местных компонентов, которые представлены ниже.

Используйте большой верблюжий кейс для местных компонентов

Иногда имена наших компонентов будут длиннее, например, записьxieDaJiaoкомпоненты.

const xieDaJiao = {
        template: `<h2>谢大脚</h2>`
    }

Имя переменной теперь имеет прописные и строчные буквы, в настоящее время при сборке тестового компонента следует использовать эту форму (с-вырезать слова).

const app = Vue.createApp({
    components: { 
        jspang: counter, 
        'xie-da-jiao': xieDaJiao 
    },
    template: `
    <h2>JSPang.com</h2>
    <xie-da-jiao />
    <jspang />
    
`

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

const XieDaJiao = {
        template: `<h2>谢大脚</h2>`
    }

Вот все коды этого урока, которые помогут вам лучше учиться.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const Counter = {
        data() {
            return {
                count: 0
            }
        },
        template: `<div>{{count}}<button @click="count++">增加1</button></div>`
    }
    const XieDaJiao = {
        template: `<h2>谢大脚</h2>`
    }
    const app = Vue.createApp({
        components: {
            jspang: Counter,
            'xie-da-jiao': XieDaJiao
        },
        template: `
            <h2>JSPang.com</h2>
            <xie-da-jiao />
            <jspang />
            
        `
    })
    const vm = app.mount("#app")

</script>

</html>

03. [Компонент] Статическая и динамическая передача значений родительского и дочернего компонентов

Это первый урок после праздника Весны в 2021 году (пятый день Лунного Нового года).Я был со своей семьей много лет назад и во время китайского Нового года, поэтому урок не был записан. Если вы давно его не изучали, то можете немного просмотреть код из предыдущего урока и выучить заново. На этом уроке предстоит изучить передачу значений родительских и дочерних компонентов, включая передачу статических и динамических значений.

Подготовьте базовый код

Для того, чтобы лучше продемонстрировать видео, вам нужно создать новый файл, который называется здесьDemo3.html, затем скопируйтеDemo2.htmlкод, удалите код из предыдущего урока, оставив основную структуру кода.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo03</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>
<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template:`<h2>JSPang.com</h2>`
    })
   
    const vm= app.mount("#app")
</script>
</html>

Следует отметить, что официальный источник здесь не цитируется, аbootcdnисточник. Причина уже упоминалась в предыдущих двух уроках, поэтому я не буду повторяться здесь. С самым простым кодом давайте объявим глобальный компонентSon.

app.component('Son',{
    template:`<div>Son div </div>`
})

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

const app = Vue.createApp({
    template:`
        <h2>JSPang.com</h2>
        <Son />
    `
})

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

Передача значений из родительского компонента в дочерний компонент (статическое значение передачи)

в подкомпонентеSon divЭто жестко запрограммировано.Если вы хотите динамически передавать от родительского компонента, вы можете использовать метод атрибута, а затем дочерний компонент использует реквизит для его получения.

Например, там, где мы вызываем дочерний компонент, через атрибутnameпередать技小胖текст в.

const app = Vue.createApp({
    template:`
        <h2>JSPang.com</h2>
        <Son name="技小胖" />
    `
})

использовать после родовpropsПримите в дочернем компоненте, затем используйте выражение интерполяции (двойные фигурные скобки{{name}}) распечатываются.

app.component('Son',{
    props:['name'],
    template:`<div>{{name}} div </div>`
})

Таким образом параметры принимаются и отображаются.

Динамические данные как параметр

Параметры, передаваемые приведенным выше кодом, жестко закодированы, и бизнес-логика не может быть записана, что мы часто называем статическими параметрами. Если вы хотите сделать код более гибким, вы можете использовать здесь динамическую передачу параметров. Динамическая передача параметров сначала помещает переданные параметры в Vue.элемент данных, то есть,dataв свойствах.

Например, вdataОбъявите свойство name в , и назначьте его как技小胖. В это время необходимоtemplateПривяжите это свойство имени в . Таким образом, ваши значения не статичны, а динамичны.

const app = Vue.createApp({
    data(){
        return {
            name: "技小胖"
        }
    },
    template:`
        <h2>JSPang.com</h2>
        <Son v-bind:name="name" />
    `
})

Конечноv-bind:nameЕго также можно записать в сокращенной форме как:name. Переписанный код выглядит следующим образом:

template:`
    <h2>JSPang.com</h2>
    <Son :name="name" />
`

Также есть небольшая ямка для статических параметров, которую нужно пояснить, то есть статически можно передавать только строковый тип.String, а динамический параметр может быть нескольких типов, даже функция (метод).

Пример передачи параметров будет подробно объяснен ниже, сначала рассмотрим пример передачи чисел.

Например, мы теперь меняем обратно статические параметры, а передаваемое содержимое — это число123, но в шаблоне используйтеtypeofПри просмотре свойств это по-прежнему строка.

Переход к статической передаче параметров, параметр123.

template:`
    <h2>JSPang.com</h2>
    <Son name="123" />
`

используется в подкомпонентахtypeofГлядя на тип, вы обнаружите, что он по-прежнемуstringТипы.

app.component('Son',{
    props:['name'],
    template:`<div>{{ typeof name}} div </div>`
})

Однако, если он изменен на динамическую передачу параметров, он становится числовым типом.

const app = Vue.createApp({
    data(){
        return {
            name:123
        }
    },
    template:`
        <h2>JSPang.com</h2>
        <Son :name="name" />
    `
})

Использование, когда параметр является функцией

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

Требование такое, мы написалиXiaoJieJieГлобальный подкомпонент , а то при клике дама сначала скажет пожалуйста оплатите, а потом передаем функцию отдать деньги.

записывать小姐姐подкомпоненты:

app.component('XiaoJieJie',{
    props:['pay'],
    methods:{
        handleClick(){
            alert('请付钱....')
            this.pay()  // 付多少钱,是顾客说的算的,所以调用时才能确定
        }
    },
    template:`<div @click="this.handleClick"> 和小姐姐,打招呼! </div>`
})

Когда вызывается родительский компонент,payэто функция, определенная в данных, а затем вызываемая с динамическими параметрами.

const app = Vue.createApp({
    data(){
        return {
            name:123,
            pay:()=>{
                alert('给你500元')
            }
        }
    },
    template:`
        <h2>JSPang.com</h2>
        <Son :name="name" />
        <xiao-jie-jie :pay="pay"/>
    `
}

В следующем видео мы продолжим объяснять написание некоторых методов проверки, когда компоненты передают значения. Чтобы посмотреть это видео, подпишитесь на общедоступную учетную запись WeChat.技术胖.

04. [Компонент] Операция проверки, когда компоненты передают значения

Теперь вы можете легко передавать значения компонентам, что очень удобно и бесплатно для использования.В реальной разработке эти переданные параметры также, вероятно, будут получены через пользовательский ввод, и необходима необходимая проверка интерфейса. Однако в компоненте также требуется самая базовая проверка. В этом уроке мы узнаем о проверке передачи значения компонента в Vue3.

Подготовьте основные документы

Скопируйте предыдущий урокDemo3.htmlкод, чтобыDemo4.htmlи удалитьXiaoJieJieПользовательские компоненты и места для вызова. Чтобы облегчить ваше обучение, вот код для вас, вы можете скопировать и использовать его напрямую.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo04</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        data() {
            return {
                name: 123,
                pay: () => {
                    alert('给你500元')
                }
            }
        },

        template: `
            <h2>JSPang.com</h2>
            <Son :name="name" />
        `
    })

   app.component('Son',{
		    props:['name'],
		    template:`<div>{{ typeof name}} div </div>`
		})
    
    const vm = app.mount("#app")
</script>

</html>

Если вы следите за видеооперацией, вы также можете прямо вDemo3.htmlВ файл вносятся изменения, это нужно только для лекций, поэтому пишется другой файл.

проверка типа

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

app.component('Son', {
        props: {
            name: String
        },
        template: `<div>{{name}} div </div>`
    })

В это время код имеет функцию проверки, откройте控制台ConsoleВы можете увидеть подсказку. Здесь следует отметить, что такого рода подсказка не сообщит об ошибке и не заблокирует программу, а будет выдана только в консоли.warn警告信息.

В это время в элементе данных123, когда он преобразуется в строку, программа больше не будет сообщать об ошибке. Типы проверки, поддерживаемые Vue, включают: строку, логическое значение, массив, объект, функцию и символ.

Требуемые настройки контрольной суммы по умолчанию

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

требуетсяОбязательно

Если вам требуется компонент для использования, вы должны передать параметры, вы можете использоватьrequiredпроверять.

app.component('Son', {
        props: {
            name: {
                type: String,
                required: true
            }
        },
        template: `<div>{{name}} div </div>`
    })

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

значение по умолчанию по умолчанию

Давайте посмотрим на написание значения по умолчанию, и напишем его в оригиналеrequiredнапрямую писатьdefaultВот и все. Например, напишите это следующим образом.

app.component('Son', {
        props: {
            name: {
                type: String,
                default: 'JSPang.com'
            }
        },
        template: `<div>{{name}} div </div>`
    })

Это означает, что при вызове компонента, если параметры не переданы, значение по умолчанию равноJSPang.com.

Точная проверка-валидатор

Если ни одна из вышеперечисленных проверок не соответствует вашим требованиям, вы также можете выполнить точную проверку. Например, теперь требуется, чтобы передаваемая строка содержалаJSPangЭти несколько символов вы можете использоватьvalidatorпроверять. это функция и принимаетvalueзначение, это значение является переданным значением.

app.component('Son', {
    props: {
        name: {
            type: String,
            validator: function (value) {
                console.log(value.search("JSPang"))
                return value.search("JSPang") != -1
            },
            default: 'JSPang.com'
        }
    },
    template: `<div>{{name}} div </div>`
})

потому что использоватьsearchЧтобы убедиться, что возвращается позиция, в которой появляется строка, и она отображается, когда не найдена.-1. Итак, здесь определено, что если нет-1Просто пройдите верификацию.

При не прохождении проверки в консоли выдается предупреждение.

Ну вот и все содержание этой статьи.Надеюсь, изучив, вы сможете узнать метод проверки, когда компоненты передают значения.

05. [Компонент] Важный механизм в компоненте — единый поток данных

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

написать счетчик

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

создать новыйDemo5.html, затем скопируйтеDemo4.html, удалите лишний и бесполезный код и оставьте только самую основную структуру кода. Вы также можете скопировать следующий код.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo05</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        data() {
            return {
                
            }
        },
        template: `
            <h2>JSPang.com</h2>
        `
    })

    const vm = app.mount("#app")
</script>

</html>

После копирования кода напишите глобальный компонент, который принимает параметрcounter, код показан ниже.

app.component('Counter', {
    props: ['counter'],
    template: `
        {{counter}}<button @click="counter+=1">增加数量</button>
    `
})

Напишите глобальные компонентыCounterПосле этого его можно использовать в родительском компоненте, т.к. счетчик передается в дочерний компонент, поэтому он должен быть в элементе данныхdataзаявил в.

const app = Vue.createApp({
    data() {
        return {
            counter: 0
        }
    },
    template: `
        <h2>JSPang.com</h2>
        <counter :counter="counter"/>
    `
})

Вроде бы все работает нормально, но при предварительном просмотре в браузере вы видите, что нажатие кнопки вообще не работает. Это результат ограничений механизма одностороннего потока данных.

Концепция однонаправленного потока данных

Что такое однонаправленный поток данных? Официальное объяснение довольно туманно.

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

Когда я впервые прочитал этот текст, я не знал, что он пытается сказать, но после изучения и проектирования концепция единого потока данных на самом деле очень проста для понимания. Можно просто сказать:Данные передаются от родительского компонента к дочернему компоненту и могут быть связаны только в одну сторону. Дочерний компонент не может напрямую изменять данные, переданные от родительского компонента.

Вот почему программа, которую мы написали выше, не может быть использована. Как изменить эту программу, чтобы сделать ее удобной для использования?Метод очень простой.Объявите переменную в элементе данных в компоненте, присвойте переменную, переданную из родительского компонента, во внутреннюю переменную, а затем вы можете изменить ее по своему желанию .

app.component('Counter', {
    props: ['counter'],
    data() {
        return {
            newCounter: this.counter
        }
    },
    template: `
        {{newCounter}}<button @click="this.newCounter+=1">增加数量</button>
    `
})

Это можно изменить. По мере прохождения программы мы лучше понимаем, что单项数据流После этого снова подведем итоги.Односторонний поток данных означает, что родительский компонент может передавать данные дочернему компоненту, но дочерний компонент не может изменять данные.

Почему существует однонаправленный механизм потока данных?

Конечной целью единого потока данных является уменьшение связанности и независимости компонентов. Например, теперь три страницы вызываются одновременно<counter/>Компоненты, без механизма единого потока данных, легко могут стать явлением, когда значение одного компонента меняется, а также меняются значения других компонентов. Пусть данные компонентов страницы связаны между собой, и нет возможности использовать их независимо.

template: `
    <h2>JSPang.com</h2>
    <counter :counter="counter"/>
    <counter :counter="counter"/>
    <counter :counter="counter"/>
`

Цель этого урока — понять, что такое концепция единого потока данных в компоненте.

06. [Компонент] Советы по использованию не реквизита

Этот класс в основном говорит оNon-propsатрибут, что этоNon-propsАтрибут собственно в том, что дочерний компонент не принимает параметры, переданные родительским компонентом, и дочерний компонент полностью копирует атрибут в свою метку, которая называетсяNon-propsАтрибуты. Я полагаю, что вы еще не можете полностью понять это предложение, это не имеет значения, мы продолжаем учиться.

Подготовка базовых страниц и подкомпонентов

показыватьNon-propsСтиль атрибута, нам нужно написать код, чтобы объяснить использование, вы можете использовать этот процесс в качестве обзора. новыйDemo6.htmlфайл, затем скопируйтеDemo5.htmlкод дляDemo5.htmlсередина. Удалите код, написанный в предыдущем уроке, и оставьте самую простую структуру.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo06</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: ` <h2>JSPang.com</h2>`
    })
    const vm = app.mount("#app")
</script>

</html>

Затем мы пишем глобальный компонент Hello, код выглядит следующим образом.

app.component('Hello', {
    template: `<h3>Hello World</h3>`
})

После написания дочернего компонента вы можете использовать его непосредственно в родительском компоненте.

const app = Vue.createApp({
    template: `
        <h2>JSPang.com</h2>
        <hello />
    `
})

Исходные свойства без реквизита

В приведенном выше коде мы не принимали никаких переданных параметров в подкомпонент, поэтому мы его вообще не писали.props, но в это время еще можно передавать значения при вызове.

const app = Vue.createApp({
    template: `
    <h2>JSPang.com</h2>
    <hello msg="jspang" />
`
})

В это время вы открываете консоль в своем браузере и просматриваетеElementsэтикетка, вы можете увидеть<h3>уже на этикеткеmsg=jspangТакое свойство, то есть родительский компонент напрямую пересаживает свойство в дочернее свойство.

<h3 msg="jspang">Hello World</h3>

Если вы хотите устранить такой вид переноса или копирования, вы можете принять это свойство в подкомпоненте, но не использовать его.

app.component('Hello', {
     props: ['msg'],
     template: `<h3>Hello World</h3>`
 })

При открытии браузераElementsПросмотр ярлыков, нет лишних атрибутов.

После понимания двух способов, что мы собираемся сказать?Non-propАтрибут, когда родительский компонент передает параметры дочернему компоненту, дочерний компонент не пишет никаких приемных методов. В это время родительский компонент полностью скопирует свойство в дочерний компонент, и дочерний компонент также может получить значение свойства.

Наиболее распространенный вариант использования — написание стилей CSS непосредственно в теге.

const app = Vue.createApp({
    template: `
        <h2>JSPang.com</h2>
        <hello style="color:red;" />
    `
})

В это время дочерний компонент получит это свойство напрямую, и шрифт станет красным.

свойство inheritAttrs

Иногда мы просто не хотим принимать параметры, и мы не хотимNon-propsАтрибуты работают, на этот раз можно использовать на дочерних компонентахinheritAttrsсвойств для решения этой проблемы.

app.component('Hello', {
    inheritAttrs: false,
    template: `<h3>Hello World</h3>`
})

В это время тег стиля больше не будет копироваться в дочерний компонент, аHello WorldТоже не краснеет.

Непрофильное решение для отказа нескольких узлов

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

app.component('Hello', {
    template: `
        <h3>Hello World</h3>
        <h3>Hello World</h3>
        <h3>Hello World</h3>
    `
})

В этом случае репликация завершится ошибкой. Можно, конечно, добавить к ним корневой узел, но есть способ решить эту проблему без добавления корневого узла. Например, теперь мы хотим сделать первый компонент в<h3>Метка копирует свойства, переданные родительским компонентом, и ее можно записать следующим образом.

pp.component('Hello', {
    template: `
    <h3 v-bind="$attrs">Hello World</h3>
    <h3>Hello World</h3>
    <h3>Hello World</h3>
`
})

Обратите внимание, что тестируемый$attrsНе один атрибут, а все атрибуты. Конечно, здесь только один атрибут, поэтому копируется только один, например, если вы пишете другой атрибут, его тоже можно скопировать.

const app = Vue.createApp({
    template: `
    <h2>JSPang.com</h2>
    <hello style="color:red;" msg="jspang" />
`
})

В этот момент вы открываете браузер и видите, что оба свойства копируются в первое.<h3>на этикетке.

<h3 msg="jspang" style="color: red;">Hello World</h3>

На это нужно обратить внимание,v-bind="$attrs"Это означает, что все свойства параметров, переданные родительским компонентом, копируются в дочерний компонент.

Если вы хотите скопировать только одно свойство, как сейчас, мы копируем только одно свойствоstyle, напишите так.

app.component('Hello', {
    template: `
        <h3 v-bind="$attrs">Hello World</h3>
        <h3 v-bind:style="$attrs.style">Hello World</h3>
        <h3>Hello World</h3>
    `
})

На этот раз второй<h3>Этикетка только копируетсяstyleАтрибуты. Конечно, вы также можете сократить, удалитьv-bind, но использовать:представлять.

Использование нереквизитных свойств в бизнес-логике

То, что я только что сказал, было использовано на этикеткеNon-propsсвойства, если вы хотите использовать в бизнес-логикеNon-propsАтрибуты также возможны. Например, использование в жизненном цикле.

app.component('Hello', {
    mounted() {
        console.log(this.$attrs.msg)
    },
    template: `
    <h3 v-bind="$attrs">Hello World</h3>
    <h3 v-bind:style="$attrs.style">Hello World</h3>
    <h3>Hello World</h3>
    `
})

Затем зайдите в консоль в браузере для просмотра, вы можете увидеть распечаткуjspangшрифт. фактическиthis.$attrsЭто общее свойство Vue, и нам нужно правильно его использовать.

07 [Компонент] Связь через события в компонентах

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

Благодаря написанию счетчиков наши цели обучения в этом разделе заключаются в следующем:

  • Дочерний компонент вызывает метод записи событий родительского компонента.
  • Как передать параметры из дочернего компонента в событие родительского компонента
  • При передаче параметров дочерним компонентам, как передатьemitsчек об оплате

Начнем наше исследование непосредственно.

Напишите встречный случай

создать новый файлDemo7.htmlфайл, затем скопируйтеDemo5.htmlфайл вDemo7.htmlсередина. модифицировать.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo07</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        data() {
            return {
                counter: 0
            }
        },
        template: `
                    <h2>JSPang.com</h2>
                    <counter :counter="counter"/>  
             `
    })
    app.component('Counter', {
        props: ['counter'],
        template: `
        {{counter}}<button @click="this.counter+=1">增加数量</button>
    `
    })

    const vm = app.mount("#app")
</script>

</html>

Приведенный выше код, когда мы нажимаем увеличить в браузере, не может увеличитьсяcounterзначение, это Vue单向数据流пределы. Но иногда мы просто хотим изменить значение, переданное из родительского компонента в дочерний компонент, что нам делать?

Дочерний компонент вызывает событие родительского компонента

В это время дочернему компоненту необходимо вызвать событие родительского компонента, тем самым изменив значение в родительском компоненте. Сначала мы пишем метод в родительском компоненте с именемhandleAddCounter. Этот метод делает одну вещь, которая не выполняется ни разу, в элементе данныхcounterплюс один.

methods: {
    handleAddCounter() {
        this.counter += 1
    }
},

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

В это время вы можете сначала子组件ШаблонtemplateНапишите одинclickмероприятие.

{{counter}}<button @click="handleClick">增加数量</button>

Дочерний компонент вызывает не метод родительского компонента, а метод дочернего компонента. Если вы хотите вызвать родительский компонентhandleAddConterметод, вы можете создать новый метод в дочернем компоненте в это времяhandleClick, затем используйте$emitВызов события ответа родительского компонентаadd. Конкретный код выглядит следующим образом.

app.component('Counter', {
    props: ['counter'],
    emits: ['add'],
    methods: {
        handleClick() {
            this.$emit('add')
        }
    },
    template: `
    {{counter}}<button @click="handleClick">增加数量</button>
`
})

В настоящее времяaddчто это такое?addЭто реагировать на события в шаблоне родительского компонента.template, добавитьaddРеагировать на события, затем реагировать на события, а затем вызывать методыhandleAdCounter.

Шаблон в родительском компоненте:

template: `
            <h2>JSPang.com</h2>
            <counter :counter="counter" @add="handleAddCounter"/>  
        `

В это время вы можете перейти в браузер, чтобы увидеть результаты, вы обнаружите, что когда вы нажимаете кнопку добавления, элемент данных вcounterзначение уже может быть увеличено. Просто предупреждение будет напечатано на консоли.

[Vue warn]: Extraneous non-emits event listeners (add) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option. 
  at <Counter counter=3 onAdd=fn<bound handleAddCounter> > 
  at <App>

предупреждение означает, что вы звонитеaddметод не работаетemitsсделать заявление.

app.component('Counter', {
    props: ['counter'],
    emits: ['add'],
    methods: {
        handleClick() {
            this.$emit('add')
        }
    },

После ее объявления предупреждение в консоли пропадает. Это также пара Vue子组件Ограничение при вызове родительского компонента заключается в том, что его необходимо объявить перед вызовом, иначе будет выдано предупреждение.

Дочерний компонент передает параметры родительскому компоненту

Например, когда мы не хотим добавлять 1 каждый раз, это значение равно子组件решили, например2Бар. В это время дочерний компонент должен передать значение родительскому компоненту, что также можно сделать. Вы можете написать так в дочернем компоненте.

methods: {
    handleClick() {
        this.$emit('add', 2)
    }
},

Затем примите этот параметр в родительском компонентеparam(Название этого параметра можно использовать произвольно), и вывести его на консоль для удобства просмотра.

methods: {
    handleAddCounter(param) {
        console.log(param)
        this.counter += param
    }
},

В это время параметры дочернего компонента передаются родительскому компоненту и могут использоваться. Конечно, у вас есть лучший вариант: поместить всю бизнес-логику в дочерний компонент и передать результат родительскому компоненту. Я обычно предпочитаю использовать этот метод, например, код можно написать следующим образом. Бизнес-логика написана в подкомпонентах

methods: {
    handleClick() {
        this.$emit('add', this.counter + 3)
    }
},

Родительский компонент может напрямую принять результат

methods: {
    handleAddCounter(param) {
        console.log(param)
        this.counter = param
    }
},

Проверка прошедших значений

Когда дочерний компонент передает значение родительскому компоненту, также можно включить функцию проверки. проверка пройденаemitsобъявлено с этой опцией. Например, теперь мы требуем, чтобы значение, переданное для сложения, не превышало 20. Предупреждать, если оно больше 20.

emits: {
    add: (value) => {
        return value < 20 ? true : false
    }
},

Моя бизнес-логика здесь очень проста, вы можете написать процесс проверки в соответствии с вашей бизнес-логикой.

Это все для этого раздела, давайте рассмотрим его. В этом разделе мы в основном объясняем работу подкомпонентов, вызывая методы родительского компонента и передавая параметры между компонентами. Маленькие друзья после обучения должны практиковаться на практике.Только на практике вы можете найти проблемы и по-настоящему научиться.

08. [Компонент] Использование слотов в компонентах Слот -1

Содержание этого раздела — использование слотов в компонентах. Для более наглядного понимания слотов мы используем кейс Red Romance Choice Technician.

написать инфраструктуру

Для лучшего объяснения давайте создадим новый файлDemo8.html, вы можете скопировать самую простую файловую структуру ниже. После копирования напишем другой код.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo08</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: ` <h2>欢迎光临红浪漫-请选择您的技师</h2>`
    })

    const vm = app.mount("#app")
</script>

</html>

Это самый простой код Vue3 с одним шаблоном.template. Затем мы создаем новый глобальный подкомпонент. Подкомпоненты называются技师компонент, в нем всего один простейший шаблон.

app.component('JiShi', {
    template: `
        <div>
            <span>经过你的慎重考虑.最终选择了。</span>
            <span>
                xxx
            </span>
        </div>
    `
})

После того, как у вас есть дочерний компонент, вызовите этот дочерний компонент в родительском компоненте.

const app = Vue.createApp({
    template: `
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <ji-shi />
        `
})

В настоящее времяXXX, конечно, его можно получить путем передачи и принятия атрибутов.Вы освоили этот способ.В этом разделе мы узнаем об активностях с использованием слотов.slot.

Знакомство со слотами

Объявление слота очень простое, просто добавьте его в дочерний компонент<slot></slot>Достаточно метки, а затем используйте двойную метку, чтобы вызвать ее в родительском компоненте. Конкретный код выглядит следующим образом:

<script>
    const app = Vue.createApp({
        template: `
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <ji-shi > 谢大脚 </ji-shi>
        `
    })

    app.component('JiShi', {
        template: `
        <div>
            <span>经过你的慎重考虑.最终选择了。</span>
            <span>
                <slot> </slot>
               
            </span>
        </div>
    `
    })

    const vm = app.mount("#app")
</script>

В это время заходим в браузер и видим, что на странице есть нужный результат. Вы можете сделать страницу богаче, потому что слот поддерживает любой элемент DOM, например, мы добавляем<div>Затем сделайте шрифт красным и размер шрифта 50 пикселей.

const app = Vue.createApp({
    template: `
    <h2>欢迎光临红浪漫-请选择您的技师</h2>
    <ji-shi > <div style="color:red;font-size:50px;">谢大脚</div> </ji-shi>
    `
})

Например, теперь звоните дважды<ji-shi>Компонентам также можно придать разные стили.

const app = Vue.createApp({
        template: `
    <h2>欢迎光临红浪漫-请选择您的技师</h2>
    <ji-shi > <div style="color:red;font-size:50px;">谢大脚</div> </ji-shi>
    <ji-shi > <div style="color:green;font-size:50px;">刘英</div> </ji-shi>
    `
})

Использование подкомпонентов в слотах

Слоты могут быть достаточно мощными, чтобы их можно было использовать напрямую子组件, а затем небольшой пример использования подкомпонентов в слотах. Первым может быть объявлен один из самых простых дочерних компонентов. Этот подкомпонент называетсяproject, то есть смысл проекта, это показать проект который мы сделали после выбора техника.

app.component('project', {
        template: `<span style="color:blue;">项目是胖哥老三样</span>`
    })

После того, как у вас есть компонент, вы можете использовать его непосредственно в слоте родительского компонента.Код выглядит следующим образом.

const app = Vue.createApp({
    template: `
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <ji-shi > 
                <div style="color:red;font-size:50px;">
                    谢大脚,<project />
                </div>
        </ji-shi>
        <ji-shi > <div style="color:green;font-size:50px;">刘英</div> </ji-shi>
        `
})

На превью в браузере видно, что слот можно поставить子组件из.

Использование динамических данных в слотах

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

const app = Vue.createApp({
    data() {
        return {
            jishi: '晓红'
        }
    },
    template: `
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <ji-shi > 
                <div style="color:red;font-size:50px;">
                    {{jishi}},<project />
                </div>
        </ji-shi>
        <ji-shi > <div style="color:green;font-size:50px;">刘英</div> </ji-shi>
    `
})

В это время нам нужно обратить внимание на проблему переменной области, например, у нас также есть элемент данных в нашем подкомпоненте.jishi, а затем назначьте его谢大脚.

app.component('JiShi', {
    data() {
        return {
            jishi: '谢大脚'
        }
    },
    template: `
    <div>
        <span>经过你的慎重考虑.最终选择了。</span>
        <span>
            <slot> </slot>
            
        </span>
    </div>
`
})

В это время вы обнаружите, что браузер по-прежнему отображает晓红, на этот раз мы пришли к выводу, который вам тоже удобно запомнить.

  • Атрибуты данных, вызываемые в родительском шаблоне, используют данные в родительском шаблоне.
  • Атрибуты данных, вызываемые в подшаблоне, используют данные в подшаблоне.

На этом содержание урока закончилось. Этот урок является первым знакомством. В следующем уроке мы продолжим знакомство со слотами.

09. [Компонент] Использование слотов в компонентах Слот-2

Этот раздел продолжает объяснять знания, связанные со слотами.Изучая предыдущую статью, вы нашли простой способ использования слотов. В этом уроке я предложу вам углубленное изучение и рассмотрю два метода записи, которые часто используются в слотах: значение слотов по умолчанию и использование именованных слотов.

Написать базовый файл

создать новый файлDemo9.html, а затем скопируйте простейшую структуру кода ниже.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo09</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: ` <h2>欢迎光临红浪漫-请选择您的技师</h2>`
    })

    const vm = app.mount("#app")
</script>

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

Как написать значение слота по умолчанию

Напишите глобальный компонент первым в файлеJiShi, код показан ниже.

app.component('JiShi',{
        template:`
            <div>
                你选择了<slot></slot>为你服务。
            </div>
        `
    })

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

const app = Vue.createApp({
    template: ` 
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <ji-shi><span style="color:red;">大脚</span></ji-shi>
    `
})

Это знания из предыдущего раздела, мы будем рассматривать их как обзор. Теперь есть новый клиент. Это первый раз. Мне жаль заказывать техника. Тогда нам нужно дать ему значение по умолчанию. Например, значение по умолчанию «Xiaohong». Ключевой синтаксис для значений по умолчанию находится в<slot>Просто введите значение прямо в слот.

app.component('JiShi',{
    template:`
        <div>
            你选择了<slot><span style="color:green;">晓红</span></slot>为你服务。
        </div>
    `
})

Теперь при таком способе написания при передаче значения будет отображаться обычное значение, а при отсутствии значения будет отображаться значение по умолчанию «Xiaohong».

Это использование значений по умолчанию в слотах, если вы уже знаете, давайте перейдем к следующему знанию, именованным слотам.

Использование именованных слотов

Первый взгляд на спрос, то есть, если идти в город пешком, пройти три процесса: до заказчика договориться о месте, выбрать техника, выбрать товар.

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

app.component('HongLangMan',{
        template:`
            <div>
                 <div>1.男宾一位,请上二楼。</div>
                 <div>2.你选择了大脚为你服务</div>
                 <div>3.你点了198元泰式按摩</div>
            </div>
        `
    })

Требования к программированию таковы, что выбор того, кто будет вас обслуживать, остается неизменным, то есть содержание во втором div остается неизменным. Но первое и третье предложения должны быть определены в родительском компоненте с помощью метода slot. Вы обнаружите, что в настоящее время существует проблема с программой.<slot>куда поставить? Кажется, это никуда не годится, поэтому мы просто поставили два<slot>, один сверху и один снизу, тест.

app.component('HongLangMan',{
    template:`
        <div>
                <slot></slot>
                <div>2.你选择了大脚为你服务</div>
                <slot></slot>
        </div>
    `
})

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

const app = Vue.createApp({
    template: ` 
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <hong-lang-man>
            <div>1.女宾一位,请上三楼。</div>
            <div>3.顾客选择了全身SPA。</div>
        </hong-lang-man>
    `
})

В это время, когда вы открываете браузер, вы обнаружите, что содержимое слота появляется дважды. Это также означает, что наша первая попытка не удалась.

На самом деле использование именованных слотов уже предусмотрено в Vue, что дает<slot>Тег добавляет атрибут имени, и вы можете написать дочерний компонент следующим образом.

app.component('HongLangMan',{
    template:`
        <div>
                <slot name="one"></slot>
                <div>2.你选择了大脚为你服务</div>
                <slot name="two"></slot>
        </div>
    `
})

Тогда родительский компонент можно вызвать следующим образом.

const app = Vue.createApp({
    template: ` 
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <hong-lang-man>
            <template v-slot:one><div>1.女宾一位,请上三楼。</div></template>
            <template v-slot:two><div>3.顾客选择了全身SPA。</div></template>
        </hong-lang-man>
    `
})

Теперь вы можете определить два слота отдельно в компоненте. Надеюсь, вы освоите этот метод.

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

10. [Компонент] Сокращенное название слота и слот с ограниченной областью действия

В этом разделе я сначала расскажу о сокращенном методе именованных слотов, который является дополнением к отсутствующим знаниям в предыдущем классе. Затем я расскажу о области действия ключевого слота в этом разделе.Это все еще относительно сложно понять, поэтому, если вы не понимаете, как только вы это изучите. Неважно, дважды введите код, а затем снова посмотрите видео или прочитайте статью, у вас должно быть глубокое понимание. Давайте сначала рассмотрим сокращенный метод для именованных слотов.

Сокращенный метод для именованных слотов

Здесь мы открываем метод Demo9.html Про именованные слоты мы узнали в прошлом классе (если не здесь, то можете посмотреть видео или статью последнего класса).

При определении местоположения слота в родительском шаблоне используйтеv-slot:oneЭтот метод, по сути, этот синтаксис можно сократить как#one. В это время код становится следующим.

const app = Vue.createApp({
    template: ` 
    <h2>欢迎光临红浪漫-请选择您的技师</h2>
    <hong-lang-man>
        <template v-slot:one><div>1.女宾一位,请上三楼。</div></template>
        <template v-slot:two><div>3.顾客选择了全身SPA。</div></template>
    </hong-lang-man>
`
})

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

Слоты с заданной областью — подготовка базового кода

На самом деле проблема основного слота предметной области решения состоит в том, что есть слот в подкомпонентах, и есть переменные, которые используются в родительских компонентах. Давайте сначала посмотрим на такую ​​потребность: написать дочернюю сборку, есть большие ноги, Лю Инхэ Xiaohong три переменных имени, а затем вывести его в подкомпоненты в виде цикла.

Прежде чем изучать слот домена, давайте выполним это основное требование, скопируем код Demo9 на страницу Demo10.html, а затем оставим самый простой код.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo10</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: `  <h2>欢迎光临红浪漫-请选择您的技师</h2>`
    })

    const vm = app.mount("#app")
</script>

Выше приведен самый простой код Vue3, не объясняя слишком много, вы можете скопировать этот код напрямую и начать свое обучение. Далее нам нужно написать подкомпонент, отвечающий только что упомянутым требованиям.

<script>
    const app = Vue.createApp({
        template: `  
            <h2>欢迎光临红浪漫-请选择您的技师</h2>
            <list />
        `
    })
    app.component('List', {
        data() {
            return {
                list: ['大脚', '刘英', '晓红']
            }
        },
        template: `
            <div>
                <div v-for="item in list">{{item}}</div>    
            </div>
        `
    })

    const vm = app.mount("#app")
</script>

Приведенный выше код, написание дочернего компонентаlist, а затем в компоненте списка объявляется элемент массива данных списка. В элементе данных есть три значения大脚,刘英а также晓红. Попробуйте в шаблонеv-forВ виде тиража.

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

Слоты области действия — конкретное объяснение

Когда базовый код готов, пришло время узнать о слотах с ограниченной областью действия. Текущий цикл в подкомпоненте<div>Метка, теперь требует, чтобы эта метка определялась при вызове родительского компонента, то есть для использования слота. (Следует отметить, что такая ситуация часто встречается при написании компонентов, поэтому следует уделить достаточно внимания).

Наша первоначальная идея могла состоять в том, чтобы сначала преобразовать подкомпоненты и увеличитьslotСлот, код шаблона после добавления слота выглядит следующим образом.

template: `
    <div>
        <slot v-for="item in list"  />    
    </div>
`

Затем вызывается родительский компонент, вызов выглядит следующим образом.

const app = Vue.createApp({
    template: `  
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <list> <span></span> </list>
    `
})

В это время просмотрите его в браузере, откройте консоль, и вы увидите, что в DOM их три.<span>помечен. иллюстрироватьDOMПередано в виде слота. Следующий вопрос заключается в том, как родительский компонент использует переменные в дочернем компоненте.

Родительский компонент хочет использовать значение в слоте дочернего компонента, вы можете использовать:Передается в виде привязки, например написания как:item="item", конкретный код можно записать следующим образом.

app.component('List', {
    data() {
        return {
            list: ['大脚', '刘英', '晓红']
        }
    },
    template: `
        <div>
            <slot v-for="item in list" :item="item" />    
        </div>
    `

После написания он используется в родительском компонентеv-slot="xxx"Форма принята, и ее можно использовать после получения.

const app = Vue.createApp({
    template: `  
    <h2>欢迎光临红浪漫-请选择您的技师</h2>
    <list v-slot="props"> 
        <span>{{props.item}}</span> 
    </list>
`
})

В это время вы обнаружите, что список может отображаться нормально, и вы также можете изменить метку.Вы можете попробовать поставить<span>Замените этикетку на<div>тег, чтобы попробовать.

Обратите внимание здесьpropsВсе данные, передаваемые дочерними компонентами, являются объектами, поэтому мы должны добавить.itemбыть использованным. Вы можете изменить код.

<list v-slot="props">
    <div>{{props.item}}-{{props}}</div> 
</list>

Выходные результаты следующие

大脚-{ "item": "大脚" }
刘英-{ "item": "刘英" }
晓红-{ "item": "晓红" }

Упростите обозначение слотов с заданной областью действия.

На самом деле упрощенный метод также очень прост, если используется форма деструктурирования, которая является способом записи в ES6. Если вы не знакомы с этой частью, вы можете взглянуть на знания синтаксиса ES6 о деструктуризации.

const app = Vue.createApp({
    template: `  
        <h2>欢迎光临红浪漫-请选择您的技师</h2>
        <list v-slot="{item}"> 
            <div>{{item}}</div> 
        </list>
        `
})

Хотя это письмо простое, его все же немного сложно понять.

Подводя итог: на этом уроке мы в основном изучили два знания: одно — сокращенный метод именованного слота, а второе — использование и сокращенный метод слота с областью действия. Дело в слоте области, и именно из-за слота области дочерний компонент может передавать свои собственные элементы данных для использования родительским компонентом.

11. [Компоненты] Динамические компоненты и сохранение состояния

В этой статье мы в основном изучаем важную концепцию Vue3 — динамические компоненты. Некоторым знакомым может быть сложно, услышав динамическую составляющую, на самом деле понять ее несложно, и она будет больше использоваться в работе.

Теперь мы подошли к виртуальному требованию: нам нужно написать функцию для выбора техников с картинками для Города мытья ног Red Romance и позволить клиентам вручную переключать этих техников. (На самом деле есть несколько способов выполнить это требование, но здесь мы намеренно используем динамические компоненты для обучения, что не означает, что это оптимальное решение.)

Подготовьте базовый код

создать новый файлDemo11.html, а затем скопируйте содержимое кода из Demo10 в Demo11 и измените его на самый простой код.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo11</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: ` 
            <h2>欢迎光临红浪漫-请选择您的技师</h2> 
        `
    })
 
    const vm = app.mount("#app")
</script>

Вы также можете скопировать этот код для быстрого обучения или даже выбить его самостоятельно (более эффектно).

Создайте подкомпонент бигфута

Теперь вы можете создать два подкомпонента для отображения фотографий снежного человека и Лю Ина. Сначала укажите адрес фотографии, необходимый в курсе (вместо этого вы также можете найти фотографию самостоятельно)

Материальные фотографии (адрес изображения доступен напрямую):

谢大脚图片地址: https://newimg.jspang.com/xiedajiao01.jpg
刘英图片地址:   https://newimg.jspang.com/liuying01.jpg

Затем напишите два компонента:

app.component('dajiao',{
    template:`<img src="https://newimg.jspang.com/xiedajiao01.jpg" />`
})

app.component('liuying',{
    template:`<img src="https://newimg.jspang.com/liuying01.jpg" />`
})

Затем используйте эти два компонента непосредственно в родительском компоненте.

const app = Vue.createApp({
    template: ` 
        <h2>欢迎光临红浪漫-请选择您的技师</h2> 
        <dajiao />
        <liuying />
    `
})

В это время мы можем проверить результат в браузере, если результат нормальный, значит, в нашем письме нет ошибки.

оригинальный эффект перехода

Требование теперь состоит в том, что если один из компонентов отображается, другой не отображается. Моя первая мысль здесь - использоватьv-showЭтот код для реализации.

Давайте сначала определим элемент данных для управления отображаемым компонентом.Элемент данных называетсяshowItem, а затем добавьте атрибут v-show к положению двух подкомпонентов, чтобы управлять окончательным отображением.

const app = Vue.createApp({
    data(){
        return {showItem:'dajiao'}
    },
    template: ` 
        <h2>欢迎光临红浪漫-请选择您的技师</h2> 
        <dajiao  v-show="showItem==='dajiao'" />
        <liuying v-show="showItem==='liuying'" />
    `
})

В настоящее времяshowItemзначениеdajiao, поэтому браузер должен отображать толькоdajiaoс компонент.

Затем напишите кнопку для переключения двух компонентов, кнопка должна связать методhandleClick, метод Для написания этой части я использовал тернарный оператор.

<button @click="handleClick">切换佳丽</button>
methods:{
    handleClick(){
        this.showItem= this.showItem=='dajiao'?'liuying':'dajiao'
    }
},

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

Код оптимизации динамического компонента

использовать动态组件метод программирования, вы можете опуститьv-showЧасть кода также может сделать код более элегантным.

<component :is="showItem" />

С помощью приведенного выше короткого кода вы можете удалить следующие две строки кода.

<dajiao  v-show="showItem==='dajiao'" />
<liuying v-show="showItem==='liuying'" />

Этот код означает использование динамического компонента и, наконец, отображение этого компонента с помощью элемента данных.showItemрешение, его значениеdajiaoПросто покажите фото Се Дацзяо, его стоимостьliuying, на котором изображена фотография Лю Ин.

Это очень просто и легко в использовании.

Сохранение состояния в динамических компонентах

Динамические компоненты очень удобны в использовании, но у них есть небольшая проблема. Давайте изменим его сейчасdajiaoкомпонент, который превращает фотографию вinputРамка.

app.component('dajiao',{
    template:`<input />`
})

В это время вы заходите в браузер для просмотра и вводите текст в поле ввода, после переключения компонентов. ты найдешьinputТекст в поле не может быть сохранен.

чтобы спастиinputтекст в поле, вы можете использовать<keep-alive>теги, обертывающие динамические компоненты.

<keep-alive>
    <component :is="showItem" />
</keep-alive>

В это время кеш достаточно активен, и значение поля ввода сохраняется. При использовании динамических компонентов часто сотрудничайте с<keep-alive>теги используются вместе.

Что ж, это содержание этого урока, я надеюсь, вы сможете освоить два важных знания, одно из которых — использование динамических компонентов, а другое —<keep-alive>Использование ярлыков.

12. [Компонент] Асинхронные компоненты и объяснение промисов

В этом разделе нам нужно объяснить асинхронные компоненты в Vue и понять, что такое асинхронные компоненты, На самом деле, есть предварительное знание, то есть вам нужно знать, что синхронно, а что асинхронно. и вы также будете использоватьPromise, Если вы не очень хорошо разбираетесь в Promise, я предлагаю вам сначала ознакомиться с основами JavaScript, а затем изучить его.

Пишите базовый код и синхронизируйте компоненты

создать новый файлDemo12.html, затем скопируйтеDemo10.htmlсодержание, изменить его.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo11</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: ` 
          
        `
    })
   
    const vm = app.mount("#app")
</script>

Затем напишите синхронный компонент (на самом деле все, что я узнал ранее, это синхронные компоненты) и используйте его в родительском компоненте.

const app = Vue.createApp({
    template: `  <div><tongbu /></div>`
})
app.component('tongbu',{
    template:`<div>JSPang.com</div>`
})

const vm = app.mount("#app")

На данный момент это синхронный компонент, потому что после вызова код будет выполняться напрямую. После того, как мы разберемся с синхронными компонентами, давайте узнаем об асинхронных компонентах.

Асинхронные компоненты в vue3

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

app.component('async-component',Vue.defineAsyncComponent(()=>{
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve({
                template:`<div>这是一个异步组件</div>`
            })
        },3000)
    })

}))

В этом коде создается новый компонент с именемasync-component, затем используйтеdefineAsyncComponent()Объявить, что это асинхронный компонент, внутри компонента, который мы используемPromiseдля завершения логики. Логика очень проста, используйтеsetTimeoutВизуализация шаблона после 3 секунд контроляtemplateПоказать содержимое.也就是说3秒后,组件才知道最终展示的内容是什么。这就是一个典型的异步组件。

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

Если вы все еще не понимаете содержание этого урока, не расстраивайтесь. Поскольку обязательным условием этого класса является то, что вы будете использовать промисы, вы можете сначала изучить знания о промисах, а затем вернуться к этому классу. Должно быть намного проще.

13. [Компонент] предоставляет и внедряет многоуровневые компоненты для передачи значений.

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

Создайте многоуровневый компонент

создать новый файлDemo13.html, скопируйте основной код, вы также можете скопировать код из предыдущего урока, чтобы изменить его.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo13</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script>
    const app = Vue.createApp({
        template: `<div>我有一套房子,我先传给我的儿子</div>`
    })
    const vm = app.mount("#app")
</script>

Текущее требование состоит в том, чтобы написать подкомпонент, а затем вызвать другой подкомпонент в подкомпоненте (который также можно представить как дочерний компонент), а затем передать значение из самого верхнего родительского компонента в подкомпонент.

Начнем с написания кода для двух подкомпонентов.

<script>
    const app = Vue.createApp({
        data(){
            return {house:'北京别墅一套'}
        },
        template: `<div>我有一套房子,我先传给我的儿子</div> `
    })

    app.component('child',{
        template:`
            <div>我是子组件,我要把房子再传给我儿子。</div>
        `
    })

    app.component('child-child',{
        template:`
            <div>我是孙子,等待接收房子</div>
        `
    })
    const vm = app.mount("#app")
</script>

Основной результат и составляющие уже есть, посмотрим как эта ситуация будет пройдена.

Распространенные способы доставки

Текущее требование состоит в том, чтобы передать его слой за слоем, мы можем использоватьpropsПолучить в виде , а затем продолжить передачу, код может быть таким.

<script>
    const app = Vue.createApp({
        data(){
            return {house:'北京别墅一套'}
        },
        template: `
            <div>我有一套房子,我先传给我的儿子</div>
            <child :house="house" />
         `
    })

    app.component('child',{
        props:['house'],
        template:`
            <div>我是子组件,我要把房子再传给我儿子。</div>
            <div>儿子接收{{house}}</div>
            <child-child :house="house" />
        `
    })

    app.component('child-child',{
        props:['house'],
        template:`
            <div>我是孙子,等待接收房子</div>
            <div>孙子接收{{house}}</div>
        `
    })
    const vm = app.mount("#app")
</script>

В это время проверьте результат в браузере, и вы обнаружите, что результат успешен. Каждый раз, когда он получен с реквизитами, он затем передается на следующий уровень с помощью свойств привязки.

Но сейчас спрос изменился.Есть еще дом площадью 200 квадратных метров на третьем транспортном кольце Пекина.Они не хотят передавать его внуку напрямую через руки сына.Как с этим работать?

Многоуровневые компоненты передают значение, обеспечивают и внедряют

В настоящее время вы можете использовать предоставление для передачи и внедрение для получения, сначала объявите один ниже элемента данных.provide.

const app = Vue.createApp({
    data(){
        return {house:'北京别墅一套'}
    },
    provide:{
        newHouse:'北京200平方房子一套'
    },
    template: `
        <div>我有一套房子,我先传给我的儿子</div>
        <child :house="house" />
        `
})

Затем дочерний компонент не используется для каких-либо изменений, он используется непосредственно во внучатом компоненте.injectПросто примите это.

app.component('child-child',{
    props:['house'],
    inject:['newHouse'],
    template:`
        <div>我是孙子,等待接收房子</div>
        <div>孙子接收{{house}},{{newHouse}}</div>
    `
})

После написания вы можете открыть браузер, чтобы просмотреть его, и обнаружить, что компонент внука также может быть получен без проблем.

У нас не так много уровней обучения кейсов, поэтому вы не чувствуете себя очень сильными.Если эта иерархическая связь дойдет до 5-6 уровней, а потом использовать реквизит для ее прохождения, это будет очень хлопотно, и будет много избыточности кода. использоватьprovideа такжеinjectможет решить эту проблему.

Итак, «Изучаем Vue3.x с нуля — Сезон 2 — Компоненты» в этом сезоне подошли к концу. Третий сезон «Vue3 Animation» начал обновляться.