写点什么

3 个概念,入门 Vue 组件开发

  • 2019-04-01
  • 本文字数:6007 字

    阅读完需:约 20 分钟

3个概念,入门 Vue 组件开发

“组件”是 Vue 中比较基础的概念,但我发现,许多同学对 Vue 组件的概念和由来并不是清楚。因此,我希望通过这个专题,带大家换个角度来分析,最终让大家更清楚组件开发。


首先,我们先不谈组件,我想问大家一个问题:


我们平常用任何编程语言写方法(method)的时候,当一个方法里的逻辑过多时,我们会怎么办?当多个方法里有很多相似的逻辑时,我们该怎么办?


答案很明了:拆分成一个独立的方法。


如果拆分后还是有类似问题呢?那就继续拆分。


类比一下,HTML 也一样。当我们写了一大堆的 HTML 后,发现有不少类似或重复的地方,我们也可以按照拆分的方法,拆分 HTML。除了拆分 HTML 之外,我们还可以拆分针对这段 HTML 书写的逻辑,甚至是样式。拆分后的 HTML,逻辑,样式组合在一起,我们就称之为组件。


这么讲似乎有点抽象,我们来举个例子吧。假如我们要做一个简单的 TodoList 项目,代码如下:


<ul>​    <li>​      <input type="checkbox">​      <span>学习 Vue 属性</span>​      <button>删除</button>​    </li>​    <li>​      <input type="checkbox">​      <span>学习 Vue 事件</span>​      <button>删除</button>​    </li>​    <li>​      <input type="checkbox">​      <span>学习 Vue 插槽</span>​      <button>删除</button>​    </li>  </ul></div>
复制代码


可以看到,我们 li 标签内的内容越来越多,似乎可以把它独立出来,在 Vue 中,通过以下代码就可以将这部分代码独立出来.


通过 Vue.component 定义(注册)一个组件,起名为 todo-item, 组件的 HTML 写在 template 字段上:


Vue.component('todo-item', {  template: `<li>​      <input type="checkbox">​      <span>学习 Vue 属性</span>​      <button>删除</button>​    </li>`})
复制代码


然后,你可以通过下面这样的方式来使用这个组件:


  <ul>​    <todo-item></todo-item>​    <todo-item></todo-item>​    <todo-item></todo-item>  </ul></div>
复制代码


当然前提条件是你要先 new Vue 一个实例,并添加挂载点


new Vue({  el: '#app'  // 提供一个挂载点,这样我们就可以在里面使用 todo-item 了})
复制代码


这样一来清爽了许多,可是这样就变成三个“学习 Vue 属性” 事项了,我们还缺“学习 Vue 事件”和“学习 Vue 插槽” ,怎么办呢,这就要用到 Vue 的属性了。


点击此处,开始你的第一个 Vue 程序


点击此处,了解单文件组件

属性

我们接着改改,调用方法时,可以传递不同的参数,方法也可以接收参数,执行不同的逻辑,加载组件时同样也可以传递不同的参数(属性),组件也可以接收参数(属性)来显示不同的内容:


Vue.component('todo-item', {  props: ['item'], // 声明能接收的参(属)数(性)  // {{item}} 使用传递过来的 item  template: `<li>​      <input type="checkbox">​      <span>{{item}}</span>​      <button>删除</button>​    </li>`})
<div id="app"> <ul>​ <todo-item item="学习 Vue 属性"></todo-item>​ <todo-item item="学习 Vue 事件"></todo-item>​ <todo-item item="学习 Vue 插槽"></todo-item> </ul></div>
复制代码


我们再精简一下:


 <ul>​    <todo-item v-for="item in list" :item="item"></todo-item>  </ul></div>new Vue({  el: '#app',  data() {​    return {​      list: ['学习 Vue 属性', '学习 Vue 事件', '学习 Vue 插槽']​    }  }})
复制代码


这样就可以了,是不是很简单?


点击此处,深入学习 Vue 中组件的属性

事件

我现在已经学完了 Vue 属性,想要从 todolist 里面把它删除掉,这好像并不太容易。这时,我需要给 button 绑定一个事件,当然 Vue 提供给我们了一个简单的方式进行绑定事件,用@xxx 就可以进行事件绑定了(这里的 xxx 指的任一字符串,根据你的实际需要来命名就行)


Vue.component('todo-item', {  props: ['item'],  template: `<li>​      <input type="checkbox">​      <span>{{item}}</span>​      <button @click="handleClick">删除</button>​    </li>`,  methods: {​    handleClick() {​    }  }})
复制代码


然后我们需要把点击事件告诉我们的上层(父组件),Vue 同样给我们提供了一个 API:this.$emit(‘xxx’, …),我们既然是做删除操作,那就是叫 delete 好了,我们还可以传递更多的参数,如 this.item:


handleClick() {  this.$emit('delete', this.item)}
复制代码


上层组件还缺少了一个用来接收 delete 的地方,我们可以通过 @delete 的方式来绑定一个用来接收 delete 事件的方法:


<todo-item v-for=“item in list” :item=“item” @delete=“handleDelete”>


最后只需要在 methods 字段上定义一个 handleDelete 方法,改变 list 数组就完成了我们的删除操作:


new Vue({  el: '#app',  data() {    return {      list: ['学习 Vue 属性', '学习 Vue 事件', '学习 Vue 插槽']    }  },  methods: {    handleDelete(item) {      const index = this.list.findIndex(text=>text === item);      this.list.splice(index, 1);    }  }})
复制代码


以上就是 Vue 中事件的用法。


点击此处,深入学习 Vue 中组件的事件

插槽

现在我想让这个 TodoList 中的“学习 Vue XXX”前加个图标 Icon,怎么办呢?还好 Vue 早就帮我想到了,我们不能再通过属性传递这些带有标签的内容,而是通过一种名叫“插槽”的东西进行传递:


<todo-item v-for="item in list" :item="item" @delete="handleDelete">  <span>我是Icon</span></todo-item>
复制代码


当然我们也不能再用双括号来解析,我们需要使用这种写法来解析:


template: `<li>​      <input type="checkbox">​      <span>{{item}}</span>​      <slot></slot>​      <button @click="handleClick">删除</button>​    </li>`,
复制代码


这种我们称之为默认插槽。


现在我想更进一步,添加两个图标,一个在文字前面,一个在文字后面,没问题:


<todo-item v-for="item in list" :item="item" @delete="handleDelete">  <span slot="prefixIcon">我是前缀Icon</span>  <span slot="suffixIcon">我是后缀Icon</span></todo-item>
复制代码


同样 template 需要更改:


template: `<li>​      <input type="checkbox">​      <slot name="prefixIcon"></slot>​      <span>{{item}}</span>​      <slot name="suffixIcon"></slot>​      <button @click="handleClick">删除</button>​    </li>`,
复制代码


这便是我们的具名插槽。


如果想让功能更加丰富的话,比如我想根据我的 input checkbox 的是否选中来改变图标的颜色,该怎么做?


第一步,记录我们 input 的选中状态,我们使用 Vue 的 v-model 进行 input 的双向绑定:


Vue.component('todo-item', {  props: ['item'],  data() {​    return {​      checked: false, // 默认不选中​    }  },  template: `<li>​      <input type="checkbox" v-model="checked">​      <slot name="prefixIcon"></slot>​      <span>{{item}}</span>​      <slot name="suffixIcon"></slot>​      <button @click="handleClick">删除</button>​    </li>`,  methods: {​    handleClick() {​      this.$emit('delete', this.item)​    }  }})
复制代码


状态有了,现在需要把这个状态传递给上层:


<slot name="prefixIcon" v-bind="{checked}">我是前缀Icon</slot>
复制代码


接收到状态后并根据状态提供不同颜色的图标:


<span slot="prefixIcon" slot-scope="props" :style="{color: props.checked ?'red':'blue'}">我是前缀Icon</span>
复制代码


这就是我们的作用域插槽。


为了方便理解,插槽使用方式我们使用了 Vue 2.5 版本的语法进行讲解,Vue 2.6 的语法可查看视频教程。


点击此处,深入学习 Vue 中组件的插槽


如果你已经阅读到了这里,那么恭喜你,你已经可以进行简单的 Vue 组件开发了。


如果还想学习更多的 Vue 实战技巧,欢迎订阅我的视频课程《Vue 开发实战》


2019-04-01 17:443979

评论 1 条评论

发布
用户头像
<span slot="prefixIcon" slot-scope="props" :style="{color: props.checked ?'red':'blue'}"> 我是前缀 Icon</span>
这行代码里面 slot-scope="props" 是什么意思呢?
2019-04-10 14:34
回复
没有更多了
发现更多内容

【广州银行信用卡中心】5分钟实现一键发布!

嘉为蓝鲸

IT

人工智能深入油气领域 百度智能云与石化盈科共建合同智能化应用平台

百度开发者中心

人工智能

软件测试/测试开发丨数据持久化技术(Python)的使用

测试人

软件测试 自动化测试 测试开发

Python十大实用技巧【附源码】

我爱娃哈哈😍

Python 开发技巧

对象存储BOS: 通过安卓SDK使用HTTPDNS服务

百度开发者中心

对象存储

软件测试|教你如何用Python获取昨天今天明天的日期

霍格沃兹测试开发学社

触达率提升 20%,融云推送优化实践

融云 RongCloud

产品 实践 融云

软件测试/测试开发丨跨平台API对接(Python)的使用

测试人

软件测试 jenkins 自动化测试 测试开发

Spring生态简介

Java你猿哥

Java spring Spring Boot 后端 ssm

阿里三面46题:java高级+数据库+网络+架构设计!含答案大赠送!

Java你猿哥

Java 阿里巴巴 后端 面经 春招

xx产品介绍

andy

在线教育≠在线观看:风变科技应用无影打造自动化实训教学模式

云布道师

无影

嘉为科技与工银科技正式启动数字研运一体化合作项目

嘉为蓝鲸

得物榜单|全链路生产迁移及B/C端数据存储隔离

得物技术

运维 生产

分布式数据库架构路线大揭秘

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 3 月 PK 榜

图数据库中的“分布式”和“数据切分”(切图)

NebulaGraph

数据库 分布式 图数据库

2021年第十一届数据技术嘉年华(DTC)资料分享

墨天轮

数据库 GaussDB TiDB 国产数据库 南大通用

先巩固下 Java 线程这些基础操作,再开始多线程编程也不迟

Java你猿哥

Java 多线程 开发

与高校开发者面对面,昇腾AI开发者创享日首次走进沈阳高校

科技热闻

NFT游戏藏品开发DApp系统搭建

薇電13242772558

NFT

共36万字!为上岸Alibaba,我把Github上Java面试题都整理了一遍

Java你猿哥

Java Spring Boot ssm 面经 春招

信通院MLOps旗舰级评测,业内首批通过!

百度开发者中心

人工智能 深度学习‘’ 文心一言

唯一入选的制品库!嘉为蓝鲸CPack制品管理平台成功入选!

嘉为蓝鲸

IT

打造江西数智产业高地,百度飞桨人工智能产业赋能中心落户南昌青山湖

百度开发者中心

人工智能 百度飞桨

介绍3种ssh远程连接的方式

华为云开发者联盟

后端 开发 华为云 华为云开发者联盟 企业号 3 月 PK 榜

etl 增量对比解决方案 etl-engine 如何实现增量对比抽取

weigeonlyyou

大数据 hadoop 数据库迁移 云数据迁移 Kafka ETL

【中远海运特运】WeOps产品为业务系统安全稳定保驾护航!

嘉为蓝鲸

加速国产化真替真用,京东云打造“多云多芯多活””数字基础设施

京东科技开发者

国产化 数字化建设 数字基础设施 国产化替代 京东云峰会

12家辽宁AI领先企业加入昇腾万里伙伴计划

科技热闻

如何通过C#/VB.NET从PowerPoint文档中提取图片

在下毛毛雨

C# .net PowerPoint 提取图像

如何分析网站监控中的数据报表,都有哪些关键信息?

云智慧AIOps社区

监控 监控宝 云智慧 监控安全 网站监控

3个概念,入门 Vue 组件开发_大前端_唐金州_InfoQ精选文章