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 相关文章推荐
jquery实现邮箱自动补全功能示例分享
Feb 17 Javascript
jQuery 实现侧边浮动导航菜单效果
Dec 26 Javascript
jQuery处理图片加载失败的常用方法
Jun 08 Javascript
JavaScript实现弹出模态窗体并接受传值的方法
Feb 12 Javascript
JS实现六位字符密码输入器功能
Aug 19 Javascript
javascript正则表达式模糊匹配IP地址功能示例
Jan 06 Javascript
jQuery动态移除和添加背景图片的方法详解
Mar 07 Javascript
Node.JS 循环递归复制文件夹目录及其子文件夹下的所有文件
Sep 18 Javascript
微信小程序使用navigateTo数据传递的实例
Sep 26 Javascript
AngularJS使用ng-repeat遍历二维数组元素的方法详解
Nov 11 Javascript
vue3修改link标签默认icon无效问题详解
Oct 09 Javascript
html5中sharedWorker实现多页面通信的示例代码
May 07 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
javascript下操作css的float属性的特殊写法
2007/08/22 Javascript
JavaScript 三种创建对象的方法
2009/10/16 Javascript
加载远程图片时,经常因为缓存而得不到更新的解决方法(分享)
2013/06/26 Javascript
JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享
2013/07/02 Javascript
NodeJS学习笔记之Http模块
2015/01/13 NodeJs
JavaScript简介_动力节点Java学院整理
2017/06/26 Javascript
提升页面加载速度的插件InstantClick
2017/09/12 Javascript
VUE实现一个分页组件的示例
2017/09/13 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
2018/01/06 jQuery
vue 项目中使用Loading组件的示例代码
2018/08/31 Javascript
详解Vue2 添加对scss的支持
2019/01/02 Javascript
如何在微信小程序中实现Mixins方案
2019/06/20 Javascript
在layui中layer弹出层点击事件无效的解决方法
2019/09/05 Javascript
Node.js API详解之 vm模块用法实例分析
2020/05/27 Javascript
[26:40]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第一局
2016/02/25 DOTA
手动实现把python项目发布为exe可执行程序过程分享
2014/10/23 Python
Python列表生成器的循环技巧分享
2015/03/06 Python
python监控文件或目录变化
2016/06/07 Python
python使用fcntl模块实现程序加锁功能示例
2017/06/23 Python
解决pycharm安装后代码区不能编辑的问题
2018/10/28 Python
详解PyCharm+QTDesigner+PyUIC使用教程
2019/06/13 Python
Python 将json序列化后的字符串转换成字典(推荐)
2020/01/06 Python
tensorflow模型继续训练 fineturn实例
2020/01/21 Python
纯css3实现效果超级炫的checkbox复选框和radio单选框
2014/09/01 HTML / CSS
THE OUTNET英国官网:国际设计师品牌折扣网站
2016/08/14 全球购物
2019年.net常见面试问题
2012/02/12 面试题
带病坚持工作事迹
2014/05/03 职场文书
2014年乡镇领导个人整改措施
2014/09/19 职场文书
违反单位工作制度检讨书
2014/10/25 职场文书
检查机关领导群众路线教育实践活动个人整改措施
2014/10/28 职场文书
团结友爱主题班会
2015/08/13 职场文书
公安纪律作风整顿心得体会
2016/01/23 职场文书
《画家和牧童》教学反思
2016/02/17 职场文书
Python基础之元编程知识总结
2021/05/23 Python
排查MySQL生产环境索引没有效果
2022/04/11 MySQL
JDK8中String的intern()方法实例详细解读
2022/09/23 Java/Android