Знакомство с компонентами Vue

внешний интерфейс JavaScript Vue.js

предисловие

Vue.js — это прогрессивный фреймворк (официальное описание) для создания пользовательских интерфейсов. С точки зрения непрофессионала, Vue.js — это легкая, простая в использовании, простая в использовании, удобная и гибкая интерфейсная среда MVVM. Краткий API и качественная документация на китайском языке облегчают разработчикам начало работы с платформой Vue.

Эта серия статей объединит некоторый личный опыт (кенг) в использовании Vue (кенг) и некоторые кейсы, выведет некоторые знания о фреймворке Vue, а также закрепит понимание фреймворка Vue.

Знакомство с компонентами

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

Регистрация компонентов Vue

Мы можем зарегистрировать компонент Vue через глобальную регистрацию и локальную регистрацию. Разница между этими двумя методами заключается в том, что глобально зарегистрированный компонент можно использовать где угодно. Фактически, все экземпляры Vue будут отображать этот глобальный компонент, а локальные компоненты регистрируются только на определенный объект экземпляра Vue, и могут отображаться только при создании экземпляра этого экземпляра Vue.При использовании в других местах они будут отображаться как обычные теги Html. Давайте сначала разберемся с регистрацией глобальных компонентов.
Пройти, если компоненты Vue зарегистрированы глобальноVue.component(tagName, options)способ зарегистрироваться. См. простой пример.

<div id="app" class="demo">
    <!-- Vue组件 -->
    <simple-component></simple-component>
</div>
<script>
    Vue.component("simple-component", {
        template: "<span>我是一个最简单的Vue组件示例</span>"
    })
    new Vue({
        el: "#app"
    })
</script>

Метод Vue.component передает два параметра: один параметр — это имя пользовательской метки компонента, другой параметр — объект, а значение свойства шаблона внутри — это шаблон компонента.

Вы можете подумать, что содержимое компонента слишком простое, метка всего одна, если содержимое компонента более сложное, следует ли сращивать содержимое вместе со строками, как раньше? Это кажется слишком страшным.Даже если используется строковый синтаксис es6, это большой толчок, чтобы записать его, что очень неэлегантно. Ну да, во Vue есть хорошее решение этой проблемы, можно использовать<script type="x-template">теги для обработки сложных шаблонов компонентов.

<div id="app2" class="demo">
    <vut-button></vut-button>
</div>
<script type="x-template" id="vComponent">
    <div class="vut-button">
        <span>我是Button组件</span>
    </div>
</script>

<script>
    Vue.component("vut-button", {
        template: "#vComponent"
    })
    new Vue({
        el: "#app2"
    })
</script>

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

<div id="app-test" class="demo">
    <vut-button></vut-button>
</div>
<template id="vComponent">
    <div class="vut-button">
        <span>我是Button组件</span>
    </div>
</template>

<script>
    Vue.component("vut-button", {
        template: "#vComponent"
    })
    new Vue({
        el: "#app-test"
    })
</script>

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

<div id="app-local" class="demo">
    <!-- Vue组件 -->
    <simple-component></simple-component>
</div>
<script>
    new Vue({
        el: "#app-local",
        components: {
            "simple-component": {
                template: "<span>我是一个最简单的局部Vue组件示例</span>"
            }
        }
    })
</script>

Параметры экземпляра VuecomponentsСодержит свойство, ключ — это имя компонента, а значение — это объект, содержащий свойства, такие как шаблон компонента.

Передать данные с помощью Prop

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

<div id="app" class="demo">
    <simple-component link="https://github.com/vuejs/vue"></simple-component>
</div>
<script>
    Vue.component("simple-component", {
        template: "<span>Vue的github地址是:{{ link }}</span>",
        props: ["link"]
    })
    new Vue({
        el: "#app"
    })
</script>

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

props: {
    link: {
        type: String, //数据类型
        defalut: "https://www.baidu.com/" //默认值
    }
}

Так как же родительский компонент динамически передает данные дочернему компоненту? Помните роль инструкции v-bind, ее роль用于动态绑定html属性或者是组件的props值, поэтому для динамической передачи данных следует использовать инструкцию v-bind.

<template id="userComponent">
    <div>
        <p>用户名:{{ userName }}</p>
        <p>性别:{{ sex }}</p>
        <p>年龄:{{ age }}</p>
    </div>
</template>
<script type="text/javascript">
    Vue.component("user-component", {
        template: "#userComponent",
        props: ["userName", "sex", "age"]
    })
</script>
<div id="app2" class="demo">
    <div>
        <input type="text" v-model="userName" placeholder="请输入用户名">
        <input type="text" v-model="sex" placeholder="请输入性别">
        <input type="text" v-model="age" placeholder="请输年龄">
    </div>
    <user-component
    :user-name="userName"
    :sex="sex"
    :age="age"
    >
    </user-component>
</div>
<script type="text/javascript">
    new Vue({
        el: "#app2",
        data: {
            userName: "",
            sex: "",
            age: ""
        }
    })
</script>

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

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

<template id="comment-component">
    <div class="i-comment-area">
        <textarea rows="5" class="i-textarea" placeholder="请输入内容" v-model="commentValue"></textarea>
        <div class="i-comment-submit" @click="handleSubmit">
            <span>提交</span>
        </div>
    </div>
</template>

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

Vue.component("i-comment", {
    template: "#comment-component",
    data: function(){
        return {
            commentValue: ""
        }
    },
    methods: {
      handleSubmit: function(){
          if(this.commentValue.length < 1){
              alert("评论不能为空");
              return;
          }
          this.$emit("content", this.commentValue);
          this.commentValue = "";
      }
    }
})

Вы можете обнаружить, что опция экземпляра данных в компоненте отличается от предыдущего метода написания, да, это то, на что вы должны обратить внимание при написании компонента,Vue规定了组件中的data选项必须是函数. Затем привяжите событие клика к кнопке отправкиhandleSubmit, когда вы заполните содержание комментария и нажмете, чтобы отправить комментарий, компонент пройдет$emit(eventName)Инициировать событие с параметром, который передает содержимое комментария родительскому компоненту.

Поскольку дочерний компонент передается$emit(eventName)Как для связи с родительским компонентом родительский компонент получает данные, переданные дочерним компонентом?$on(eventName)Слушайте события.

<div id="simple-comment" class="demo">
    <i-comment v-on:content="commentData"></i-comment>
    <label class="title">评论列表</label>
    <ul class="comment-list">
        <li v-for="(item,index) in commentList">
            <span>{{ item.time }}</span>
            <span>{{ item.content }}</span>
        </li>
    </ul>
</div>

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

Реализовать компонент Switch UI

Затем реализуйте компонент пользовательского интерфейса Switch, фактически испачкав руки. Во-первых, подумайте о том, какие базовые API-интерфейсы должны быть у компонента Switch.

  • Учитывая сценарий использования, необходимо сформулировать компоненты Switch разного размера, поэтому необходимоsizeAPI.
  • Учитывая, что будут сценарии, где использование запрещено, необходимо запретить и включить функцию компонента, поэтому необходимоdisabledAPI.
  • Учитывая необходимость настройки цвета фона при открытии и закрытии, необходимоon-colorа такжеoff-colorAPI для настройки цвета фона.
  • Точно так же вам может потребоваться настроить текст, отображаемый при открытии и закрытии, поэтому вам нужноon-textа такжеoff-textAPI определяется из текстового дисплея.
  • Также может быть необходимо получить текущее состояние через мониторинг событий и выполнять некоторые операции в соответствии с состоянием, поэтому мероприятие требуется для контроля изменения состояния, поэтому необходимоon-changeAPI.

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

<span :class="wrapClass">
    <span :class="switchClass" @click="handleChangeFn" ref="switch">
        <input type="hidden" :value="currentValue">
    </span>
</span>

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

var prefixClass = "vut-switch";
Vue.component("vut-switch",{
    template: "#switch-component",
    props: {
        value: {
            type: Boolean,
            default: false
        }
    },
    data: function(){
        return {
            currentValue: this.value //当前状态
        }
    },
    computed: {
        wrapClass: function(){
            return prefixClass + "-wrap";
        },
        switchClass: function(){
            return [
                prefixClass,
                {
                    [prefixClass + "-checked"]: this.currentValue
                }
            ];
        }
    }
})

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

Значение размера должно быть передано через родительский компонент, поэтому сначала определите объект размера в опции props в дочернем компоненте.

props: {
    value: {
        type: Boolean,
        default: false
    },
    size: String //尺寸
}

Затем наша идея состоит в том, чтобы управлять отображаемыми компонентами Switch с помощью различных стилей. Мы добавляем разные значения класса и формулируем разные стили в соответствии с переданными значениями разных размеров, поэтому свойство вычисления switchClass можно записать следующим образом:

switchClass: function(){
    return [
        prefixClass,
        {
            [prefixClass + "-checked"]: this.currentValue,
            [prefixClass +"-"+ this.size]: this.size
        }
    ];
}

Затем добавьте соответствующие стили.

/*小尺寸*/
.vut-switch-small{
    width: 40px;
    height: 20px;
}
.vut-switch-small:after{
    width: 16px;
    height: 16px;
}
.vut-switch-small.vut-switch-checked:after{
    left: 22px;
}

/*大尺寸*/
.vut-switch-large{
    width: 60px;
}
.vut-switch-large.vut-switch-checked:after{
    left: 38px;
}

Наконец, мы используем компонент Switch в шаблоне инициализации экземпляра Vue.

<vut-switch size="small"></vut-switch>
<vut-switch size="large"></vut-switch>

Таким образом, мы можем контролировать размер отображаемого компонента Switch, и эффект будет следующим:

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

props: {
    value: {
        type: Boolean,
        default: false
    },
    size: String, //尺寸
    onColor: String, //开启时的自定义背景色
    ofColor: String //关闭时的自定义背景色
}

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

setBackgroundColor: function(){
    let customColor = this.currentValue ? this.onColor : this.offColor;
    this.$refs.switch.style.backgroundColor = customColor;
}

Затем прослушайте изменения значения currentValue, чтобы вызвать эту функцию.

watch: {
    currentValue: function(){
        this.setBackgroundColor();
    }
}

Наконец, мы используем компонент Switch в шаблоне инициализации экземпляра Vue.

<vut-switch on-color="#13ce66" off-color="#ff4949"></vut-switch>

Эффект следующий:

Посмотрите полный примеркомпонент переключателя.

постскриптум

Статьи написаны в настрое обучения и подведения итогов, на любые ошибки и проблемы в тексте можно указать на github.issues. Все кейсы в этой статье размещены на github по адресу:GitHub.com/Веб-проблема/….