7.1 组件作用:

提高代码复用性,使项目易于维护

7.1 组件的使用

7.1.1 组件注册-全局注册

全局注册后,任何vue的实例都可以使用该组件.
Vue.component('my-component',{})my-component就是自定义组件的名称,推荐使用小写加减号的方式来命名.
要在父元素中使用组件,必须在父元素实例初始化之前注册组件Vue.component('my-component', {template: '<div>这是my-component的内容!!</div>'
})
var app = new Vue({el: '#app',data: {}
})
=================================================
<div id="app"><my-component></my-component>
</div>

7.1.2 组价注册-局部注册

var Child = {template: '<div>这里是组件内容!!</div>'
}
var app = new Vue({el: '#app',data: {},components: {'my-component': Child}
})
==============================================
<div id="app"><my-component></my-component>
</div>

7.2 使用props传递数据

7.2.1 props的基本用法

组件不仅仅是对模板的内容进行复用,更重要的是要进行模板之间的通信

正向传递数据

父组件的模板包含子组件,父组件要想子组件正向的传递数据或参数,
子组件解收到后根据参数的不同来渲染不同的内容或执行操作.

props值的分类

1.数组
2.对象

props命名规则:在使用DOM模板时:使用CamelCase(驼峰命名)的props名称要使用kebab-case:

例:

<div id="app"><my-component warning-text="提示信息!"></my-component>
</div>
========================================================================
<script>Vue.component('my-component',{props:['warningText'],template:'<div>{{warningText}}</div>'})var app = new Vue({el:'#app'})
</script>

props作为需要被转变的原始值传入,在这种情况下使用计算属性.

例:

Vue.component('my-component',{props:['width'],template:'<div :style="style">组件内容</div>',computed:{style:function(){return {width:this.width+'px'}}}
})

7.2.2 prop数据的验证

例:   Vue.component('my-component',{props:{//必须是数字propA:Number,//必须是数字或字符串propB:[String,Number],//布尔值,如果没有定义,默认值是truepropC:{type:Boolean,default:true},//数字,并且必须是必传propD:{type:Number,required:true},//如果是数组或对象,默认值必须是一个而函数来返回propE:{type:Array,default:function(){return []}},//自定义一个验证函数propF:{validator:function(value){return value>10}}},template:'<div>{{propA}}:{{propD}}</div>'})

验证的type类型

  • String
  • Number
  • Boolean
  • Object
  • Array
  • Function

7.3 组件通信

* 7.3.1 父子组件通信

**自定义事件**<div id="app"><p>总数:{{total}}</p><my-component @increase="handleGetTotal" @reduce="handleGetTotal"></my-component></div>======================================================================================Vue.component('my-component',{template:`<div><button @click="handleIncrease">+1</button><button @click="handleReduce">-1</button></div>`,data:function(){return{counter:0}},methods:{handleIncrease:function(){this.counter++this.$emit('increase',this.counter)},handleReduce:function(){this.counter--this.$emit('reduce',this.counter)}}})var app = new Vue({el:'#app',data:{total:0},methods:{handleGetTotal:function(total){this.total=total}}})

使用v-model

<div id="app"><p>总数:{{total}}</p><my-component v-model="total"></my-component></div>
==========================================================
Vue.component('my-component',{template:'<button @click="handleClick">+1</button>',data:function(){return{counter:0}},methods:{handleClick:function(){this.counter++this.$emit('input',this.counter)}}})var app = new Vue({el:'#app',data:{total:0}})

使用v-model自定义双向绑定组件

<div id="app"><p>总数:{{total}}</p><my-component v-model="total"></my-component><button type="button" @click="handleReduce">-1</button></div>
==============================================================
Vue.component('my-component',{props:['value'],template:'<input :value="value" @input="updateValue"></input>',methods:{updateValue:function(event){this.$emit('input',event.target.value)}}})var app = new Vue({el:'#app',data:{total:0},methods:{handleReduce:function(){this.total--}}})

实现一个具有双向数据绑定的v-model组件要满足的要求

 * 接收一个value属性* 有新的value时触发input事件

* 7.3.2 非父子间组件通信(兄弟组件之间通信,跨级组件之间通信)

  • 1.中央事件总线(bus)
  • 2.父链
**定义:** 在子组件中,使用this.$parent可以直接访问该组件的父实例或组件,父组件也可以通过this.$children访问他所有的子组件,而且可以递归或向下无线访问,知道根实例或最内层组件**例:**  Vue.component('my-component',{template:'<button @click="handleChange">通过父链修改父组件数据</b1utton>',methods:{handleChange:function(){this.$parent.message="来自子组件的数据"}}         })var app = new Vue({el:'#app',data:{message:''}
})
  • 3.子组件索引
>> **示例**    <div id="app"><button @click="handleRef">通过ref获取子组件实例</button><my-component ref="comA"></my-component></div>===========================================================Vue.component('my-component',{template:'<div>子组件</div>',data:function(){return{message:'自组件内容'}}})var app = new Vue({el:'#app',methods:{handleRef:function(){//通过ref来获取指定ref实例var msg = this.$refs.comA.messageconsole.log(msg)}}})

7.4 使用slot分发内容

7.4.1 什么是slot

可以在组件中插入内容
组件的3个API来源:props传递数据、event出发事件、slot分发内容
内容分发:当需要组件混合使用时,混合父组件的内容与子组件的模板时,就会用到slot

7.4.2 什么是编译作用域

7.4.3 作用域的用法

* 单个slot

示例

<div id="app"><child-component><p>分发的内容</p></child-component></div>======================================Vue.component('child-component',{template:`<div><slot>子组件默认显示的内容</slot></div>`})var  app = new Vue({el:'#app'})
* 具名插槽

示例

<div id="app"><child-component><p slot="header">我是头部</p><p>默认插槽</p><p slot="footer">我是尾部插槽</p></child-component></div>================================================Vue.component('child-component',{template:`<div><div class="header"><slot name="header"></slot></div><div><slot></slot></div><div class="footer"><slot name="footer"></slot></div></div>`})var app =  new Vue({el:'#app'})

7.4.4 作用域插槽

示例

<div id="app"><child-component><template scope="props"><p>来自父组件的内容</p><p>{{props.msg}}</p></template></child-component>
</div>==========================================================Vue.component('child-component',{template:`<div><slot msg="来自子组件的内容"></slot></div>`})var app = new Vue({el:'#app'})

示例2

<div id="app"><my-list :books="books"><template slot="book" slot-scope="props">                    <li>{{props.bookName}}</li></template></my-list><ul><li v-for="book in books">{{book.name}}</li></ul></div>==========================================================Vue.component('my-list',{props:{books:{type:Array,default:function(){return []}}},template:`<ul><slot name="book" v-for="book in books" :book-name="book.name"></slot></ul>`})var app = new Vue({el:'#app',data:{books:[{name:'《Vue.js实战》'},{name:'《JavaScript语言精粹》'},{name:'《JavaScript高级程序设计》'}]}})

7.4.5 访问slot

被分发的内容使用$slot来访问

<div id="app"><my-component><h2 slot="header">标题</h2><p>主体内容</p><p>更多主体内容</p><div slot="footer">底部信息</div></my-component></div>==========================================================================Vue.component('my-component',{template:`<div class="container"><div class="header"><slot name="header"></slot></div><div class = "main"><slot></slot></div><div class = "footer"><slot name = "footer"></slot></div></div>`,           mounted:function(){var header = this.$slots.headervar main = this.$slots.defaultvar footer = this.$slots.footerconsole.log(main)console.log(header)console.log(footer)console.log(footer[0].elm.innerHTML)}          })var app = new Vue({el:'#app',})

7.5 组件的高级用法

7.5.1 递归组件 (组件可以在它的模板内递归的调用自己)

示例

<div id="app"><child-component :count="1"></child-component></div>===================================================================Vue.component('child-component',{name:'child-component',props:{count:{type:Number,default:1}},template:`<div class="child"><child-component :count="count+1" v-if="count<3"></child-component></div>`})var app = new Vue({el:'#app',data:{}})

使用场景:级联菜单,树形控件

7.5.2 内联模板

示例

<div id="app"><child-component inline-template><div><h2>在父组件中定义子组件的模板</h2><p>{{m}}</p><p>{{msg}}</p></div></child-component>            </div>====================================================================Vue.component('child-component',{data:function(){return{msg:'在子组件中声明的数据'                    }}})var app = new Vue({el:'#app',data:{m:'在父组件中声明的数据'}})

子组件和父组件中声明的数据都可以渲染,个人环境中只能渲染子组件的数据而不能渲染父组件的数据

7.5.3 动态组件

使用<component>元素来动态的挂载不同的组件

示例

<div id="app"><component :is="currentView"></component><button @click="handleChangeView('A')">切换到A</button><button @click="handleChangeView('B')">切换到B</button><button @click="handleChangeView('C')">切换到C</button></div>==========================================================================================var app = new Vue({el:'#app',components:{comA:{template:'<div>组件A</div>'},comB:{template:'<div>组件B</div>'},comC:{template:'<div>组件C</div>'}},data:{currentView:'comA'},methods:{handleChangeView:function(component){this.currentView='com'+component}}})

7.5.4 异步组件

vue观察到数据变化时并不是直接更新DOM,而是开启一个队列,并缓冲在同一事件循环中发生的所有数据改变.在缓冲时会去除重复的数据,从而避免不必要的计算和DOM操作,然后在下一个事件循环tick中,Vue刷新队列并执行实际(已经去重)工作,

示例

<div id="app"><child-component></child-component></div>=======================================================================Vue.component('child-component',function(resolve,reject){window.setTimeout(function(){resolve({template:'<div>我是异步加载的</div>'})},2000)})var app = new Vue({el:'#app'})

7.6 其他

7.6.1 $nextTick

需求场景

有一个div默认为用v-if将其隐藏,当点击按钮时,将v-if的值修改为true显示div,同时获取div中的文本内容

模板代码

<div id="app"><div id="test" v-if="showDiv">这是一段文本</div><button @click="getText">获取文本</button></div>

错误js代码

var app = new Vue({el:'#app',data:{showDiv:false},methods:{getText:function(){this.showDiv=truevar text = document.getElementById('test').innerHTMLconsole.log(text)       }}         })

正确JS代码

var app = new Vue({el:'#app',data:{showDiv:false},methods:{getText:function(){this.showDiv=true              this.$nextTick(function(){var text = document.getElementById('test').innerHTMLconsole.log(text)})}}          })

7.6.2 x-tamplates

示例

<div id="app"><my-component></my-component><script type="text/x-template" id="my-component"><div>这是组件的内容</div></script></div>===========================================================================Vue.component('my-component',{template:'#my-component'})var app = new Vue({el:'#app',})

7.6.3 手动挂载实例

示例

<div id="mount-div"></div>========================================var MyComponent = Vue.extend({template:'<div>Hello:{{name}}</div>',data:function(){return{name:'Aresn'}}});new MyComponent().$mount('#mount-div')

《Vue.js实战》第七章.组件相关推荐

  1. vue.js实战——购物车练习(包含全选功能)

    vue.js实战第5章 54页的练习1 直接放代码好了,全选的部分搞了好久,代码好像有点啰嗦,好在实现功能了(*^▽^*) HTML: <!DOCTYPE html> <html l ...

  2. Vue.js实战之系统学习第七节

    想看上一节的请点击: Vue.js实战之系统学习第六节 接下来我们要学习第七节了,时间过的好快. 组件详解 组件是Vue.js的核心功能,也是整个框架设计最精彩的地方,当然也是最难掌握的.本章节将带你 ...

  3. Vue.js实战——封装长按能量条火箭发射动画组件_17

    一.目标 按照项目需求,需要完成如下几部分的功能: 1.长按屏幕时,显示能量条动画(类似环形进度条): 2.当能量条充满时,发射小火箭: 二.实现效果 三.步骤 按照需求分析,上述目标可以拆解成3个功 ...

  4. js 查错_7年前端开发经验的我,写了本Vue.js实战开发,开源高清PDF下载

    Vue作为目前发展最迅速的前端框架越来越多的受到前端T程师青睐,Vue社区也是Web前端最活跃的社区之一. 更多的公司在转为Vue框架,但针对Vue优秀权威.实战的图书相对欠缺,梁灏著<Vue. ...

  5. [Vue.js] 一篇超级长的笔记,给《Vue.js 实战》划个重点

    本文前言 本笔记建立在书籍<Vue.js实战 / 梁灏编著>的基础上,旨在帮助有 Vue.js 基础的朋友快速回忆 Vue.js 的细碎内容.初学者建议阅读<Vue.js实战> ...

  6. 2018最新vue.js实战项目:美团外卖平台

    vue.js实战项目:美团外卖平台 第1章 课程简介 1-1 课程简介 1-2 课程安排 第2章 Vue.js介绍 2-1 Vuejs介绍-近年来前端开发趋势 2-2 Vuejs介绍-MVVM框架 2 ...

  7. 美团外卖平台vue.js实战项目(完整)

    vue.js实战项目:美团外卖平台 第1章 课程简介 1-1 课程简介 1-2 课程安排 第2章 Vue.js介绍 2-1 Vuejs介绍-近年来前端开发趋势 2-2 Vuejs介绍-MVVM框架 2 ...

  8. axios vue 动态date_Web前端Vue系列之-Vue.js 实战

    课程简介: 课程目标:通过本课程的学习,让大家掌握Vue.js的进阶知识并在项目中应用. 适用人群:具有一定vue开发基础的开发人员. 课程概述:Vue (读音 /vjuː/,类似于 view) 是一 ...

  9. 3.Vue.js 实战 调查问卷WebApp项目

    问卷调查demo已上传,欢迎大家指正,欢迎大家下载:https://download.csdn.net/download/lzb348110175/11085995 如果您没积分的话,可以私信/评论, ...

最新文章

  1. 获取保存在沙盒中plist文件的用户的字典信息
  2. 2012级计算机应用基础,2012年计算机应用基础
  3. .net webapi 接收参数_FastReport.Net报表设计器如何连接到SQLCe
  4. 纯 CSS 实现三角形尖角箭头的实例
  5. 汇编语言 利用栈 将数据逆序存放
  6. [转载] Scala继承与Java的区别
  7. jquery radio设置选中_前端jQuery实战之 attr() 和 prop() 的区别
  8. Eclipse主题插件之DevStyle
  9. 人工智能之语音识别概述(一)
  10. 阵处理与波束形成学习心得(二)
  11. C#panel渐变绘制
  12. 是时候重估“返利网”的市场价值了
  13. STC开天斧虚拟示波器使用
  14. Most of the disks failed
  15. css Flex布局第一部分(基础)
  16. 【入门】QQ聊天机器人--HelloWorld篇
  17. pixi 平铺精灵 demo (一)
  18. 如何锁定win10笔记本键盘
  19. python3 陌生的角落(1):基础语法
  20. vue如何引入外部js文件,待解决,急!!!

热门文章

  1. 中国首枚NFC邮票发行背后,NFC技术的“有限性”创新
  2. 中职计算机专业英语说课稿,中职英语说课稿范文
  3. 三、T100应付管理之采购应付-入库应付管理篇
  4. echarts 自定义legend 初始化为灰色
  5. 惊艳的产品背后,是锐利的设计思维
  6. 云帆教育大数据分享-Flume-0.9.4源码编译及一些编译出错解决方法
  7. 理财入门:财务报表(简单介绍,后续入门系列文章写完后,会写实践文章在详细介绍)
  8. java 查看对象内存占用大小
  9. 换IP软件能否实现定时切换IP?一起来验证
  10. 软件系统的标准化和产品化