一、组件化开发概述
  1.组件化开发思想
    标准
    分治:不同的功能分配到不同的组件中
    重用:
    组合
  2.编程中的组件化思想体现
  3.组件化规范:
    Web Components
      我们希望尽可能多的重用代码
      自定义组件的方式不太容易(html、css和js)
      多次使用组件可能导致冲突
    Web Components通过创建封装好功能的定制元素解决上述问题
    Vue部分实现了上述规范
    不同的功能封装到不同的组件中,组件可以组合以形成完整的应用
 
二、组件的注册
 
  2.1 全局组件注册语法
    Vue.component(组件名称,{
      data:组件数据,
      template:组件模板内容
    })
 
  例:
1 // 定义一个名为button-counter的组件
2 Vue.component('button-counter',{
3 data:function(){
4 return{
5 count:0
6 }
7 },
8 template:`<button @click='count++'>点击了{{count}}次</button>`
9 });
  
  2.2 组件的用法
1 <div id="app">
2 <button-counter></button-counter>
3 <button-counter></button-counter>
4 <button-counter></button-counter>
5 </div>
    注:组件可以重用,且组件之间是相互独立的
  2.3 组件注册注意事项
    1.data必须是一个函数
      分析函数与普通对象的对比
 
    2.组件模板内容必须是单个的根元素
      分析实际演示效果
 
    3.组件模板内容可以是模板字符串
      模板字符串需要浏览器提供支持(ES6语法)
 
    4.组件的命名方式
      短横线
      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,
      }
    })
 1 var HelloWorld = {
2 data:function(){
3 return{
4 msg:'Hello World'
5 }
6 },
7 template:`<div>{{msg}}</div>`
8 };
9
10 var HelloTom = {
11 data:function(){
12 return{
13 msg:'Hello Tom'
14 }
15 },
16 template:`<div>{{msg}}</div>`
17 };
18
19 var HelloJerry = {
20 data:function(){
21 return{
22 msg:'Hello Jerry'
23 }
24 },
25 template:`<div>{{msg}}</div>`
26 };
27 var vm = new Vue({
28 el:'#app',
29 data:{
30
31 },
32 components:{
33 'hello-world':HelloWorld,
34 'hello-tom':HelloTom,
35 'hello-jerry':HelloJerry
36 }
37 })
    注:局部组件只能在父组件中使用,不能在其他的组件中使用
 
三、Vue调试工具
  3.1 调试工具安装
    (1) 克隆仓库
    (2) 安装依赖包
    (3) 构建
    (4) 打开Chrome扩展页面
    (5) 选中开发者模式
    (6) 加载已解压的扩展,选择shells/chrome
 
四、组件间数据交互
   
  4.1 父组件向子组件传值
 
    1.子组件中通过props接收父组件传递过来的内容,具体通过属性名来接收
    2.父组件通过属性将值传递给子组件,属性绑定有两种方式,一是写死,二是动态绑定
    3.属性可以传递多个,具体可以在props中多加参数
1 <div id="app">
2 {{pmsg}}
3 <menu-item title='来自父组件的值'></menu-item>
4 <menu-item :title='ptitle' content='hello'></menu-item>
5 </div>
 1 Vue.component('menu-item',{
2 props:['title','content'],
3 data:function(){
4 return{
5 msg:'子组件自身的数据'
6 }
7 },
8 template:`<div>{{msg + '----' + title + '----' + content}}</div>`
9 })
10 var vm = new Vue({
11 el:'#app',
12 data:{
13 pmsg:'父组件中的内容',
14 ptitle:'父组件传向子组件的动态绑定的数据'
15 }
16 })

    

   4.2 props属性名规则
     1.在props中使用驼峰的形式,模板中需要使用短横线的形式
     2.字符串形式的模板中没有这个限制   
1 <div id="app">
2 {{pmsg}}
3 <menu-item :menu-title='ptitle'></menu-item>
4 </div>
 1 Vue.component('third-com',{
2 props:['testTitle'],
3 template:`<div>{{testTitle}}</div>`
4 })
5 Vue.component('menu-item',{
6 props:['menuTitle'],
7 template:`<div>{{menuTitle}}<third-com testTitle="啦啦啦"></third-com></div>`
8 })
9 var vm = new Vue({
10 el:'#app',
11 data:{
12 pmsg:'父组件中的内容',
13 ptitle:'动态绑定属性'
14 },
15 })
    4.3 props属性值类型
 
      字符串  String
      数值     Number
      布尔值  Boolean
      数组     Array
      对象     Object 1<div id="app"> 2<!--       
 3             字符串  String
4 数值   Number
5 布尔值  Boolean
6 数组   Array
7 对象   Object
8 -->
9 <menu-item :pstr='pstr' :pnum='pnum' :pboo='pboo' :parr='parr' :pobj='pobj'></menu-item>
10 </div>
 1 Vue.component('menu-item',{
2 props:['pstr','pnum','pboo','parr','pobj'],
3 template:`<div>
4 <div>{{"传递的是字符串" + pstr}}</div>
5 <div>{{"传递的是数字" + pnum}}</div>
6 <div>{{"传递的是布尔值" + pboo}}</div>
7 <div>数组:</div>
8 <ul>
9 <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
10 </ul>
11 <div>{{"传递的是对象:"}}<span>{{pobj.name}}</span><span>{{pobj.age}}</span></div>
12 </div>`
13 })
14 var vm = new Vue({
15 el:'#app',
16 data:{
17 pmsg:'父组件中的内容',
18 pstr:'hello',
19 pnum:12,
20 pboo:true,
21 parr:['apple','orange','banana'],
22 pobj:{
23 name:'lisi',
24 age:12
25 }
26 }
27 })

       

    4.4 子组件向父组件传值
 
      注:props传递数据原则: 单向数据流,只允许父组件向子组件传递数据,不允许子组件直接操作props的数据
 
      1. 子组件通过自定义事件向父组件传值
        <button v-on:click='$emit("enlarge-text")'>扩大字体</button>
 
      2. 父组件监听子组件事件
        <menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>
 
1 <div id="app">
2 <div :style='{fontSize:fontSize + "px"}'>{{pmsg}}</div>
3 <menu-item :parr='parr' @enlarge-text='handle'></menu-item>
4 </div>
 1  /*
2 props传递数据原则: 单向数据流,只允许父组件向子组件传递数据,不允许子组件直接操作props的数据
3 */
4 Vue.component('menu-item',{
5 props:['parr'],
6 template:`
7 <div>
8 <ul>
9 <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
10 </ul>
11 <button @click='parr.push("lemon")'>点击</button>
12 <button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button>
13 </div>
14 `
15 })
16 var vm = new Vue({
17 el:'#app',
18 data:{
19 pmsg:'父组件中内容',
20 parr:['apple','orange','banana'],
21 fontSize:10
22 },
23 methods: {
24 handle:function(){
25 // 扩大字体大小
26 this.fontSize += 5;
27 }
28 },
29 })
      
      3. 子组件通过自定义事件向父组件传递消息
        <button v-on:click='$emit("enlarge-text",0.1)'>扩大字体</button>
 
      4. 父组件监听子组件的事件
        <menu-item v-on:enlarge-text='fontSize += $event'></menu-item>
        $event是固定的
1 <div id="app">
2 <div :style='{fontSize:fontSize + "px"}'>{{pmsg}}</div>
3 <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item>
4 </div>
 1  Vue.component('menu-item',{
2 props:['parr'],
3 template:`
4 <div>
5 <ul>
6 <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
7 </ul>
8 <button @click='parr.push("lemon")'>点击</button>
9 <button @click='$emit("enlarge-text",5)'>扩大父组件中字体大小</button>
10 <button @click='$emit("enlarge-text",10)'>扩大父组件中字体大小</button>
11 </div>
12 `
13 })
14 var vm = new Vue({
15 el:'#app',
16 data:{
17 pmsg:'父组件中内容',
18 parr:['apple','orange','banana'],
19 fontSize:10
20 },
21 methods: {
22 handle:function(val){
23 // 扩大字体大小
24 this.fontSize += val;
25 }
26 },
27 })
 
 
    4.5 非父子组件间传值
      1. 单独的事件中心管理组件间的通信
        var eventHub = new Vue()
      2. 监听事件与销毁事件
        eventHub.$on('add-todo',addTodo)
        eventHub.$off('add-todo')
      3. 触发事件
        eventHub.$emit('add-todo',id)

   

1 <div id="app">
2 <div>父组件</div>
3 <div><button @click='handle'>销毁事件</button></div>
4 <test-tom></test-tom>
5 <test-jerry></test-jerry>
6 </div>
 1  // 提供事件中心
2 var hub = new Vue();
3
4 Vue.component('test-tom',{
5 data:function(){
6 return{
7 num:0
8 }
9 },
10 template:`
11 <div>
12 <div>TOM:{{num}}</div>
13 <div>
14 <button @click='handle'>点击</button>
15 </div>
16 </div>
17 `,
18 methods: {
19 handle:function(){
20 // 触发兄弟组件的事件
21 hub.$emit('jerry-event',2);
22 }
23 },
24 mounted:function(){
25 // 监听事件
26 hub.$on('tom-event',(val) =>{
27 this.num += val;
28 });
29 }
30 });
31 Vue.component('test-jerry',{
32 data:function(){
33 return{
34 num:0
35 }
36 },
37 template:`
38 <div>
39 <div>JERRY:{{num}}</div>
40 <div>
41 <button @click='handle'>点击</button>
42 </div>
43 </div>
44 `,
45 methods: {
46 handle:function(){
47 // 触发兄弟组件的事件
48 hub.$emit('tom-event',1);
49 }
50 },
51 mounted:function(){
52 // 监听事件
53 hub.$on('jerry-event',(val) =>{
54 this.num += val;
55 });
56 }
57 });
58
59 var vm = new Vue({
60 el:'#app',
61 data:{
62
63 },
64 methods: {
65 handle:function(){
66 hub.$off('tom-event');
67 hub.$off('jerry-event');
68 }
69 },
70 })
五、组件插槽
    5.1 组件插槽的作用
      父组件向子组件传递内容
      <alert-box>hi</alert-box> -> <slot></slot>
 
    

    5.2 组件插槽的基本用法
      1.插槽的位置
        Vue.component('alert-box',{
          template:`
            <div class="demo-alert-box">
            <strong>Error!</strong>
            <slot></slot>
            </div>
              `
        })
      2.插槽的位置
        <alert-box>Something bad happened</alert-box>       
1 <div id="app">
2 <alert-box>啦啦啦</alert-box>
3 <alert-box></alert-box>
4 </div>

    

 1 Vue.component('alert-box',{
2 template:`
3 <div>
4 <strong>ERROR:</strong>
5 <slot>默认内容</slot>
6 </div>
7 `
8 })
9 var vm = new Vue({
10 el:'#app',
11 data:{
12
13 }
14 })
    5.3 具名插槽用法
      1.插槽定义
      <div class="container">
        <header>
          <slot name="header"></slot>
        </header>
 
        <main>
          <slot></slot>
        </main>
 
        <footer>
          <slot name="footer"></slot>
        </footer>
      </div>
      2.插槽内容
        <base-layout>
          <h1 slot="header">标题内容</h1>
          <p>主要内容1</p>
          <p>主要内容2</p>
          <p slot="footer">底部内容</p>
        </base-layout>
 
    5.4 作用域插槽
      应用场景:父组件对子组件内容进行加工处理
 
六、基于组件的案例 - 购物车
    6.1 按照组件化的方式实现业务需求
      根据业务功能进行组件化划分
        (1) 标题组件 展示文本
        (2) 列表组件 列表展示、商品数量变更、商品删除
        (3) 结算组件 计算商品总额
      实现整体布局和样式效果
        划分独立的功能组件
        组合所有的子组件形成整体结构
        逐个实现各个组件功能
        标题组件
        列表组件
        结算组件
      

4.Vue组件的更多相关文章

  1. vue组件

    分享出来让思路更成熟. 首先组件是 Vue.js 最强大的功能之一. 可以减少很多的工作量,提高工作效率. 编写一个可复用性的组件,虽然官网上也有.... 编写可复用性的vue组件 具备一下的几个要求 ...

  2. vue组件的配置属性

    vue组件的声明语法: Vue.component('component-name',{ template:'<p>段落{{prop1}} {{prop2}}</p>', da ...

  3. vue组件,撸第一个

    实现此例您可以学到: vue-cli的基本应用 父组件如何向子组件传递值 单文件组件如何引入scss v-on和v-for的基础应用 源码下载 一.搭建vue开发环境 更换镜像到cnpmnpm ins ...

  4. vue组件最佳实践

    看了老外的一篇关于组件开发的建议(强烈建议阅读英文原版),感觉不错翻译一下加深理解. 这篇文章制定一个统一的规则来开发你的vue程序,以至于达到一下目的. 1.让开发者和开发团队更容易发现一些事情. ...

  5. JS组件系列——又一款MVVM组件:Vue(二:构建自己的Vue组件)

    前言:转眼距离上篇 JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查) 已有好几个月了,今天打算将它捡起来,发现好久不用,Vue相关技术点都生疏不少.经过这几个月的时间,Vue ...

  6. vue组件大集合 component

    vue组件分为全局组件.局部组件和父子组件,其中局部组件只能在el定义的范围内使用, 全局组件可以在随意地方使用,父子组件之间的传值问题等. Vue.extend 创建一个组件构造器 template ...

  7. 【Vue】详解Vue组件系统

    Vue渲染的两大基础方式 new 一个Vue的实例 这个我们一般会使用在挂载根节点这一初始化操作上: new Vue({ el: '#app' }) 注册组件并使用—— 全局注册 通过Vue.comp ...

  8. 关于vue组件的一个小结

    用vue进行开发到目前为止也有将近一年的时间了,在项目技术选型的时候隔壁组选 react的时候我们坚持使用vue作为前端的开发框架.虽然两者思想上的差异不大,但是vue的语法在代码的可读性以及后期的维 ...

  9. Vue组件基础用法

    前面的话 组件(Component)是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.根据项目需求,抽象出一些组件,每个组件里包含了展现.功能和样式.每个页面,根据自己所需, ...

  10. Vue组件模板形式实现对象数组数据循环为树形结构

    数据结构为数组中包含对象--树形结构,用Vue组件的写法实现以下的效果: 树形列表,缩进显示层级,第5级数据加底色,数据样式显色,点击展开折叠数据.本文为用Vue实现方式,另有一篇为用knockout ...

随机推荐

  1. Worksheet使用方法

    1  下载印象笔记: iPhone/iPad在App Store搜索"印象笔记"后下载 安卓在应用市场或在印象笔记官网yinxiang.com下载,图标同上 电脑可至印象笔记官网y ...

  2. Cplex-opl解决网络路由选择和资源分配问题

    安装Cplex 注意事项:全英文系统.安装路径.代码,会减少软件运行设置错误.(该软件对中文支持性不好) opl语言基础 [转载]CPLEX学习笔记二 – OPL的数据类型 - 知乎 (zhihu.c ...

  3. 说说Selenium的几个痛处

    Selenium挺好用,但也有几个不爽的地方: 1. 元素无法点击,因为scroll to element这一招时常不管用 2. 调试慢,一进入调试模式,PyCharm突然变慢, evaluate如同 ...

  4. 4.docker安装mysql

    下载mysql镜像 打开docker镜像仓库 https://hub.docker.com 我们下载官方镜像,点击打开 可以看到tags有很多不通版本的mysql 比如我想安装5.7版本的就可以使用  ...

  5. 8. C程序测试用数组个人技巧

    在测试程序的时候经常用到用于测试的数组. 这时,数组定义\声明时,最好不要填上元素个数. 当执行某种循环操作(例如将数组中的元素利用循环插入链表中时), 用sizeof(array_name)/siz ...

  6. python爬取知乎的网站内容

    #获取知乎的网站内容 import requests #数据请求模块 第三方模块 pip install requests import re #正则表达式 #网页head头 heads = { 'U ...

  7. VS2010运行opencv的程序,出现“应用程序无法正常启动0xc000007b”的解决方法

    问题描述 当我们在用vs2010对工程进行编译结束后,并且生成了可执行文件时,但是运用时却出现了"应用程序无法正常启动0xc000007b" 解决方法 这个通常是有一些动态链接库没 ...

  8. C# 屏蔽词过滤

    参考:https://www.cnblogs.com/kubidemanong/p/10834993.html public class TreeNode { public char Char; pu ...

  9. 29 Django自定义模板功能

    在相应的app文件夹中,创建templatetags文件夹,必须是templatetags文件夹命名: 注意:templatetags文件夹中必须要有__init__.py文件 jd.py: from ...

  10. JS中Promise

    Promise的作用: Promise是异步微任务,解决了异步多层嵌套回调的问题,让代码的可读性更高,更容易维护. Promise如何使用: Promise是ES6提供的一个构造函数,可以使用Prom ...