Vue学习笔记(二) —— 组件开发

简介

在了解了Vue语法的基础知识和经常使用特性以后,在进行正式的开发以前,很是有必要的对组件化的相关知识进行了解。本文就是为介绍组件的相关知识点的。javascript

一、组件化开发思想

现实生活中的组件化思想主要是:标准,分治,重用和组合。而软件上的组件化思想,其实都是对上面所说的进行抽象表示,然而每种语言所用的标准可能又不相同。css

组件化规范:Web Componentshtml

可是这个规范并非全部的浏览器都支持java

  • 咱们但愿尽量多的重用代码
  • 自定义组件的方式不太容易(html,css和js
  • 屡次使用组件可能致使冲突

Web Components 经过建立封装好功能的定制化元素来解决上述问题。web

其官网地址为:https://developer.mozilla.org/zh-CN/docs/Web/Web_Componentschrome

Vue部分的实现了上述规则。shell

二、组件注册

2.1 全局组件注册语法

Vue.component(组件名称 ,{
    data: 组件数据,
    template: 组件模板内容
})

如下是定义组件的具体例子。数组

// 定义一个名为button-counter的新组件
Vue.component('button-counter',{
    data: function () {
        return {
            count : 0
        }
    },
    template : '<button v-on:click="count++">点击了{{count}}次。</button>'
})

2.2 组件的用法

<div id="app">
    <button-counter></button-counter>
</div>
<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>

2.3 组件注册的注意事项

  • data 必须是一个函数浏览器

    • 分析函数和普通对象的对比
  • 组件模板内容必须是单个根元素app

    • 分析演示实际的效果
  • 组件模板内容可用是模板字符串

    • 模板字符串须要浏览器提供支持(ES6语法)
    • 即模板内容使用反引号(tab键上面那个键)包裹,可多行显示,可读性强。(正常是用单引号包裹的)
  • 组件命名方式

    • 短横线方式
    • 驼峰方式
Vue.component('my-component',{ /*...*/})
Vue.component('MyComponent',{ /*...*/})

若是使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件;可是在普通的标签模板中,必须使用短横线的方式使用组件。

2.4 局部组件注册

var ComponentA = { /* ... */}
var ComponentB = { /* ... */}
var ComponentC = { /* ... */}

new Vue({
    el: '#app',
    components: {
        'component-a': ComponentA,
        'component-b': ComponentB,
        'component-c': ComponentC
    }
})

局部组件只能在组测它的父组件中使用,其余地方不可使用。

三、Vue调试工具

3.1 安装调试工具

在官网的生态系统菜单下可找到 Devtools
在这里插入图片描述

安装步骤:

  • 克隆仓库
  • 安装依赖包
  • 构建
  • 打开chrome扩展页面
  • 选中开发者模式
  • 加载已经解压的扩展,选中shells/chrome

安装后以下图所示:
在这里插入图片描述

可用很直观的查看组件之间的层次关系。

四、组件间的数据交互

4.1 父组件向子组件传值

一、组件内部经过props接收传递过来的值

Vue.component('menu-item',{
    props: ['title'],
    data: function() {
        return {
            msg: '子组件自己的数据'
        }
    }
    template:'<div>{{ msg + "-------" + title }}</div>'
})

二、父组件经过属性将值传递给子组件

<menu-item title="来自父组件的数据"></menu-item>
<menu-item :title="title"></menu-item>

三、props属性名规则

  • props中使用驼峰形式,模板中须要使用短横线的形式

  • 字符串形式的模板中没有这个限制

Vue.component('menu-item', {
    // 在javascript中是驼峰式的
    props: ['menuTitle'],
    template: '<div>{{ menuTitle }}</div>'
})
<!-- 在html中是短横线方式的 -->
<menu-item menu-title="nihao"></menu-item>

四、props属性值类型

  • 字符串 String
  • 数值 Number
  • 布尔值 Boolean
  • 数组 Array
  • 对象 Object

4.2 子组件向父组件传值

props传递数据原则:单项数据流。即父组件可经过props向子组件传递数据,不建议经过props从子组件向父组件传值。

一、子组件经过自定义事件向父组件传递信息

<button v-on:click='$emit("enlarge-text")'>扩大字体</button>

二、父组件监听子组件的事件

<menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>

三、子组件经过自定义事件(带参数)向父组件传递信息

<button v-on:click='$emit("enlarge-text",0.1)'>扩大字体</button>

<!--父组件处理事件-->
<menu-item v-on:enlarge-text='fontSize += $event'></menu-item>

4.3 非父子组件间传值

一、单独的事件中心管理组件间的通讯

var eventHub = new Vue()

二、监听事件与销毁事件

eventHub.$on('add-todo',addToDo)
eventHub.$off('add-todo')

三、触发事件

eventHub.$emit('add-todo',id)

可参考下图所示
在这里插入图片描述

五、组件插槽

5.1 组件插槽的做用

  • 父组件向子组件传递内容
    在这里插入图片描述

5.2 组件插槽级别用法

一、插槽位置

Vue.conmponent('alert-box', {
    template: ` <div class="demo-alert-box"> <strong>Error:</strong> <slot>默认内容</slot> </div> `
})

二、插槽内容和显示效果

<alert-box>有一个bug</alert-box>
<alert-box>有一个警告</alert-box>
<alert-box></alert-box>

<!--显示以下-->
Error:有一个bug
Error:有一个警告
Error:默认内容

5.3 具名插槽用法

一、插槽定义

<div class="container">
    <header>
        <slot name="header"></slot>
    </header>
    <main>
        <slot></slot>
    </main>
    <footer>
        <slot name="footer"></slot>
    </footer>
</div>

二、插槽内容

<base-layout>
    <h1 slot=="header">标题内容</h1>

    <p>主要内容1</p>
    <p>主要内容2</p>

    <p name="footer">底部内容</p>
</base-layout>
<base-layout>
    <tempalte slot=="header">
        <h1>标题内容</h1>
        <h1>标题内容</h1>
    </tempalte>

    <p>主要内容1</p>
    <p>主要内容2</p>

    <tempalte name="footer">
        <p>底部内容</p>
        <p>底部内容</p>
    </tempalte>    
</base-layout>

5.4 做用域插槽

  • 应用场景:父组件对子组件的内容进行加工处理

一、插槽定义

<ul>
    <li v-for="item in list" v-bind:key="item.id">
        <!--bind后的item是自定义的,引号中的item是上面的-->
        <slot v-bind:item="item">
            {{ item.name }}
        </slot>
    </li>
</ul>

二、插槽内容

<fruit-list v-bind:list="list">
    <template slot-scope="slotProps">
        <!--此处显示了加工处理的状况-->
        <strong v-if="slotProps.item.current">
            {{ slotProps.item.text}}
        </strong>
    </template>
</fruit-list>

总结

组件化的开发,可让咱们在实际的项目中对不少公共的功能进行抽取,从而实现重用。固然,本文中的不少知识点不是只看看就能理解的,须要手动的编码去感觉代码的实现细节,并加深理解。接下来是关于先后的交互的相关总结,有兴趣的也可看看。