位置: IT常识 - 正文

【vue2】组件进阶与插槽详解(vue 组件)

编辑:rootadmin
【vue2】组件进阶与插槽详解

推荐整理分享【vue2】组件进阶与插槽详解(vue 组件),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:vue组件is,vue tips组件,vue如何进行组件化开发,vue如何进行组件化开发,vue2.0组件,vue 组件,vue2.0组件,vue如何进行组件化开发,内容如对您有帮助,希望把文章链接给更多的朋友!

🥳博       主:初映CY的前说(前端领域)

🌞个人信条:想要变成得到,中间还有做到!

🤘本文核心:v-modedl表单双向绑定、ref|$ref操作dom、dynamic动态组件、$nextTick同步、匿名插槽、具名插槽、作用域插槽

目录(文末有给大家准备好的Xmind思维导图)

一、组件进阶

1.v-model语法

2.ref与$ref语法

3.dynamic动态组件

4.this.$nextTick()

二、匿名|具名|作用域插槽

插槽概念:

1.匿名插槽

2.具名插槽

3.作用域插槽

一、组件进阶1.v-model语法

v-model指令我们的一个初印象就是表单数据实现绑定双向,一修改同步修改,那么本质是什么?

博主认为v-mode语法本质上是简化了书写操作。触发v-model需要满足两个条件的(标红部分是语法规定部分不可自定义)

data中数据变化,表单的值也会变化  :value="data中的属性名" 表单的值发生变化,data中的数据也会变化  @input="data中的属性名=$event.target.value"

当满足了就可直接写上v-model="我们data中的属性名"

举个例子:

<template> <div> <h1>根组件App.vue</h1> <!-- 1.v-model = "msg" (1)data中的数据变化,表单的值也会变化 :value="msg" (2)表单的值发生变化,data中的数据也会变化 @input="msg=$event.target.value" --> <input type="text" v-model="msg" /> <hr /> <!-- 这种写法与上面写法功能一致 --> <input type="text" :value="msg" @input="msg = $event.target.value" /> <hr /> <!-- 这种写法也与上面写法一致 --> <input type="text" :value="msg" @input="doInput" /> <hr /> </div></template><script>export default { data() { return { msg: "" }; }, methods: { doInput(e) { this.msg = e.target.value; } }};</script><style></style>

 效果演示:

 可见:当我们直接用v-model="属性名“这种方法写简化了书写的难度达到了同样的效果。

2.ref与$ref语法

这个语法可使用操作dom元素。每个 vue 的组件实例上,都包含一个$refs 对象,里面存储着对应的DOM 元素或组件的引用。

注意点:

当ref="自定义名"是写在组件身上就可以得到该对象实例vue

绑定是ref,调用是$refs

1.绑定dom写法:<标签 ref="自定义名"></标签>

<div ref="aaa" class="box"></div> <input ref="bbb" type="text"> <my-goods ref="ccc" ></my-goods>

2.调用dom写的:this.$refs.自定义属性名 

console.log(this.$refs.aaa);console.log(this.$refs.bbb);console.log(this.$refs.ccc);// 调用子组件方法console.log(this.$refs.ccc.doClick());//都包含一个$refs 对象因此可已获取标签里面的方法(组件)

参考下面这个例子:

父组件:App.vue

<template> <div> <h1>我是父组件</h1> <button @click="onAdd">点我查看ref打印的啥</button> <div ref="aaa" class="box"></div> <input ref="bbb" type="text"> <my-goods ref="ccc" ></my-goods> </div></template><script>import MyGoods from '@/components/MyGoods.vue'export default { components: { MyGoods }, data() { return { } }, methods: { onAdd() { console.log(this); console.log(this.$refs.aaa); console.log(this.$refs.bbb); console.log(this.$refs.ccc); // 调用子组件方法 console.log(this.$refs.ccc.doClick()); }, }}</script><style></style>

子组件:MyGoods.vue

<template> <div> <p>商品名称:小米</p> <p>商品价格:{{ price }}</p> <button @click="doClick">点我购买</button> </div></template><script>export default {props:{ value:Number},data(){ return{ price:'999' }}, methods: { doClick() { console.log("点击了购买"); return 0//当不写的时候调用了方法没有return会提示undefinded }}}</script><style></style>

实现效果:

3.dynamic动态组件

什么是动态组件: 让多个组件使用同一个挂载点并动态切换,这就是动态组件。

通过设置组件名,让一个挂载点可以切换不同的组件。

语法格式:

<component :is="组件名"></component>

举个例子:

父组件App.vue

<template> <div> <h1>我是父组件</h1> <button @click="comName='login'">登录</button> <button @click="comName='user'">信息</button> <component :is="comName"></component> </div></template><script>import login from '@/components/login.vue'import user from '@/components/user.vue'export default { components: { login, user }, data() { return { comName:"user" }}}</script><style></style>

子组件 user.vue

<template> <div> <p>我是个人信息组件</p> </div></template><script>export default {name:"user"}</script><style></style>

子组件 login.vue

<template> <div> <p>我是登录组件</p> </div></template><script>export default {name:"login"}</script><style></style>

实现效果:

【vue2】组件进阶与插槽详解(vue 组件)

 可以看到我们通过<component :is="组件名">找到相应的标签运行

4.this.$nextTick()

是用来将我们vue的异步操作进行放在页面dom渲染前面。想要在修改数据后立刻得到更新后的DOM结构,可以使用Vue.nextTick()

上个例子:

<template> <div> <h1>我是父组件</h1> <input type="text" v-if="flag" ref="input"> <button v-else @click="doClick">点我开始输入</button> </div></template><script>export default { data() { return { flag: false } }, methods: { doClick() { this.flag = true//异步操作,生命周期中修改阶段 this.$nextTick( () => {//一定要箭头函数,因为箭头函数的this指向上一层作用域与原本的this是同一个 this.$refs.input.focus() } ) } }}</script><style></style>

 实现的效果:

当 this.flag = true执行完成之后页面应该是执行渲染在页面的操作,但是我们的 vue是异步的微任务(Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新),渲染的时候找不到ref="input"这个dom就会报错,因此需要就用  this.$nextTick来将需要的操作放在渲染之前。

 可看上图:当我写在外面的时候就会报错。

原理:vue操作dom是异步的操作,如果需要同步显示出来需要利用this.$nextTick()将异步操作提前放在dom树更新后,页面渲染前

二、匿名|具名|作用域插槽插槽概念:slot相当于是组件里面的一个内置的开关,打开了这个开关就可以在复用组件的同时修改单个组件中的HTML的结构。用来解决组件复用的同时可以对单个组件进行修改操作,让组件变得更加灵活1.匿名插槽

我们在父中调用子组件,在复用组件的同时修改单个组件不受影响

插槽书写结构:   

父传:<子组件名>HTML结构</子组件名>

子收: <slot>此处写默认值</slot>

我们一起来看看这个例子:

父组件:App01(匿名插槽).vue

<template> <div> <h1>我是父组件</h1> <goods><button>已下单</button></goods> <goods></goods> <goods ><button disabled>已卖完</button></goods> <goods><a href="#">点我跳转</a></goods> </div></template><script>import goods from '@/components/goods.vue'export default {components:{goods}}</script><style></style>

 子组件:goods.vue

<template> <div class="son"> <h3>我是子组件</h3> <h4>商品名称</h4> <!-- slot相当于是一个开关,打开了这个开关就可以插入想要的值 从父传 HTML的结构 --> <slot>我是默认的插槽</slot> </div></template><script>export default { name: "goods", data() { return {} }}</script><style scoped>.son { border: 1px solid red;}</style>

我们先看下我们的实现效果:

 可以看出来,我们的<goods></goods>调用了四次,我们在父中的值传到子中的都不一样,页面也根据我们所想的展示出来了不同的组件。

2.具名插槽

使用多个slot实现精准的传递多个位置的插槽给子组件 ,写的时候必须在<template></template>中

具名插槽书写结构: 

父传:

<组件名> <template v-slot:自定义名> <h2>HTML结构</h2> </template> </组件名>

子收:

      <div >          <slot name="自定义插槽名">插槽默认值</slot>      </div>

我们一起来看看这个例子:

父组件:App02(具名插槽).vue

<template> <div> <h1>我是父组件</h1> <cell> <template v-slot:title> <h2>I am Tittle</h2> </template> <template v-slot:content> <i>I am goodsInfo</i> </template> <template v-slot:right> <i>My position</i> </template> </cell> </div></template><script>import cell from '@/components/cell.vue'export default {components:{cell}}</script><style></style>

 子组件:cell.vue

<template> <div class="cell"><!-- 具名插槽使用: 1.在子组件钟使用 slot+name确定组件的作用域 2.在父组件钟用template 接收 使用v-slot:name传递 --> <div class="title" > <slot name="title">我是默认标题</slot> </div> <div class="content" > <slot name="content"> 我是文本信息</slot> </div> <div class="right" > <slot name="right">我是右侧信息</slot> </div> </div></template><script>export default {}</script><style> .cell{ border: 1px solid #f00; height: 60px; padding: 10px; position: relative; } .title{ float: left; line-height: 1px; } .content{ position: absolute; bottom: 10px; left: 10px; } .right{ float: right; }</style>

 实现效果:

 通过这个例子,我们可以看到,我们具名比匿名插槽多了一个精准定位的功能。

3.作用域插槽

父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容

作用域插槽书写结构: 

子组件传递:

<slot 属性名="属性值">默认值</slot>

父组件接收:(注意接收的是一个对象)

<组件名 父传值属性> <template v-slot="{一个对象}"> HTML属性 </template> </组件名>

来个例子:

父组件:App03(作用域插槽).vue

<template> <div> <!-- 1.匿名插槽:父组件传递 单个HTML结构 给子组件 父传:<子组件>HTML结构</子组件> 子收:<slot>默认HTML结构</slot> 2.具名插槽:父组件传递 多个HTML结构 给子组件 父传: <子组件> <template #插槽名> HTML结构 </template> </子组件> 子收:<slot name="插槽名">默认HTML结构</slot> 3.作用域插槽:子组件传递数据给父组件 子传:<slot 属性名="属性值">默认HTML结构</slot> 父收: <子组件> <template v-slot="对象名"> HTML结构 </template> </子组件> --> <!-- (具名插槽 + 作用域插槽)组合写法:#插槽名 = "对象名" --> <h1>父组件</h1> <student></student> <h3>删除功能</h3> <student :arr="list1"> <template v-slot="{ $index }"> <button @click="list1.splice($index, 1)">删除</button> </template> </student> <h3>头像功能</h3> <student :arr="list2"> <template v-slot="{ row }"> <img :src="row.headImgUrl" alt="" /> </template> </student> </div></template><script>import student from "./components/student.vue";export default { components: { student }, data() { return { list1: [ { id: "13575", name: "小传同学", age: 18, headImgUrl: "https://www.yuucn.com/wp-content/uploads/2023/04/1682102844-13c1b4659da3c08.jpg", }, { id: "62408", name: "小黑同学", age: 25, headImgUrl: "https://www.yuucn.com/wp-content/uploads/2023/04/1682102850-13c1b4659da3c08.jpg", }, { id: "73969", name: "智慧同学", age: 21, headImgUrl: "https://www.yuucn.com/wp-content/uploads/2023/04/1682102857-13c1b4659da3c08.jpg", }, ], list2: [ { id: "13575", name: "传同学", age: 8, headImgUrl: "https://www.yuucn.com/wp-content/uploads/2023/04/1682102844-13c1b4659da3c08.jpg", }, { id: "62408", name: "黑同学", age: 5, headImgUrl: "https://www.yuucn.com/wp-content/uploads/2023/04/1682102850-13c1b4659da3c08.jpg", }, { id: "73969", name: "慧同学", age: 1, headImgUrl: "https://www.yuucn.com/wp-content/uploads/2023/04/1682102857-13c1b4659da3c08.jpg", }, ], }; },};</script><style></style>

子组件: student.vue

<template> <div> <slot name="title" >修改</slot> <table border="1"> <thead> <tr> <th>序号</th> <th>姓名</th> <th>年龄</th> <th>头像</th> </tr> </thead> <tbody> <tr v-for="(item,index) in arr" :key="item.id"> <td>{{ index+1 }}</td> <td>{{ item.name }}</td> <td>{{ item.age }}</td> <td> <slot :row="item" :$index="index"></slot> </td> </tr> </tbody> </table> </div></template><script>export default { props: { arr: Array }, data() { return {} }}</script><style scoped>table { margin-top: 20px;}td { height: 60px;}img { height: 90%;}</style>

效果如下:

 可以看见,我们复用的三个student的组件都分别实现了不同的效果,第一个因为我没有将父组件中的arr传进去,因此arr提示undefin,后面两个组件分别实现了不同的功能。对比具名插槽,作用域插槽实现了

总结匿名|具名|作用域函数:

匿名插槽:插槽可以实现组件复用的同时显示不同的内容

具名插槽:slot开关可以写多个,并且可以精准定位到我们想要的位置

作用域插槽:子组件可以传递数据给父组件

好了,兄弟姐妹们,本文结束喽!如果有未知的疑问,大家留言我会尽我所能帮助大家

下篇文章将讲解【路由】的使用,本专栏将持续更新,欢迎关注~ 

本文链接地址:https://www.jiuchutong.com/zhishi/300550.html 转载请保留说明!

上一篇:nodejs——解决跨域问题(node.js解决跨域请求)

下一篇:web开发 用idea创建一个新项目(idea搭建web开发环境)

  • vivoiQOO锁屏原子随身听怎么关闭(vivo手机怎么关闭原子桌面)

    vivoiQOO锁屏原子随身听怎么关闭(vivo手机怎么关闭原子桌面)

  • 抖音喜欢列表怎么设置隐私(抖音喜欢列表怎么清零)

    抖音喜欢列表怎么设置隐私(抖音喜欢列表怎么清零)

  • vivo NEX 3s支持4k高清录像的吗(vivonex3s支持5g吗)

    vivo NEX 3s支持4k高清录像的吗(vivonex3s支持5g吗)

  • ppt怎么设置艺术字位置(ppt怎么设置艺术效果)

    ppt怎么设置艺术字位置(ppt怎么设置艺术效果)

  • 小米8关机键失灵(小米8关机键失灵怎么关机)

    小米8关机键失灵(小米8关机键失灵怎么关机)

  • pcpmoo是什么手机型号(pcamoo是什么手机价格)

    pcpmoo是什么手机型号(pcamoo是什么手机价格)

  • 快手极速版能用几个账号(快手极速版能用支付宝提现吗)

    快手极速版能用几个账号(快手极速版能用支付宝提现吗)

  • 港版苹果6可以用电信卡吗(港版苹果可以用移动卡吗)

    港版苹果6可以用电信卡吗(港版苹果可以用移动卡吗)

  • 苹果截屏快捷键没反应(苹果截屏快捷键怎么关闭)

    苹果截屏快捷键没反应(苹果截屏快捷键怎么关闭)

  • 耳机孔有一节插不进去(耳机插孔旁边的小孔是干嘛的)

    耳机孔有一节插不进去(耳机插孔旁边的小孔是干嘛的)

  • 华为已连接(不可上网) 但是wifi正常(华为已连接(不可上网)别的手机可以了)

    华为已连接(不可上网) 但是wifi正常(华为已连接(不可上网)别的手机可以了)

  • 新号码注册的淘宝被永封(新号码注册的淘宝怎么找)

    新号码注册的淘宝被永封(新号码注册的淘宝怎么找)

  • 手机可以上网电脑不能上网(手机可以上网电脑连不上网怎么回事)

    手机可以上网电脑不能上网(手机可以上网电脑连不上网怎么回事)

  • iphone11美版怎么区分v版s版(iphone11美版怎么插双卡)

    iphone11美版怎么区分v版s版(iphone11美版怎么插双卡)

  • 华为nova5pro缺点是(华为nova5pro的优点和缺点)

    华为nova5pro缺点是(华为nova5pro的优点和缺点)

  • ipad2插卡版支持4g网吗(ipad4g插卡版)

    ipad2插卡版支持4g网吗(ipad4g插卡版)

  • 充电器滋滋响正常吗(充电器滋滋的响)

    充电器滋滋响正常吗(充电器滋滋的响)

  • vivox21什么时候上市(vivox21什么时候出的)

    vivox21什么时候上市(vivox21什么时候出的)

  • 手机快手闪退怎么回事(快手闪退是什么情况)

    手机快手闪退怎么回事(快手闪退是什么情况)

  • 抖音里面怎么看访客记录(抖音里面怎么看直播)

    抖音里面怎么看访客记录(抖音里面怎么看直播)

  • 拼多多怎么看一共消费(拼多多怎么看一年消费多少)

    拼多多怎么看一共消费(拼多多怎么看一年消费多少)

  • 办公打印机的使用步骤(办公打印机的使用)

    办公打印机的使用步骤(办公打印机的使用)

  • 透明水印怎么做(如何制作透明水印logo)

    透明水印怎么做(如何制作透明水印logo)

  • 小米9月亮模式在哪(小米9月亮模式是真的吗)

    小米9月亮模式在哪(小米9月亮模式是真的吗)

  • 淘金币在哪能看到过期(淘金币怎么找)

    淘金币在哪能看到过期(淘金币怎么找)

  • 苹果Mac OS X系统快速显示/恢复隐藏文件的方法介绍(苹果macbook 系统)

    苹果Mac OS X系统快速显示/恢复隐藏文件的方法介绍(苹果macbook 系统)

  • 税前利润税率
  • 残保金计入管理费用还是营业税金及附加
  • 什么不属于损益类的会计项目
  • 给个体工商户付款可以到个人账户
  • 企业增资认缴是什么意思
  • 个人因终止投资经营而取得的股权转让收入如何计算个人所得税?
  • 增值税专用发票的税率是多少啊
  • 无形资产 减值
  • 一个公司帮另一个公司代付款
  • 企业长期待摊费用包括
  • 向银行借款一年是长期还是短期
  • 没超过标准的招待费缴税吗
  • 补记以前年度往来款
  • 增值税发票抵扣联丢失怎么办
  • 电子发票是专用发票吗
  • 公休假补贴多少钱
  • 广告费扣除年限
  • 宣告分派现金股利影响所有者权益变动吗
  • 车辆保险分期分摊怎么做账?
  • 进项税额多出来怎么处理
  • 固定资产处理收入计入什么科目
  • 价内税与价外税名词解释
  • 会计科目未付利润属于哪个科目
  • 支付商品展览费计入
  • 结转已经销售商品成本
  • win10开机黑屏几秒
  • 小米6桌面图标消失了
  • 企业所得税汇算清缴扣除标准2023
  • 慈善捐赠金额排行
  • 期间损益的科目
  • php aop
  • wordpress邮箱怎么配置
  • iframe frame
  • 股东无偿投入的土地需要摊销吗
  • php chr函数
  • 接受捐赠的增值税要交企业所得税吗
  • 含工资表的会计科目
  • vue页面刷新时原有的数据还在吗
  • 论文笔记模板
  • 流动比率越高越好嘛
  • 怎么查看python
  • 不动产投资缴纳什么税
  • python动态数据类型
  • PostgreSQL更新表时时间戳不会自动更新的解决方法
  • mysql5.7.17在win2008R2的64位系统安装与配置实例
  • 小规模企业免征增值税如何申报
  • 在校大学生可以考教师资格证吗
  • 代数分配法的优缺点和适用范围
  • 资质平移股权账务怎么办
  • 车辆保险都入什么
  • 生产企业出口退税政策
  • 员工借款后离职怎么处理
  • 税控服务费怎么记账
  • 转账时转错账号怎么办
  • 新担保法2021和担保期限
  • 工业企业中制造费用包括哪些内容
  • 安装mysql提示one or more
  • win8系统如何安装软件
  • 下载win10 32位
  • 简述操作系统更新设置方法
  • wdcp的/www目录大小调整或增加分区/硬盘的方法
  • windows任务管理器占用cpu过高
  • windows注册表简单应用
  • windows7如何设置电脑不待机
  • removed.exe - removed是什么进程 有什么用
  • win7无法删除d盘
  • window10邮件
  • linux系统修改
  • fragment的replace方法
  • 设置cmd命令
  • cocos2dx 不规则按钮的实现
  • Unity3D游戏开发毕业论文
  • jquery 日期
  • 你知道python不
  • unityprefab
  • 从零开始的基础篇
  • nodejs 扫描目录
  • javascript图片切换代码
  • 12366纳税服务热线接收税收违法行政行为举报管理办法
  • 印花税怎么计提科目
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设