iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Vue和React的插槽怎么使用
  • 835
分享到

Vue和React的插槽怎么使用

2023-06-27 10:06:04 835人浏览 独家记忆
摘要

今天小编给大家分享一下Vue和React的插槽怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。插槽,在React中没找

今天小编给大家分享一下VueReact的插槽怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

插槽,在React中没找到??

在使用Vue的时候,插槽是一个特别常用的功能,通过定义插槽,可以在调用组件的时候将外部的内容传入到组件内部,显示到指定的位置。在Vue中,插槽分为默认插槽,具名插槽和作用域插槽。其实不仅仅Vue,在 React 中其实也有类似插槽的功能,只是名字不叫做插槽,下面我将通过举例来说明。

默认插槽

现在项目需要开发一个卡片组件,卡片可以指定标题,然后卡片内容可以用户自定义,这时候对于卡片内容来说,就可以使用插槽来实现,下面我们就分别使用VueReact来实现这个功能

Vue实现

首先实现一个card组件,如下代码所示

        <div class="card">       <div class="card__title">         <span>{{ title }}</span>       </div>       <div class="card__body">                </div>     </div>         export default {     props: {       title: {         type: String,         default: ''       }     }   }

可以看到上面我们使用了,这个就是组件的默认插槽,在使用组件的时候,传入的内容将会被放到所在位置

在外部使用定义的card组件

        <div>                <div>我将被放在card组件的默认插槽里面</div>            </div>         import MyCard from '../components/card'   export default {     components: {       MyCard     }   }

如上代码,就可以使用组件的默认插槽将外部的内容应用到组件里面指定的位置了。

React实现

虽然在React里面没有插槽的概念,但是React里面也可以通过props.children拿到组件标签内部的子元素的,就像上面代码`标签内的子元素,通过这个我们也可以实现类似Vue`默认插槽的功能,一起看看代码。

使用React定义Card组件

   import React from 'react'      export interface CardProps {     title: string,     children: React.Reactnode   }      export default function(props: CardProps) {        return (       <div className="card">         <div className="card__title">           <span>{props.title}</span>         </div>         <div className="card__body">           {}           {props.children}         </div>       </div>     );   }
   import React from 'react'   import Card from './components/Card'      export default function () {        return (       <div>                    <div>我将被放在card组件的body区域内容</div>                </div>     );   }

在外部使用Card组件

具名插槽

继续以上面的Card组件为例,假如我们现在需求发生了变化,组件的title也可以使用插槽,这时候对于Vue就可以使用具名插槽了,而React也是有办法实现的哦。

Vue实现

Vue的具名插槽主要解决的是一个组件需要多个插槽的场景,其实现是为`添加name`属性来实现了。

我们就上面的需求对card组件进行修改

  <div class="card">    <div class="card__title">            <span v-if="title">{{ title }}</span>          </div>    <div class="card__body">                </div>  </div>export default {  props: {    title: {      type: String,      default: ''    }  }}

card组件修改完之后,我们再去调整一下使用card组件的地方

  <div>                        <span>这里是标题</span>            <div>我将被放在card组件的默认插槽里面</div>      </div>import MyCard from '../components/card'export default {  components: {    MyCard  }}
React实现

React连插槽都没有, 更别提具名插槽了,但是没有不代表不能模拟出来。对于Reactprops,我们不仅仅可以传入普通的属性,还可以传入一个函数,这时候我们就可以在传入的这个函数里面返回jsX,从而就实现了具名插槽的功能。

对原有的Card组件进行修改

import React from 'react'export interface CardProps {  title?: string,  // 加入了一个renderTitle属性,属性类型是Function  renderTitle?: Function,  children: React.ReactNode}export default function(props: CardProps) {  const {title, renderTitle} = props  // 如果指定了renderTtile,则使用renderTitle,否则使用默认的title  let titleEl = renderTitle ? renderTitle() : <span>{title}</span>  return (    <div className="card">      <div className="card__title">{titleEl}</div>      <div className="card__body">        {}        {props.children}      </div>    </div>  );}

这时候就可以在外部自定义title

import React from 'react'import Card from './components/Card'export default function () {  return (    <div>       {          return <span>我是自定义的标题</span>        }      }>        <div>我将被放在card组件的body区域内容</div>          </div>  );}
作用域插槽

有时让插槽内容能够访问子组件中才有的数据是很有用的,这个就是Vue提供作用域插槽的原因。我们继续使用上面的Card组件为例,现在我基于上面的卡片组件开发了一个人员信息卡片组件,用户直接使用人员信息卡片组件就可以将人员信息显示到界面中,但是在某些业务模块需要自定义人员信息显示方式,这时候我们就需要使用到作用域插槽了。

Vue实现

实现用户信息卡片组件,里面使用了作用域插槽

      <div class="content">                            <span>姓名: {{ userInfo.name }}</span>        <span>性别: {{ userInfo.sex }}</span>        <span>年龄: {{ userInfo.age }}</span>          </div>  import CustomCard from '../card'export default {  components: {    CustomCard  },  data() {    return {      userInfo: {        name: '张三',        sex: '男',        age: 25      }    }  }}

在外部使用人员信息组件

  <div>                  <div class="custom-user">          <ul>            <li>姓名: {{ userInfo.name }}</li>            <li>年龄: {{ userInfo.age }}</li>          </ul>        </div>            </div>import UserCard from '../components/user-card'export default {  components: {    UserCard  }}
React实现

在具名插槽那一小节我们通过给组件传入了一个函数,然后在函数中返回JSX的方式来模拟了具名插槽,那么对于作用域插槽,我们依然可以使用函数的这种方式,而作用域插槽传递的参数我们可以使用给函数传参的方式来替代

实现人员信息卡片组件

   import React, { useState } from 'react'      import Card from './Card'      interface UserCardProps {     renderUserInfo?: Function   }      export interface UserInfo {     name: string;     age: number;     sex: string;   }      export default function(props: UserCardProps) {     const [userInfo] = useState({       name: "张三",       age: 25,       sex: "男",     });        const content = props.renderUserInfo ? (       props.renderUserInfo(userInfo)     ) : (       <div>         <span>姓名: {userInfo.name}</span>         <span>年龄: {userInfo.age}</span>         <span>性别: {userInfo.sex}</span>       </div>     );        return        {content}        }

在外部使用人员信息卡片组件

   import React from 'react'   import UserCard, { UserInfo } from "./components/UserCard";      export default function () {        return (       <div>          {             return (               <ul>                 <li>姓名: {userInfo.name}</li>               </ul>             );           }}         >       </div>     );   }

Context, React中的provide/inject

通常我们在项目开发中,对于多组件之间的状态管理,在Vue中会使用到Vuex,在React中会使用到redux或者Mobx,但对于小项目来说,使用这些状态管理库就显得比较大材小用了,那么在不使用这些库的情况下,如何去完成数据管理呢?比如面试最常问的祖孙组件通信。在Vue中我们可以使用provide/inject,在React中我们可以使用Context

假设有这样一个场景,系统现在需要提供一个换肤功能,用户可以切换皮肤,现在我们分别使用VueReact来实现这个功能。

Vue中的provide/inject

Vue中我们可以使用provide/inject来实现跨多级组件进行传值,就以上面所说场景为例,我们使用provide/inject来实现以下

首先,修改App.vue内容为以下内容

  <div id="app">      </div>export default {  data() {    return {      themeInfo: {        theme: 'dark'      }    }  },  provide() {    return {      theme: this.themeInfo    }  }}

然后在任意层级的子组件中像下面这样使用

  <div :class="`child-${theme.theme}`">  </div>export default {  inject: ['theme']}

这样就可以实现theme在所有子组件中进行共享了

React中的Context

Vue中我们使用provide/inject实现了组件跨层级传值功能,在React中也提供了类似的功能即Context,下面我们使用Context来实现相同的功能。

在项目src目录下新建context目录,添加MyContext.js文件,然后添加以下内容

import {createContext} from 'react'// 定义 MyContext,指定默认的主题为`light`export const MyContext = createContext({  theme: 'light'})

MyContext提供了一个Provider,通过Provider可以将theme共享到所有的子组件。现在我们在所有的组件的共同父组件比如App.js上面添加MyContext.Providertheme共享出去

import { MyContext } from '@/context/MyContext';export default function() {    const [theme, setTheme] = useState('dark')    return (                     )  }

然后这时候就可以直接在所有的子组件里面使用定义的主题theme

import React, { useContext } from 'react'import { MyContext } from '@/context/MyContext';export default function() {   const {theme}  = useContext(MyContext)   return <div className={`child-${theme}`}>}

没有了v-model,但也不影响使用

我们知道ReactVue都是单向数据流的,即数据的流向都是由外层向内层组件进行传递和更新的,比如下面这段React代码就是标准的单向数据流.

import React, { useState } from "react";export default function(){  const [name] = useState('子君')  return <input value={name}></input>}
vue中使用v-model

如上代码,我们在通过通过value属性将外部的值传递给了input组件,这个就是一个简单的单向数据流。但是在使用Vue的时候,还有两个比较特殊的语法糖v-model.sync,这两个语法糖可以让Vue组件拥有双向数据绑定的能力,比如下面的代码

   <input v-model="name"/>  export default {    data() {      return {        name:'子君'      }    }  }

通过v-model,当用户修改input的值的时候,外部的name的值也将同步被修改。但这是Vue的语法糖啊,React是不支持的,所以React应该怎么办呢?这时候再想想自定义v-modelv-model实际上是通过定义value属性同时监听input事件来实现的,比如这样:

  <div class="custom-input">     <input :value="value" @input="$_handleChange"/>  </div>  export default {    props:{      value:{        type: String,        default: ''      }    },    methods:{      $_handleChange(e) {        this.$emit('input', e.target.value)      }    }  }
react寻找v-model替代方案

同理,React虽然没有v-model语法糖,但是也可以通过传入属性然后监听事件来实现数据的双向绑定。

import React, { useState } from 'react'export default function() {  const [name, setName] = useState('子君')  const handleChange = (e) => {    setName(e.target.value)  }  return <div>    <input value={name} onChange={handleChange}></input>  </div>}

小编刚开始使用react,感觉没有v-model就显得比较麻烦,不过麻烦归麻烦,代码改写也要写。就像上文代码一样,每一个表单元素都需要监听onChange事件,越发显得麻烦了,这时候就可以考虑将多个onChange事件合并成一个,比如像下面代码这样

import React, { useState } from 'react'export default function () {  const [name, setName] = useState('子君')  const [sex, setSex] = useState('男')  const handleChange = (e:any, method: Function) => {    method(e.target.value)  }  return <div>    <input value={name} onChange={(e) => handleChange(e, setName)}></input>    <input value={sex} onChange={(e) => handleChange(e, setSex)}></input>  </div>}

没有了指令,我感觉好迷茫

Vue中我们一般绘制页面都会使用到templatetemplate里面提供了大量的指令帮助我们完成业务开发,但是在React中使用的是JSX,并没有指令,那么我们应该怎么做呢?下面我们就将Vue中最常用的一些指令转换为JSX里面的语法(注意: 在Vue中也可以使用JSX)

v-showv-if

Vue中我们隐藏显示元素可以使用v-show或者v-if,当然这两者的使用场景是有所不同的,v-show是通过设置元素的display样式来显示隐藏元素的,而v-if隐藏元素是直接将元素从dom中移除掉。

看一下Vue中的v-showv-if的用法

        <div>       <span v-show="showName">姓名:{{ name }}</span>       <span v-if="showDept">{{ dept }}</span>     </div>         export default {     data() {       return {         name: '子君',         dept: '银河帝国',         showName: false,         showDept: true       }     }   }

v-showv-if转换为JSX中的语法

Vue中指令是为了在template方便动态操作数据而存在的,但是到了React中我们写的是JSX,可以直接使用JS,所以指令是不需要存在的,那么上面的v-show,v-if如何在JSX中替代呢

   import React, { useState } from 'react'      export default function() {     const [showName] = useState(false)        const [showDept] = useState(true)        const [userInfo] = useState({       name:'子君',       dept: '银河帝国'     })        return (       <div>         {}         <span style={{display: showName ? 'block' : 'none'}}>{userInfo.name}</span>         {}         {showDept ? <span>{userInfo.dept}</span>: undefined}       </div>     )   }
v-for

v-forVue中是用来遍历数据的,同时我们在使用v-for的时候需要给元素指定keykey的值一般是数据的id或者其他唯一且固定的值。不仅在Vue中,在React中也是存在key的,两者的key存在的意义基本一致,都是为了优化虚拟DOM diff算法而存在的。

Vue中使用v-for

        <div>       <ul>         <li v-for="item in list" :key="item.id">           {{ item.name }}         </li>       </ul>     </div>         export default {     data() {       return {         list: [           {             id: 1,             name: '子君'           },           {             id: '2',             name: '张三'           },           {             id: '3',             name: '李四'           }         ]       }     }   }

React中使用v-for的替代语法

react中虽然没有v-for,但是JSX中可以直接使用JS,所以我们可以直接遍历数组

   import React from 'react'      export default function() {     const data = [       {         id: 1,         name: "子君",       },       {         id: "2",         name: "张三",       },       {         id: "3",         name: "李四",       },     ];        return (       <div>         <ul>           {           data.map(item => {             return <li key={item.id}>{item.name}</li>           })         }         </ul>       </div>     )   }
v-bindv-on

v-bindVue中是动态绑定属性的,v-on是用于监听事件的,因为React也有属性和事件的概念,所以我们在React也能发现可替代的方式。

Vue中使用v-bindv-on

        <div>              <input :value="value" @input="handleInput" />     </div>         export default {     data() {       return {         value: '子君'       }     },     methods: {       handleInput(e) {         this.value = e.target.value       }     }   }

React中寻找替代方案

Vue中,作者将事件和属性进行了分离,但是在React中,其实事件也是属性,所以在本小节我们不仅看一下如何使用属性和事件,再了解一下如何在React中自定义事件

开发一个CustomInput组件

   import React from 'react'      export interface CustomInputProps {     value: string;     //可以看出 onChange是一个普通的函数,也被定义到了组件的props里面了     onChange: ((value: string,event: React.ChangeEvent) => void) | undefined;   }      export default function(props: CustomInputProps) {          function handleChange(e: React.ChangeEvent) {       // props.onChange是一个属性,也是自定义的一个事件       props.onChange && props.onChange(e.target.value, e)     }        return (       <input value={props.value} onChange={handleChange}></input>     )   }

使用CustomInput组件

   import React, { useState } from 'react'      import CustomInput from './components/CustomInput'      export default function() {    const [value, setValue] =  useState('')       function handleChange(value: string) {      setValue(value)    }        return (       <div>                </div>     )   }

以上就是“Vue和React的插槽怎么使用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: Vue和React的插槽怎么使用

本文链接: https://www.lsjlt.com/news/309702.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 生态系统中流行库和框架的贡献指南
    作为 c++++ 开发人员,通过遵循以下步骤即可为流行库和框架做出贡献:选择一个项目并熟悉其代码库。在 issue 跟踪器中寻找适合初学者的问题。创建一个新分支,实现修复并添加测试。提交...
    99+
    2024-05-15
    框架 c++ 流行库 git
  • C++ 生态系统中流行库和框架的社区支持情况
    c++++生态系统中流行库和框架的社区支持情况:boost:活跃的社区提供广泛的文档、教程和讨论区,确保持续的维护和更新。qt:庞大的社区提供丰富的文档、示例和论坛,积极参与开发和维护。...
    99+
    2024-05-15
    生态系统 社区支持 c++ overflow 标准库
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-15
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-15
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-15
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-15
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-15
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-15
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-15
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-15
    golang 数据库备份 mysql git 标准库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作