Vue 组件复用多次自定义参数操作


Posted in Javascript onJuly 27, 2020

场景:

当项目中多处出现相同的模块时,此时的正常考虑是将其做成公共组建,通过传参不同,实现多处复用

具体:

背景:项目使用的技术是VUE+ElementUI

此处,多处出现的模块是select选择框,封装成组件后,传给它option的值,代码如下:

<!--组件文件 比如说这个组件叫 vSelect 下面会用-->
<template>
  <el-select
  @change="handleChange"
  v-model="value"
  :placeholder="请选择">
    <el-option
    v-for="(item,index) in options"
    :key="index"
    :label="item.label"
    :value="item.value">
    </el-option>
  </el-select>
</template>

<script>
 export default {
  data() {
    return {
      value: '',
    }
  },
  props:['options'],
  methods: {
    handleChange(value) {
      this.$emit('my-event',value);
    }
  },
  
 }
</script>

使用时只需把文件import进来,代码如下:

<template>
  <vSelect :options="options" @my-event="select"></vSelect>
</template>
<script>
  import vSelect from '文件路径'
  export default {
    data() {
      return {
        options: [
          {
            value:0,
            label:'选项一'
          },
          {
            value:1,
            label:'选项二'
          },
        ],
      }
    },
    components: {
      vSelect
    },
    methods: {
      select(value) {
        console.log(value)
      }
    },
  }
</script>

以上的话便可以实现一个组件的简单调用,选择后的值会从子组件传到父组件

问题:

多处使用同一个组件时,会代表不同的选项,拿到的值也需要做不同的处理,正常也可以通过写多个方法来实现对取得的值的不同处理,但是这种方法不够灵活。

解决:

此时自然而然想到的一种解决方法就是给上面的select函数再增加一个参数,根据参数不同进行不同的处理

但是真正实施起来却发现会出现很多问题。

其实解决方法很简单,就是一开始没转过来弯,还是花了一些时间,最终的解决方案就是使用回调函数:

<vSelect :options="options" @my-event="val=>select(val,param)"></vSelect>

select(value,param) {
  console.log(value,param)
}

回过头来看,真的觉的这个压根都不能算作一个问题,就当记录一下作为Vue组件使用的初级教程吧,希望能够帮助到一些人。

补充知识:VUE之组件(插槽slot与可复用组件)

插槽slot

当子组件部分内容是通过父组件传递DOM进行显示时,可以不用父组件props传值的比较挫的语法,Vue中提供了一种新型语法:插槽slot。

废话不多说看代码:

<!-- html代码 -->
 <div id="app">
  <my-blog>
  <h2>格林童话</h2>
  <cite>格林兄弟</cite>
  <p>白雪公主和七个小矮人</p>
  </my-blog>
 </div>
// vue代码
 Vue.component('my-blog',{
  template:`
  <div>
   <slot></slot>
   <span>恶毒的皇后</span>
  </div>`
 })
 var app=new Vue({
  el:"#app",
 })

命名由来:

这种语法看起来像是用子组件直接往里直接插DOM内容,所以称之为插槽。

小结:

1、插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性;

2、插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制

插槽分类有很多种,本节将一一介绍

(1)单个插槽/默认插槽

(2)具名插槽

(3)作用域插槽

(4)解构插槽

插槽分类一:单个插槽(备胎插槽)

出现缘由:

最初在 标签中的任何内容都被视为备用内容。

备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容。

插槽分类一:单个插槽(备胎)

(1)宿主元素不为空时,显示宿主元素里内容,不显示备用内容

<!-- html代码 -->
 <div id="app">
  <my-blog></my-blog>
 </div>
// vue代码
 Vue.component('my-blog',{
  template:`
  <div>
   <slot>备用内容</slot>
   <span>恶毒的皇后</span>
  </div>`
 })
 var app=new Vue({
  el:"#app",
 })

注意:此时上面没有内容的情况下会自动填上默认的内容

官方文档描述:

Vue 实现了一套内容分发的 API,将 元素作为承载分发内容的出口

插槽内可以包含任何模板代码,包括 HTML模板代码,甚至可以是其它的组件。

通俗理解:

没有插槽的情况下在组件标签内写一些内容是不起任何作用的,当在组件中声明了插槽元素后,在组件元素内写的内容就会跑到它这里了,即插槽此时充当承载分发内容的出口!

具名插槽

首先看个案例,结合案例了解下具名插槽的概念

(1)在子组件中定义了三个slot标签,其中有两个分别添加了name属性header和footer。即通过给slot添加name属性,来指定当前slot的名字

<!-- html代码 -->
 <div id="app">
  <my-blog>
  <h2 slot="header">格林童话</h2>
  <cite>格林兄弟</cite>
  <p slot="footer">白雪公主和七个小矮人</p>
  </my-blog>
 </div>
// vue代码
 Vue.component('my-blog',{
  template:`
  <div>
   <slot name="header"></slot>
   <span>恶毒的皇后</span>
   <slot></slot>
   <slot name="footer"></slot>
  </div>`
 })
 var app=new Vue({
  el:"#app",
 })

具名插槽小结

(1)具名插槽其实就是在父组件中添加一个 slot=‘自定义名字' 的属性,然后在子组件中的 里面添加 name=‘自定义名字' 即可

(2)如果父组件中有一部分没有添加 slot 属性,则此处就是默认的插槽,在子组件中的 直接就是使用的父组件的默认插槽部分

(3)如果没有默认插槽,这些找不到匹配的内容片段将被抛弃。

作用域插槽slot

简介:

作用域插槽为Vue2.1.0版本新增,是一种特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。

父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

不过,我们可以在父组件中使用 slot-scope 特性从子组件获取数据。前提是需要在子组件中使用 :data=data 先传递 data 的数据。

作用域插槽案例:

<!-- html代码 -->
 <div id="app">
  <!-- 利用solt-scope获取数据 -->
  <my-blog>
  <template slot-scope="props">
   {{props.data}}
  </template>
  </my-blog>
 </div>
 // vue代码 
 // 1.子组件传递数据
 Vue.component('my-blog', {
  template: `<div>
  <slot :data="text"></slot>
  
  </div>`,
  data() {
  return {
   text: '喜欢福安'
  }
  }
 })
 var app = new Vue({
  el: "#app",
 })

注意:

(1)在父级中,具有特殊特性 slot-scope 的 元素必须存在,表示它是作用域插槽的模板(在 2.5.0+,slot-scope 能被用在任意元素或组件中而不再局限于 )。

(2)slot-scope 的值将被用作一个临时变量名,此变量接收从子组件传递过来的 prop 对象

(3)在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样,接下来父组件中使用 slot-scope 特性从子组件获取数据

案例:blog子组件可能在很多地方调用,希望在不同地方调用blog组件时

但是:注意这里要求列表的循环和样式不是由子组件决定,而是外部决定的,修改代码如下

<!-- html代码 -->
 <div id="app">
  <!-- 利用solt-scope获取数据 -->
  <my-blog>
  <template slot-scope="props">
   <h1>{{props.data}}</h1>
  </template>
  </my-blog>
  <my-blog>
  <template slot-scope="props">
   <h4>{{props.data}}</h4>
  </template>
  </my-blog>
 </div>
// vue代码 
 // 1.子组件传递数据
 Vue.component('my-blog', {
  template: `
  <div>
  <ul>
   <li v-for="text of texts">
   <slot :data="text"></slot>
   </li>
  </ul>
  </div>`,
  data() {
  return {
   texts: ["汪汪队","彩虹宝宝","天线宝宝","苏菲亚","大头儿子小头爸爸","熊出没"]
  }
  }
 })
 var app = new Vue({
  el: "#app",
 })

条件判断渲染

到目前为止,便可以在元素上随便操作了

例如:当名字长度等于3的时候,在前面加个“你好”标志

代码如下

<!-- html代码 -->
 <div id="app">
  <!-- 利用solt-scope获取数据 -->
  <my-blog>
  <template slot-scope="props">
   <h1 v-if="props.data.length==3">新推荐--{{props.data}}</h1>
   <h1 v-else>{{props.data}}</h1>
  </template>
  </my-blog>
  
 </div>
 // vue代码 
 // 1.子组件传递数据
 Vue.component('my-blog', {
  template: `
  <div>
  <ul>
   <li v-for="text of texts">
   <slot :data="text"></slot>
   </li>
  </ul>
  </div>`,
  data() {
  return {
   texts: ["汪汪队","彩虹宝宝","天线宝宝","苏菲亚","大头儿子小头爸爸","熊出没"]
  }
  }
 })
 var app = new Vue({
  el: "#app",
 })

作用域插槽slot-scrop新语法

版本:自 2.6.0 起有所更新,已废弃使用 slot-scope 语法,开始使用v-slot进行替代,如下所示

<!-- html代码 -->
 <div id="app">
  <!-- 利用solt-scope获取数据 -->
  <my-blog>
  <template v-slot="props">
   <h1 v-if="props.data.length==3">新推荐--{{props.data}}</h1>
   <h1 v-else>{{props.data}}</h1>
  </template>
  </my-blog>
  
 </div>

解构插槽:

v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JS表达式。所以在支持的环境下 (单文件组件或现代浏览器),你也可以使用 ES2015 解构来传入具体的插槽 prop,如下:

<!-- html代码 -->
 <div id="app">
  <!-- 利用solt-scope获取数据 -->
  <my-blog>
  <template v-slot="{data}">
   <h1 v-if="data.length==3">新推荐--{{data}}</h1>
   <h1 v-else>{{data}}</h1>
  </template>
  </my-blog>
 </div>
// vue代码 
 // 1.子组件传递数据
 Vue.component('my-blog', {
  template: `
  <div>
  <ul>
   <li v-for="text of texts">
   <slot :data="text"></slot>
   </li>
  </ul>
  </div>`,
  data() {
  return {
   texts: ["汪汪队","彩虹宝宝","天线宝宝","苏菲亚","大头儿子小头爸爸","熊出没"]
  }
  }
 })
 var app = new Vue({
  el: "#app",
 })

作用域插槽slot-scrop新语法

你甚至可以定义后备内容,用于插槽 prop 是 undefined 的情形

<!-- html代码 -->
 <div id="app">
  <!-- 利用solt-scope获取数据 -->
  <my-blog>
  <template v-slot="{data='这部电视禁播了'}">
   <h1 v-if="data.length==3">新推荐--{{data}}</h1>
   <h1 v-else>{{data}}</h1>
  </template>
  </my-blog>
 </div>
// vue代码 
 // 1.子组件传递数据
 Vue.component('my-blog', {
  template: `
  <div>
  <ul>
   <li v-for="text of texts">
   <slot :data="text"></slot>
   </li>
  </ul>
  </div>`,
  data() {
  return {
   texts: ["汪汪队","彩虹宝宝","天线宝宝","苏菲亚",undefined,"熊出没"]
  }
  }
 })
 var app = new Vue({
  el: "#app",
 })

编写可复用组件注意事项:

在编写组件时,最好考虑好以后是否要进行复用。一次性组件间有紧密的耦合没关系,但是可复用组件应当定义一个清晰的公开接口,同时也不要对其使用的外层数据作出任何假设。

Vue 组件的 API 来自三部分——prop、事件和插槽:

1、Prop 允许外部环境传递数据给组件;

2、事件允许从组件内触发外部环境的副作用;

3、插槽允许外部环境将额外的内容组合在组件中。

以上这篇Vue 组件复用多次自定义参数操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Using the TextRange Object
Oct 14 Javascript
用javascript实现自定义标签
May 08 Javascript
js 跨域和ajax 跨域问题小结
Jul 01 Javascript
JavaScript闭包实例讲解
Apr 22 Javascript
JS生成不重复随机数组的函数代码
Jun 10 Javascript
JQuery datepicker 用法详解
Dec 25 Javascript
Javascript之String对象详解
Jun 08 Javascript
javascript ES6中箭头函数注意细节小结
Feb 17 Javascript
JS实现的tab切换选项卡效果示例
Feb 28 Javascript
Angular4学习教程之DOM属性绑定详解
Jan 04 Javascript
JS实现碰撞检测的方法分析
Jan 19 Javascript
Vue快速实现通用表单验证的方法
Feb 24 Javascript
使用Element的InfiniteScroll 无限滚动组件报错的解决
Jul 27 #Javascript
Element InfiniteScroll无限滚动的具体使用方法
Jul 27 #Javascript
vue中父子组件传值,解决钩子函数mounted只运行一次的操作
Jul 27 #Javascript
Element Alert警告的具体使用方法
Jul 27 #Javascript
Element Badge标记的使用方法
Jul 27 #Javascript
谈一谈vue请求数据放在created好还是mounted里好
Jul 27 #Javascript
JS倒计时两种实现方式代码实例
Jul 27 #Javascript
You might like
经典的星际争霸,满是回忆的BGM
2020/04/09 星际争霸
晶体管来复再生式二管收音机
2021/03/02 无线电
某大型网络公司应聘时的笔试题目附答案
2008/03/27 PHP
PHP正确配置mysql(apache环境)
2011/08/28 PHP
使用PHP和JavaScript判断请求是否来自微信内浏览器
2015/08/18 PHP
PHP基于curl post实现发送url及相关中文乱码问题解决方法
2017/11/25 PHP
thinkphp3.2.0 setInc方法 源码全面解析
2018/01/29 PHP
PHP检查URL包含特定字符串实例方法
2019/02/11 PHP
根据地区不同显示时间的javascript代码
2007/08/13 Javascript
jQuery学习5 jQuery事件模型
2010/02/07 Javascript
Jquery ui css framework
2010/06/28 Javascript
javascript动画算法实例分析
2015/07/31 Javascript
jQuery unbind()方法实例详解
2016/01/19 Javascript
微信小程序 wxapp视图容器 view详解
2016/10/31 Javascript
AngularJS的ng Http Request与response格式转换方法
2016/11/07 Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
2020/05/31 Javascript
[01:08:48]LGD vs OG 2018国际邀请赛淘汰赛BO3 第三场 8.25
2018/08/29 DOTA
理论讲解python多进程并发编程
2018/02/09 Python
Python实现时间序列可视化的方法
2019/08/06 Python
学Python 3的理由和必要性
2019/11/19 Python
澳大利亚女士时装在线:Rockmans
2018/09/26 全球购物
Omio葡萄牙:全欧洲低价大巴、火车和航班搜索和比价
2019/02/09 全球购物
JBL美国官方商店:扬声器、耳机等
2019/12/01 全球购物
什么是虚拟内存?虚拟内存有什么优势?
2012/02/19 面试题
旅游管理本科生求职信
2013/10/14 职场文书
国际贸易专业个人求职信范文分享
2013/12/14 职场文书
服务员岗位职责
2014/01/29 职场文书
网络教育自我鉴定
2014/02/04 职场文书
生物学专业求职信
2014/07/23 职场文书
2014党员民主评议个人思想剖析发言
2014/09/19 职场文书
税务干部个人整改措施思想汇报
2014/10/10 职场文书
党员年终个人总结
2015/02/14 职场文书
《牧场之国》教学反思
2016/02/22 职场文书
2016个人廉洁自律承诺书
2016/03/25 职场文书
使用springMVC所需要的pom配置
2021/09/15 Java/Android
Javascript中async与await的捕捉错误详解
2022/03/03 Javascript