一、组件化开发概述
  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. https代理服务器(四)java动态签发【失败】

    https://zhuanlan.zhihu.com/p/355241710?utm_id=0 http://t.zoukankan.com/xiaxj-p-8961131.html https:// ...

  2. HarmonyOS基础

    目录 自适应布局 自适应拉伸布局 自适应缩放 自适应延伸 组件多态 ArkUI开发框架 基础组件 Text组件和Span组件 参考 参考:harmonyos3: 鸿蒙ArkUI eTS教程配套源码 参 ...

  3. JavaScript逗号运算符的用法

    var a = 3, b b = (a++, a) 与 var a = 3, b b = a++ 区别

  4. 【翻译】了解Flink-数据管道和ETL -- Learn Flink - Data Pipelines & ETL

    目录 无状态转换 map() flatmap() keyed 流 keyBy() keys计算 keyed流上的聚合 (Implicit)状态 reduce() 和其他聚合器 有状态的Transfor ...

  5. SDCC 学习

    单个led.c文件 #include <stdbool.h> __sfr __at(0xb0) P3; __sfr __at(0x88) TCON; __sfr __at(0x89) TM ...

  6. fiddler抓包返回304

    为了验证部分场景需要对接口返回数据进行修改后验证前端代码逻辑处理,发现同一域名下其他接口都正常返回,但是某个端口返回304. 操作步骤是页面打开后接口已经请求了,这时候才打开fiddler抓取请求拦截 ...

  7. (jmeter笔记)jmeter导出excel,中文显示乱码

    导出excel显示乱码 解决方法:http请求--Content encoding写utf-8 导出如下:

  8. mybatis纵览

    Mybatis MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作. MyBatis 可 ...

  9. memoのls

    memoのls 测试环境是Big Sur 11.2.2 在windows下都不知道cd /D E:\xxx\xxx可以直接切换盘符.今天才发现,ls命令我也不会用-- ls命令是真强大啊,之前只知道l ...

  10. 莫凡PYthon之keras 1

    莫凡PYthon 1 kearsregressionpython Regressor 回归 用神经网络去拟合数据. 主要代码 """ Regressor 回归 " ...