文章目录

  • 使用意义
  • 基础使用
  • 给组件添加属性
  • 传递事件
  • 自定义组件的v-model
    • 剖析v-model原理
    • 使用示例
  • 插槽

使用意义

有时候一组HTML代码可能会在多出使用(比如页眉页脚)。如果我们把这样的代码到处都进行复制粘贴,虽然一时方便了,但后期维护代价非常高,而且代码重复性较高,导致可读性也有所下降。这时候我们就可以将这些重复代码封装成一个组件,以后在使用的时候只需要写上自定义组件的标签即可直接调用。

基础使用

自定义组件Vue.component('标签名', {})一般我们的HTML模板和data数据以及方法之类的都会放在组件的大括号中。下面我会创建一个可以记录点击次数的自定义组件。

<!DOCTYPE html>
<html lang="zh_CN">
<head><meta charset="UTF-8"><title>dome</title>
</head><body><div id ="app"><component-button></component-button><component-button></component-button><component-button></component-button></div>
</body><script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>// 创建自定义组件Vue.component('component-button', {// 自定义组件中 template 负责放入HTML代码template: '<button @click="num+=1">当前点击了{{num}}次</button>',// data功能和Vue实例中的相同, 但自定义组件中的data是一个函数! 并且用返回值的方式定义属性,如下:// 有一定js基础或者看过我之前博客的一定知道data(){}是js创建函数data:function(){}的简写版!data(){return {num: 0}}});// 创建Vue实例new Vue({el: '#app'});
</script>
</html>

注意:创建自定义组件无论是否用到了Vue实例,都必须要有Vue实例,并且只能在Vue实例绑定的标签内才能使用自定义组件!!!
上述代码中包含了templatedata的使用方式。但需要注意在自定义组件中设置属性和在Vue实例中有所不同! 为什么我们要在自定义组件中创建属性,而不是使用Vue实例中的属性?因为如果我们多次调用自定义组件,使用组件内的属性是互相独立互不干扰的!

给组件添加属性

有时候我们需要所有组件使用的属性是共享的,需要使用Vue实例中的属性,而不是在自定义组件中创建的,这时候我就就可以通过自定义组件中的props创建属性接收值,而调用的时候我们只需要向props创建的属性中传入值即可。

<!DOCTYPE html>
<html lang="zh_CN">
<head><meta charset="UTF-8"><title>自定义组件添加属性</title>
</head><body><div id ="app"><!-- vfor是自定义标签中通过props定义的一个属性,我们需要通过此属性传入值 --><props-text :vfor="vfor_dict"></props-text></div>
</body><script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>// 创建自定义组件Vue.component("props-text", {// props中设定的是标签中的属性,我们从标签中接收此属性传入的值即可props: ["vfor"],// 如果需要写多行HTML代码,不能使用单双引号,而是使用反单引号``(英文状态下Tab键上方的键)// 多行时候需要注意的是自定义组件遵循单一根元素(根元素只能有一个,多了会出现问题)// 下方我的根元素就是table这里不能出现和table同级的元素!!!template: `<table><tr><td>称号</td><td>名字</td></tr><tr v-for="(key, value) in vfor"><td>{{key}}</td><td>{{value}}</td></tr></table>`,})// 创建Vue实例new Vue({el: '#app',data: {vfor_dict: {人类懂王 : '川建国',祖传百万 : '孙宇晨',这饭真香 : '王境泽',行业冥灯 : '罗老师'}},methods: {}});
</script>
</html>

添加的属性不仅能用于绑定Vue中的属性,主要功能是用于传值,将组件外的值传入组件内!然后组件可以根据传入的值做一些变化。
需要注意的是:多行时候需要注意的是自定义组件遵循单一根元素,在上述代码中我也有提及。如果有多个根元素,很可能会发生只执行首个根元素而又没有任何报错的情况!

传递事件

上述给组件添加属性的功能主要是用于将自定义组件中的值传入组件内,但如果我们需要将组件内的值传入组件外呢?这时候就需要使用this.$emit函数来实现

<!DOCTYPE html>
<html lang="zh_CN">
<head><meta charset="UTF-8"><title>dome21</title>
</head><body><div id ="app"><!-- 先看创建自定义属性后再看这个 --><!-- value用于传入参数,他将遍历出来的参数i传入自定义组件中 --><!-- v用于接收参数,他接收自定义组件传出的参数并在传给item方法 --><component-input v-for='i in vfor_dict' :value='i' @v='item'></component-input>{{vdata}}</div>
</body><script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>    // 创建自定义组件Vue.component("component-input", {// 创建一个value的属性用于接收参数props: ['value'],template: `<div><!-- checkbox是多选框 --><input type="checkbox" @input="transmit"><label>{{value.title}}</label></div>`,methods: {// 每次点击多选框时都会触发此方法transmit(){// 此方法定义了一个属性名为v,并将其参数通过v传出this.$emit("v", this.value.name)}}})// 创建Vue实例new Vue({el: '#app',data: {vfor_dict: [{title: '人类懂王', name : '川建国'},{title: '祖传百万', name : '孙宇晨'},{title: '这饭真香', name : '王境泽'},{title: '行业冥灯', name : '罗永浩'}],vdata : []},methods: {item(value){// indexOf方法用于判断数据是否已经存在// 因为上述多选框选择和取消选择都会传出相同的参数,我用indexOf方法判断是否当前选择状态,如果vdata中还没有此数据,反之亦然index = this.vdata.indexOf(value)// 如果数据存在,indexOf这会返回数据的角标,如果不存在则会返回-1,根据此可以做一个判断,用来添加或者删除数据if (index>=0) {this.vdata.splice(index, 1)} else {this.vdata.push(value)}}}});
</script>
</html>

自定义组件的v-model

剖析v-model原理

组件除了向内或者向外绑定外,还可以使用v-model进行双向绑定。不过这里我们需要对v-model深入剖析,v-model可以看成为v-bindv-on的组合体。就如同下述代码中使用v-bind+v-on绑定的输入框和v-model绑定的输入框达到了相同的效果!

<!DOCTYPE html>
<html lang="zh_CN">
<head><meta charset="UTF-8"><title>自定义组件内的v-model</title>
</head><body><div id ="app"><input type="text" v-model="vmodel"><p>{{vmodel}}</p><!-- $event.target.value是获取当前输入框中的值 --><input type="text" :value="vbind" @input="vbind=$event.target.value"><p>{{vbind}}</p></div>
</body><script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>// 创建Vue实例new Vue({el: '#app',data: {vmodel: '',vbind: ''}});
</script>
</html>

正如我上述例子中v-model会默认绑定value属性(prop)和input方法(event)。(不过在碰到单选、多选、下拉菜单等一些特殊情况也会绑定其他的属性和方法,如果想了解可以看我的另一篇专门介绍v-bind,v-on,v-model的博客)
当犹豫我们是自定义组件,v-model则只会默认绑定value属性(prop)和input方法(event)

使用示例

从上述v-model原理中我们可以看出v-model自动绑定属性(prop)和方法(event)限制较大,如果我们在自定义组件中想要v-model绑定指定的属性(prop)和方法(event)需要在自定义组件中添加一个model属性进行指定!

<!DOCTYPE html>
<html lang="zh_CN">
<head><meta charset="UTF-8"><title>自定义组件的v-model_2</title>
</head><body><div id ="app"><use-model v-model="vdata"></use-model></div>
</body><script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>// 创建自定义组件Vue.component('use-model', {props: ['vitem'],model: {// 绑定的属性和上述props中对应prop: 'vitem',// 绑定的事件名event: 'item-changed'},template: `<div><button @click="sub"> - </button><span>{{vitem}}</span><button @click="add"> + </button></div>`,methods: {sub(){// 这里绑定的事件名和model中事件名是一个this.$emit('item-changed', this.vitem-1)},add(){this.$emit('item-changed', this.vitem+1)}}})// 创建Vue实例new Vue({el: '#app',data: {vdata : 0}});
</script>
</html>

上述程序我们先从自定义组件中的模板开始看,如果我们点击了-或者+,则会触发执行相应的方法,而上述传递事件中我们讲过,this.$emit会向外在指定的事件名中传入值,这时候,我就让其想item-changed(这个名字是可以自己随意命名的)中传值,而这个事件名刚好是被v-model所绑定,一旦被触发这个事件,则其中的值则会传入v-model绑定的属性中。这样就刚好完成了我们的双向绑定!

上述我只是使用了v-model其中一种的使用方法,但v-model还能玩出很多其他花样。

插槽

有时候一个组件,可能其中绝大部分都相同,只有极个别的地方文本或者标签不同,这时候我们就可以用到自定义组件中的插槽来完成这个需求。
当我们使用单个插槽时,非常方便,只需要在需要插入文本或者标签的自定义组件的模板中写入<slot></slot>标签,然后在调用的自定义组件的时候,把我们需要插入的文本或者标签直接卸载自定义组件中即可。如果我们设置了多个插槽,这时候则需要name属性来指定插入那个插槽,这时候调用的时候,我们必须要使用<template v-slot:name名>标签来指定slot绑定的属性名。如下

<!DOCTYPE html>
<html lang="zh_CN">
<head><meta charset="UTF-8"><title>自定义组件的插槽</title>
</head><body><div id ="app"><use-slot url="https://www.baidu.com"><!-- 如果插槽中指定name属性的标签,必须使用<template v-slot:name名></template>包裹其想要插入的标签或者文本!--><!-- 注意:这里的template不能改变  --><template v-slot:name><h6>百度一下</h6></template><template v-slot:remarks><span>比360和搜狗好用太多了</span></template></use-slot><use-slot url="https:cn.bing.com"><template v-slot:name><h1>必应</h1></template><template v-slot:remarks><span>蛮不错的</span></template></use-slot></div>
</body><script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>// 创建自定义组件Vue.component('use-slot', {props:['url'],// 如果有多个插槽标签<slot></slot>,最好在插槽中添加一个name属性,方便在插入时插到正确的位置template:`<div><a :href="url"><slot name="name"></slot></a><span>备注: </span><slot name="remarks"></slot></div>`})// 创建Vue实例new Vue({el: '#app'});
</script>
</html>

Vue如何自定义组件?超详细Vue自定义组件指南!使用自定义组件减少重复造轮子! ∠( °ω°)/ 前端知识相关推荐

  1. 【转帖】超详细的 Vagrant 上手指南

    本文转自https://zhuanlan.zhihu.com/p/259833884 超详细的 Vagrant 上手指南 DavyCloud 努力把事讲清楚 91 人赞同了该文章 搭建 Linux 虚 ...

  2. 神器 VS Code,超详细Python配置使用指南

    作者:Lemon 出品:Python数据之道 神器 VS Code, 超详细Python配置使用指南 大家好,我是 Lemon. 之前在公众号发了关于 PyCharm 与 VS Code 对比的文章, ...

  3. 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印...

    重复造轮子系列--基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...

  4. vue学习笔记(超详细)

    文章目录 一. Vue基础 认识Vue.js Vue安装方式 Vue的MVVM 二. Vue基础语法 生命周期 模板语法 创建Vue, options可以放什么 语法 综合 v-on v-for遍历数 ...

  5. vue中使用vuex(超详细)

    vuex是使用vue中必不可少的一部分,基于父子.兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公 ...

  6. todomvc html css模板,[超详细] vue入门项目 TodoMVC 实现和思考

    如果对你有帮助希望可以点个 star 哦 ~ 一.项目初始化 1.下载模板 在存放该项目的目录下执行: git clone https://github.com/tastejs/todomvc-app ...

  7. vue+webpack搭建项目超详细教程

    在使用vue-cli之前,请确认你的电脑已经安装了 node,建议版本在 8.0.0 以上 安装淘宝镜像(强烈推荐安装,不然真的好慢,等到最后还是失败) 安装cnpm的原因:npm的服务器是外国的,所 ...

  8. Springboot+Vue整合笔记【超详细】

    | 作者:江夏 | 微信公众号:1024笔记 | 知乎:https://www.zhihu.com/people/qing-ni-chi-you-zi-96 | GitHub:https://gith ...

  9. Vue vscode 创建 vue 项目流程【超详细】

    文章目录 一.安装node 二.配置淘宝镜像 三.配置 vscode(win10) 四.全局安装脚手架 五.创建项目 六.进入项目 七.项目结构 一.安装node 请在官网下载安装:https://n ...

最新文章

  1. Python实战案例,pyecharts模块,Python实现5G数据
  2. java 升级1.8_升级java到1.8.0_111
  3. MinGW 与MSVC的区别
  4. Ubuntu18.04 root 登录
  5. 系统启动数据库服务器,linux系统如何启动数据库服务器
  6. 如何区分网线是几类的_小移课堂 | 网线这样选,网速才能嗖嗖的!
  7. 工业机器人打磨抛光编程员工资_一种工业机器人打磨抛光工作平台的制作方法...
  8. 用计算机探索奥秘规律例题,人教新课标小学五年级上册数学《用计算器探索规律》教案...
  9. python图像边缘检测_使用python获取图像中形状的轮廓(x,y)坐标
  10. CF-1156F Card Bag
  11. 清楚form表单数据的便捷jQuery之法
  12. spark-submit(spark版本2.3.2)
  13. 什么是Adobe Creative Cloud,值得吗?
  14. 重定向和请求转发详解
  15. JavaScript判断数组的几种方法
  16. 热敏打印计算机,热敏打印头工作原理是什么 热敏打印头原理介绍【详解】
  17. 用计算机代码模拟基因,一种通过计算机程序模拟产生简化DNA甲基化测序数据的方法与流程...
  18. linux capability
  19. 基于python+django框架+Mysql数据库的校园运动场地预约系设计与实现
  20. Dummy Sample

热门文章

  1. C语言画菜单函数(只为方便手机端学习用户)
  2. 字典 | springboot 返回数据字典翻译
  3. MP4:文件格式类型mp42播放解决方案
  4. [Unity] 包括场景互动与射击要素的俯视角闯关游戏Demo
  5. VMware 虚拟机实现硬盘扩容自由 无需格式化
  6. win10关机后自动重启_win10关机提示自动更新咋办?只需简单设置,即可彻底关闭...
  7. 软件测试工程师面试题合集,建议收藏一波!
  8. 课程设计 停车场管理系统(附源码)
  9. 科大讯飞版ChatGPT开始内测《讯飞星火》
  10. RK3568用户自定义开机画面功能