Vue入门(五)之组件
组件
- 1、组件的概念
- 2、组件的使用(定义,注册,和使用)
- 2.1、定义组件
- 2.2、注册组件
- 2.3、使用组件
- 2.4、组件编写方式与 Vue 实例的区别:
- 3、组件嵌套
- 4、组件的属性
- 4.1、使用 Prop 传递静态数据
- 4.2、使用 Prop 传递动态数据
- 4.3、Prop 验证
- 4.4、单向数据流
- 5、组件的事件
- 6、组件的内容(插槽)
- 6.1、单个插槽
- 6.2、具名插槽
- 6.3、编译作用域
- 7、组件(间)的通信
- 7.1、父子组件间的通信
- 7.2、兄弟组件/无关组件间的通信
- 8、动态组件
vue的基本语法已经差不多了,我们开始学习组件。
1、组件的概念
简单概括,组件就是自定义标签。
我们知道,vue框架的两大核心:数据驱动和组件化
组件封装的是完整的功能(包括:HTML、CSS、JS)
,而函数只封装JS(逻辑)
2、组件的使用(定义,注册,和使用)
2.1、定义组件
- 第一种
let 组件变量名= Vue.extend({template:'<div class="header">{{msg}},我是header组件</div>'data:function(){return {msg:”hi”}},
});
此处注意:
组件变量名不一定就是组件名;
template中引号的用法,使用单双引号时,只要换行就会报错,除非模板都写在一行,或者直接用es6模板字符串写法换行不报错,亲测有用哦;
data必须为函数,且有返回值。
自定义组件没有el项,切记。
第二种
let 组件变量名={配置项
};
//定义组件
let myZujian = {template:`<div><p>我是自定义组件{{meg}}</p></div>`,data:function(){return {meg:'真的是',}}
}
2.2、注册组件
只有经过注册的组件才能够使用
- 全局注册
Vue.component('组件名',组件变量名);
全局注册的组件,在任何vue对象里都可以使用
- 局部注册(用的较多)
//在vue对象的components选项里进行注册
new Vue({el:components:{组件名:组件变量名}
});
局部注册的组件,只能在当前vue对象(组件)里使用
//局部注册,只能在该vue对象使用
let vm = new Vue({el:'.box',data:{},//在components里注册components:{myZujian:myZujian,}})
2.3、使用组件
组件定义完了,也注册了,那怎么使用呢?
很简单,就像我们使用官方html标签一样使用就好了!
<组件名></组件名>
<!-- 组件名就是你注册时的组件名,不一定就是定义时的变量名哦 -->
<div class="box"><my-zujian></my-zujian>
</div>
2.4、组件编写方式与 Vue 实例的区别:
1、组件名不可和html官方的标签名同名,组件名如果是驼峰命名,那么使用时,用短横线连接,或者组件名首字母大写。
2、组件没有el选项,只有根实例存在el,组件里使用template定义模板
3、组件模板(html代码)只能有一个根标签
这里还有个问题:data为什么是个函数?
如果不是函数,那么,复用的组件的data共享同一块内存空间,数据会相互影响。
3、组件嵌套
把一个组件的标签写在另外一个组件的template里,就是组件嵌套。
//定义子组件1
let myCom1 = {template:`<p>我今年{{mes}}岁了</p>`,data:function(){return {mes:12}}
}//定义子组件2 组件2嵌套组件1
let myCom2 = {template:`<div>{{mee}}<my-com1></my-com1> </div>`,components:{myCom1,},data:function(){return {mee:'真的真的'}}
}
4、组件的属性
使用props(property的简写)声明组件的属性。 props是外部给组件传入的数据,而组件的data是组件内部的数据。
4.1、使用 Prop 传递静态数据
- 声明属性
props是个数组,可以声明多个属性
//定义子组件 let myCom1 = {//声明两个自定义属性props:['name','sex'],template:`<div><p>年龄:{{age}}</p><p>姓名:{{name}}</p><p>性别:{{sex}}</p></div>`,data:function(){return {age:18}}}
- 传入数据
<!-- 使用该自定义组件时,就可以传入数据了 -->
<div class="box">{{mes}}<my-com1 name="小芬" sex="23"></my-com1>
</div>
4.2、使用 Prop 传递动态数据
方法其实一样,就是传入数据的时候,将数据改成活的。
<!-- 使用v-bind -->
<div class="box">{{mes}}<my-com1 :name="name" :sex="sex"></my-com1>
</div>
let vm = new Vue({el:'.box',data:{mes:'原vue对象中的mes',name:'小芬',sex:'女',},//局部注册组件components:{myCom1,}
})
- 特殊情况:当传入的数据是一个对象的所有属性
<!-- 直接用v-bind="对象名" -->
<div class="box">{{mes}}<my-com1 v-bind="info"></my-com1>
</div>
let vm = new Vue({el: '.box',data: {info: {age: 21,name: '小芬',sex: '女',}},//局部注册组件components: {myCom1,}
})
- 还有特殊情况?
在 JavaScript 中对象和数组是通过引用传入的(传的是地址),所以对于一个数组或对象类型的 prop来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态(data),相当于函数的形参是引用类型。
4.3、Prop 验证
就是在声明属性的时候,对属性类型进行验证,注意:此时props是一个对象,而不是数组
//定义子组件
let myCom1 = {//prop验证props:{"name":{type:String,required:true,},"sex":{type:[String,Number]},"age":[Number]}, template: `<div><p>年龄:{{age}}</p><p>姓名:{{name}}</p><p>性别:{{sex}}</p></div>`,
}
4.4、单向数据流
Prop 是单向绑定的:当父组件的属性(数据)变化时,将传导给子组件,但是反过来不会。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。
- 让我们再加深一下props的理解:
在组件内部用props声明的属性,相当于封装函数时声明的形参。
使用组件时,相当于调用函数,传递实参。
5、组件的事件
1、绑定事件: HTML(标签)里的绑定方式:v-onJS(Vue)里绑定方式: vue对象.$on(“事件名”)2、触发事件 : vue对象.$emit(“事件名”,参数);
我们在使用html官方标签绑定事件时,触发事件功能官方帮我们做好了,但是我们自定义组件(标签)时,需要自己去做触发事件的功能。
我们先看一段实例代码:
<div class="box"><my-com1 @myclick="fn"></my-com1>
</div>
//定义子组件
let myCom1 = {template: `<input type="button" @click="add" value="点击加1"/>`,data:function(){return {mes:17}},methods:{add(){//触发事件,自定义标签的触发事件,// 也可以传递参数给父组件this.$emit('myclick','我是子组件的人');}}}let vm = new Vue({el: '.box',data: {},//局部注册组件components: {myCom1,},methods:{fn(str){console.log('从子组件传来的数据:',str);}}
})
步骤分析:
- 子组件myCom1模板里调用触发事件函数add;
- 使用该组件时,调用事件处理函数fn
6、组件的内容(插槽)
组件的内容就是标签的innerHTML。vueJS里使用Slot(插槽)
分发内容。
将父组件的内容(DOM)放到子组件指定的位置叫作内容分发
。
props
用来处理标签的属性 ,slot
用来处理标签的内容。
6.1、单个插槽
子组件中插入一条父组件内容
<slot></slot>
<div class="box"><my-com1><p>我在子组件里面</p></my-com1>
</div>
//定义子组件 let myCom1 = {template: `<div><div>我是子组件,并附带{{mes}}</div><slot></slot></div>`,data:function(){return {mes:17}},}let vm = new Vue({el: '.box',data: {},//局部注册组件components: {myCom1,}})
6.2、具名插槽
父级给子级传来了多个DOM(HTML元素),而且需要把不同的DOM放在子组件不同位置时,就需要给slot起名字,这就是具名插槽
。
slot元素可以用一个特殊的属性name 来配置如何分发内容。
<slot name="插槽名"></slot>
<div class="box"><my-com1><p slot="p3">我在子组件里面1</p><p slot="p2">我在子组件里面2</p><p slot="p1">我在子组件里面3</p></my-com1>
</div>
//定义子组件 let myCom1 = {template: `<div><slot name="p1"></slot><div>我是子组件,并附带{{mes}}</div><slot name="p2"></slot><slot name="p3"></slot></div> `,data:function(){return {mes:17}},}
6.3、编译作用域
即 父组件模板的内容在父组件作用域内(父组件对应的对象的作用域)编译;子组件模板的内容在子组件作用域内编译。
有兴趣可以点击插槽作用域
7、组件(间)的通信
vue组件之间的通信(传递数据)是必然的,根据vue组件之间的关系不同(父子,兄弟,或者无关组件),方法也不同。
7.1、父子组件间的通信
父—> 子: props, 子—> 父:事件
这个其实我们前面也用到过,组件事件里讲过子组件触发事件时可以带参传给父组件,达到父子组件的通信。
父---->子:refs
父传子也可以使用refs
什么是refs,可以理解为给组件一个id名,通过这个id值获取DOM,也就是标签,也即组件对象,从而操作组件对象里的属性。
refs—>dom----->组件对象----->操作组件对象的属性
如果某个元素使用ref属性,那么,在vue对象里,就能用this.$refs 访问。
//基本格式<p ref = "pId"> {{msg}}</p>methods:{testf:function(){this.$refs.pId.innerHTML = "hi";}
}
<div class="box"><input type="button" value="点击加1" @click="add"><my-com1 ref="mcon"><p slot="p2">{{mes}}</p></my-com1>
</div>
//定义子组件 let myCom1 = {template: `<div><div>我是子组件,并附带{{mes}}</div><slot name="p2"></slot></div> `,data:function(){return {mes:17}},}let vm = new Vue({el: '.box',data: {mes:22},//局部注册组件components: {myCom1,},methods:{add(){this.mes++;//获取子组件对象,改变子组件mes的值this.$refs.mcon.mes ++;}}})
7.2、兄弟组件/无关组件间的通信
事件总线(event-bus)
event-bus实质就是创建一个vue实例,通过一个空的vue实例作为桥梁实现vue组件间的通信。它是实现兄弟组件(或者任何无关组件,也可以实现父子)通信的一种解决方案。
基本步骤:
1、单独new一个Vue空对象: let bus= new Vue();
2、在组件A里,绑定一个自定义事件(相当于定义了一个自定义事件):bus.$on('eclick',target => {console.log(target) })
3、在组件B里,触发事件bus.$emit('eclick',"b传给a的");
实例代码:
<div class="box"><my-com1></my-com1><my-com2></my-com2>
</div>
//定义子组件1 let myCom1 = {template: `<input type="button" value="点击触发" @click="add"/> `,data(){return {mes:40}},methods:{add(){vm2.$emit('click',this.mes)}}}//子组件2let myCom2 = {template:`<p>我是子组件二,附带{{mes2}}</p>`,data:function(){return {mes2:20}},created(){// created函数是,组件自动调用的vm2.$on('click',(str)=>{// console.log(str);this.mes2 = str;}) }}//单独new一个空的Vue对象 绑定事件一方为接收方 ,触发事件为发送方let vm2 = new Vue({})let vm = new Vue({el: '.box',data: {mes:22},//局部注册子组件components: {myCom1,myCom2},})
集中管理($root)
把数据存到根实例的data选项,其他组件直接修改或者使用
基本格式:
//根组件内定义
new Vue({data:{a:1}
})//子组件内部使用
this // 子组件本身
this.$root // vm 根实例
this.xx //组件内部数据
this.$root.a //根实例数据
实例代码:
//定义子组件1 let myCom1 = {template: `<input type="button" value="点击触发1" @click="add"/> `,data(){return {mes:'我是子组件1数据'}},methods:{add(){//修改根组件数据this.$root.mes = this.mes;}}}//子组件2let myCom2 = {template:`<input type="button" value="点击触发2" @click="add"/> `,data:function(){return {mes2:'我是子组件2数据'}},methods:{add(){//修改根组件数据this.$root.mes = this.mes2;}}}let vm = new Vue({el: '.box',data: {mes:'我是根组件数据',},//局部注册子组件components: {myCom1,myCom2},})
8、动态组件
有的时候,在不同组件之间进行动态切换是非常有用的。即页面的某个位置要显示的组件是不确定的,是会变化的。
<component :is="组件名变量">
实例代码:选项卡
<div id="box"><button @click="fn(0)">娱乐新闻</button><button @click="fn(1)">体育新闻</button><button @click="fn(2)">天文新闻</button><div><component :is="currCom"></component></div>
</div>
//选项卡功能
let news1 = {template: "<div>娱乐新闻</div>"
}
let news2 = {template: "<div>八卦新闻</div>"
}
let news3 = {template: "<div>体育新闻</div>"
}new Vue({el: "#box",data: {currCom: "news1",coms: ["news1", "news2", "news3"]},methods: {fn(index) {this.currCom = this.coms[index];}},components: {news1, news2, news3}
});
花了一早上才写完,心塞!
Vue入门(五)之组件相关推荐
- vue入门:(组件)
模板:(template)模板声明了数据和最终展现给用户的DOM之间的映射关系. 初始数据:(data)一个组件的初始数据状态.对于可复用的组件来说,通常是私有的状态. 接收外部参数:(props)组 ...
- Vue (十五) --------- UI 组件库
目录 一.移动端常用 UI 组件库 1. Vant 2. Vux 3. Cube UI 4. Mint UI 二.PC 端常用 UI 组件库 1. Element UI 2. IView UI 3. ...
- 前端Vue入门-day04-用vue实现组件通信
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 组件的三大组成部分 注意点说明 组件的样式冲突 scoped data 是一个函数 组件通信 什么是组 ...
- Vue入门教程 第五篇 (组件)
component(组件) vue是单页面web程序,这意味着需要大量模块化界面参与其中,这就是组件. 组件是一个实现单一功能的vue界面,也可以是一个以功能划分而成的复杂vue界面. 注册组件: V ...
- Vue.js——60分钟组件快速入门(上篇)
组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢? 组件可以扩展HTM ...
- 从“心”认识Vue(五):父组件与子组件
从"心"认识Vue(五):父组件与子组件 前言 一.父组件与子组件的关系 二.注册组件语法糖 三.模板与组件的分离写法 四.组件可以访问vue实例数据吗? 五.为什么组件的data ...
- vue使用ts 引入组件_vue项目中使用ts(typescript)入门教程
最近项目需要将原vue项目结合ts的使用进行改造,这个后面应该是中大型项目的发展趋势,看到一篇不错的入门教程,结合它并进行了一点拓展记录之.本文从安装到vue组件编写进行了说明,适合入门. 1.引入T ...
- Vue入门之组件化开发
Vue入门之组件化开发 http://www.jianshu.com/p/6718ab1caa81 组件其实就是一个拥有样式.动画.js逻辑.HTML结构的综合块.前端组件化确实让大的前端团队更高效的 ...
- Vue.js——60分钟组件快速入门(下篇)
概述 上一篇我们重点介绍了组件的创建.注册和使用,熟练这几个步骤将有助于深入组件的开发.另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:"嘿,老哥,我开 ...
最新文章
- linux文件每行长度,linux – 根据第一列/行中的字符长度对文件进行排序
- ReactNative生成android平台的bundle文件命令
- rabbitmq 连接报错 An unexpected connection driver error occured(亲测)
- 生成对抗网络 : LSGAN, WGAN, CGAN, infoGAN, EBGAN, BEGAN, VAE
- python登录豆瓣_python登录豆瓣,发帖
- math.trunc_带有Python示例的math.trunc()方法
- android小程序下线,关闭小程序
- 用代码证明自己闲的蛋疼(四)——简易坑爹版学生管理系统
- MooTools官方插件 - Chain.Wait
- 在IntelliJ IDEA配置Tomcat
- Git的下载安装教程
- Logback设置property参数
- Jupyter Notebook 更改默认浏览器
- 机器学习常见模型英文介绍
- 华为nova5iotg功能使用_华为Nova2怎么使用OTG功能教程
- layui tpl中的if(){}else{}
- 数据科学家的一天,是怎样度过的?
- yo generator 强制更新文件
- 土地利用覆被变化的概念_土地利用/覆被变化(LUCC)研究现状与展望
- 奥塔在线:架构实践基础之一图胜千言
热门文章
- python 乡镇轮廓 高德_基于高德地图api和Python的区县地理边界坐标提取
- 软件 黑苹果盒盖不休眠_MacBook Pro macOS合上盖子不休眠的问题及解决办法
- Mac 合盖保持唤醒
- android training英文,English Pronunciation Training
- 中小学生相关计算机课程,中小学生计算机教学计划
- 华夏名网Discuz虚拟主机论坛空间推荐
- 分享两个免费的图片资源网站
- 那些应微信而生的商业机会
- 校园无线网条件下 实现正点原子stm32mp157教程中虚拟机、FTP、uboot的网络连接
- 铁路信号灯,白灯代表什么?