组件

  • 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);}}
})

步骤分析:

  1. 子组件myCom1模板里调用触发事件函数add;
  2. 使用该组件时,调用事件处理函数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入门(五)之组件相关推荐

  1. vue入门:(组件)

    模板:(template)模板声明了数据和最终展现给用户的DOM之间的映射关系. 初始数据:(data)一个组件的初始数据状态.对于可复用的组件来说,通常是私有的状态. 接收外部参数:(props)组 ...

  2. Vue (十五) --------- UI 组件库

    目录 一.移动端常用 UI 组件库 1. Vant 2. Vux 3. Cube UI 4. Mint UI 二.PC 端常用 UI 组件库 1. Element UI 2. IView UI 3. ...

  3. 前端Vue入门-day04-用vue实现组件通信

    (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 组件的三大组成部分 注意点说明 组件的样式冲突 scoped data 是一个函数 组件通信 什么是组 ...

  4. Vue入门教程 第五篇 (组件)

    component(组件) vue是单页面web程序,这意味着需要大量模块化界面参与其中,这就是组件. 组件是一个实现单一功能的vue界面,也可以是一个以功能划分而成的复杂vue界面. 注册组件: V ...

  5. Vue.js——60分钟组件快速入门(上篇)

    组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢? 组件可以扩展HTM ...

  6. 从“心”认识Vue(五):父组件与子组件

    从"心"认识Vue(五):父组件与子组件 前言 一.父组件与子组件的关系 二.注册组件语法糖 三.模板与组件的分离写法 四.组件可以访问vue实例数据吗? 五.为什么组件的data ...

  7. vue使用ts 引入组件_vue项目中使用ts(typescript)入门教程

    最近项目需要将原vue项目结合ts的使用进行改造,这个后面应该是中大型项目的发展趋势,看到一篇不错的入门教程,结合它并进行了一点拓展记录之.本文从安装到vue组件编写进行了说明,适合入门. 1.引入T ...

  8. Vue入门之组件化开发

    Vue入门之组件化开发 http://www.jianshu.com/p/6718ab1caa81 组件其实就是一个拥有样式.动画.js逻辑.HTML结构的综合块.前端组件化确实让大的前端团队更高效的 ...

  9. Vue.js——60分钟组件快速入门(下篇)

    概述 上一篇我们重点介绍了组件的创建.注册和使用,熟练这几个步骤将有助于深入组件的开发.另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:"嘿,老哥,我开 ...

最新文章

  1. linux文件每行长度,linux – 根据第一列/行中的字符长度对文件进行排序
  2. ReactNative生成android平台的bundle文件命令
  3. rabbitmq 连接报错 An unexpected connection driver error occured(亲测)
  4. 生成对抗网络 : LSGAN, WGAN, CGAN, infoGAN, EBGAN, BEGAN, VAE
  5. python登录豆瓣_python登录豆瓣,发帖
  6. math.trunc_带有Python示例的math.trunc()方法
  7. android小程序下线,关闭小程序
  8. 用代码证明自己闲的蛋疼(四)——简易坑爹版学生管理系统
  9. MooTools官方插件 - Chain.Wait
  10. 在IntelliJ IDEA配置Tomcat
  11. Git的下载安装教程
  12. Logback设置property参数
  13. Jupyter Notebook 更改默认浏览器
  14. 机器学习常见模型英文介绍
  15. 华为nova5iotg功能使用_华为Nova2怎么使用OTG功能教程
  16. layui tpl中的if(){}else{}
  17. 数据科学家的一天,是怎样度过的?
  18. yo generator 强制更新文件
  19. 土地利用覆被变化的概念_土地利用/覆被变化(LUCC)研究现状与展望
  20. 奥塔在线:架构实践基础之一图胜千言

热门文章

  1. python 乡镇轮廓 高德_基于高德地图api和Python的区县地理边界坐标提取
  2. 软件 黑苹果盒盖不休眠_MacBook Pro macOS合上盖子不休眠的问题及解决办法
  3. Mac 合盖保持唤醒
  4. android training英文,English Pronunciation Training
  5. 中小学生相关计算机课程,中小学生计算机教学计划
  6. 华夏名网Discuz虚拟主机论坛空间推荐
  7. 分享两个免费的图片资源网站
  8. 那些应微信而生的商业机会
  9. 校园无线网条件下 实现正点原子stm32mp157教程中虚拟机、FTP、uboot的网络连接
  10. 铁路信号灯,白灯代表什么?