写点什么

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:443892

评论 1 条评论

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

【JWT】jwt令牌研究

No8g攻城狮

JWT\ JWT

超高清设计师云工作站,为设计企业护航

清欢科技

头部效应明显,中小厂商「闷赚」的 Dating 赛道

融云 RongCloud

社交 虚拟

网络安全实战之植入后门程序

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 漏洞挖掘

云办公成趋势,华为云桌面全方位保障企业安全

科技之光

HTTP的状态码

穿过生命散发芬芳

HTTP 12月月更

华为云桌面为企业数字化发展赋能强劲动力

爱科技的水月

华为云桌面协同办公,助力建筑行业数字化转型

爱科技的水月

自动化测试技术笔记(三):如何编写技术方案

老张

自动化测试 技术方案

华为云会议,助力企业高效办公

秃头也爱科技

Verilog模块例化

芯动大师

Verilog语法 Verilog例化模块 Verilog教程

华为云桌面,为企业发展打造优质云办公环境

爱科技的水月

华为云桌面,开启云上高效办公之旅!

清欢科技

2022-12-21:uifd/ui-for-docker是docker的web可视化工具。请问部署在k3s中,yaml文件如何写?

福大大架构师每日一题

Docker 云原生 k8s k3s 福大大

数字化办公?选云桌面就对了!

科技之光

我在编码过程使用Jenkins自动化的姿势

软件工程师-罗小东

mysql数据库运维常用的shell脚本

@下一站

12月日更 12月月更

华为云桌面之下的“冰山”:技术底座x繁荣生态加速模式进化

IT科技苏辞

华为云桌面Workspace,如何为用户开启全新办公模式?

爱科技的水月

超高清设计师云工作站,设计可以更高效

清欢科技

低成本、高效率!华为云桌面助力企业数字化转型

清欢科技

数字云办公连续7年领跑,华为云桌面优势突显!

科技之光

对比PyTorch、TensorFlow、JAX、Theano,我发现都在关注两大问题

OneFlow

人工智能 深度学习 函数转换

华为云会议,让会议更智能

秃头也爱科技

安全灵活,华为云桌面成为数字化办公最佳搭档

清欢科技

云上办公,且看华为云桌面如何加速企业数字化发展之路?

科技之光

华为云会议——安全得多,高效得很

秃头也爱科技

华为云会议,更专业“会”更好

秃头也爱科技

【Spring专题】「开发指南」夯实实战基础功底之解读logback-spring.xml文件的详解实现

洛神灬殇

spring logback 12月日更 12 月 PK 榜

云上办公,还得是华为云桌面的一站式云上工作站

科技之光

华为云桌面,一站式云上数字化创作深度解读

IT科技苏辞

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