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 相关文章推荐
用于table内容排序
Jul 21 Javascript
JavaScript执行顺序详细介绍
Dec 04 Javascript
使用focus方法让光标默认停留在INPUT框
Jul 29 Javascript
JavaScript判断变量是对象还是数组的方法
Aug 28 Javascript
JavaScript设计模式经典之命令模式
Feb 24 Javascript
JS hashMap实例详解
May 26 Javascript
Vue引用第三方datepicker插件无法监听datepicker输入框的值的解决
Jan 27 Javascript
Element Input组件分析小结
Oct 11 Javascript
小程序实现人脸识别功能(百度ai)
Dec 23 Javascript
vue + elementUI实现省市县三级联动的方法示例
Oct 29 Javascript
Vue export import 导入导出的多种方式与区别介绍
Feb 12 Javascript
js闭包和垃圾回收机制示例详解
Mar 01 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
Cannot modify header information错误解决方法
2008/10/08 PHP
PHP中copy on write写时复制机制介绍
2014/05/13 PHP
PHP处理大量表单字段的便捷方法
2015/02/07 PHP
ThinkPHP使用Smarty第三方插件方法小结
2016/03/19 PHP
php 实现银联商务H5支付的示例代码
2019/10/12 PHP
Javascript打印网页部分内容的脚本
2008/11/17 Javascript
JS将数字转换成三位逗号分隔的样式(示例代码)
2014/02/19 Javascript
深入剖析JavaScript中的枚举功能
2014/03/06 Javascript
jquery使用ajax实现微信自动回复插件
2014/04/28 Javascript
JavaScript中的变量作用域介绍
2014/12/31 Javascript
jQuery实现企业网站横幅焦点图切换功能实例
2015/04/30 Javascript
jQuery实现仿百度帖吧头部固定导航效果
2015/08/07 Javascript
JavaScript为事件句柄绑定监听函数实例详解
2015/12/15 Javascript
移动端滑动插件Swipe教程
2016/10/16 Javascript
bootstrap实现的自适应页面简单应用示例
2017/03/09 Javascript
浅谈nodejs中的类定义和继承的套路
2017/07/26 NodeJs
JavaScript与Java正则表达式写法的区别介绍
2017/08/15 Javascript
jQuery的Ajax接收java返回数据方法
2018/08/11 jQuery
JavaScript函数的特性与应用实践深入详解
2018/12/30 Javascript
vue进入页面时不在顶部,检测滚动返回顶部按钮问题及解决方法
2019/10/30 Javascript
js+cavans实现图片滑块验证
2020/09/29 Javascript
Vue实现购物小球抛物线的方法实例
2020/11/22 Vue.js
python实现在控制台输入密码不显示的方法
2015/07/02 Python
详解Python3.6安装psutil模块和功能简介
2018/05/30 Python
Django 通过JS实现ajax过程详解
2019/07/30 Python
Python之Numpy的超实用基础详细教程
2019/10/23 Python
Python 3.8 新功能大揭秘【新手必学】
2020/02/05 Python
找Python安装目录,设置环境路径以及在命令行运行python脚本实例
2020/03/09 Python
OpenCV灰度化之后图片为绿色的解决
2020/12/01 Python
html5 拖拽上传图片实例演示
2013/04/01 HTML / CSS
俄语翻译实习生的自我评价分享
2013/11/06 职场文书
办理信用卡工作证明
2014/01/11 职场文书
工程采购员岗位职责
2014/03/09 职场文书
马智宇婚礼主持词
2014/03/22 职场文书
导游词之白茶谷九龙峡
2019/10/23 职场文书
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers