Vue和React的插槽怎么使用
今天小编给大家分享一下Vue和React的插槽怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
插槽,在React中没找到??
在使用Vue的时候,插槽是一个特别常用的功能,通过定义插槽,可以在调用组件的时候将外部的内容传入到组件内部,显示到指定的位置。在Vue中,插槽分为默认插槽,具名插槽和作用域插槽。其实不仅仅Vue,在 React 中其实也有类似插槽的功能,只是名字不叫做插槽,下面我将通过举例来说明。
默认插槽
现在项目需要开发一个卡片组件,卡片可以指定标题,然后卡片内容可以用户自定义,这时候对于卡片内容来说,就可以使用插槽来实现,下面我们就分别使用Vue和React来实现这个功能
Vue实现
首先实现一个card组件,如下代码所示
export default { props: { title: { type: String, default: '' } } }{{ title }}
可以看到上面我们使用了,这个就是组件的默认插槽,在使用组件的时候,传入的内容将会被放到所在位置
在外部使用定义的card组件
import MyCard from '../components/card' export default { components: { MyCard } }我将被放在card组件的默认插槽里面
如上代码,就可以使用组件的默认插槽将外部的内容应用到组件里面指定的位置了。
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 ( {props.title} {/**每个组件都可以获取到 props.children。它包含组件的开始标签和结束标签之间的内容 */} {props.children} ); } import React from 'react' import Card from './components/Card' export default function () { return ( 我将被放在card组件的body区域内容 ); }在外部使用Card组件
具名插槽
继续以上面的Card组件为例,假如我们现在需求发生了变化,组件的title也可以使用插槽,这时候对于Vue就可以使用具名插槽了,而React也是有办法实现的哦。
Vue实现
Vue的具名插槽主要解决的是一个组件需要多个插槽的场景,其实现是为`添加name`属性来实现了。
我们就上面的需求对card组件进行修改
export default { props: { title: { type: String, default: '' } }}{{ title }}
card组件修改完之后,我们再去调整一下使用card组件的地方
这里是标题import MyCard from '../components/card'export default { components: { MyCard }}我将被放在card组件的默认插槽里面
React实现
React连插槽都没有, 更别提具名插槽了,但是没有不代表不能模拟出来。对于React的props,我们不仅仅可以传入普通的属性,还可以传入一个函数,这时候我们就可以在传入的这个函数里面返回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() : {title} return ( {titleEl} {/**每个组件都可以获取到 props.children。它包含组件的开始标签和结束标签之间的内容 */} {props.children} );}这时候就可以在外部自定义title了
import React from 'react'import Card from './components/Card'export default function () { return ( { return 我是自定义的标题 } }> 我将被放在card组件的body区域内容 );}作用域插槽
有时让插槽内容能够访问子组件中才有的数据是很有用的,这个就是Vue提供作用域插槽的原因。我们继续使用上面的Card组件为例,现在我基于上面的卡片组件开发了一个人员信息卡片组件,用户直接使用人员信息卡片组件就可以将人员信息显示到界面中,但是在某些业务模块需要自定义人员信息显示方式,这时候我们就需要使用到作用域插槽了。
Vue实现
实现用户信息卡片组件,里面使用了作用域插槽
姓名: {{ userInfo.name }} 性别: {{ userInfo.sex }} 年龄: {{ userInfo.age }}import CustomCard from '../card'export default { components: { CustomCard }, data() { return { userInfo: { name: '张三', sex: '男', age: 25 } } }}
在外部使用人员信息组件
import UserCard from '../components/user-card'export default { components: { UserCard }}
- 姓名: {{ userInfo.name }}
- 年龄: {{ userInfo.age }}
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) ) : ( 姓名: {userInfo.name} 年龄: {userInfo.age} 性别: {userInfo.sex} ); return {content} }在外部使用人员信息卡片组件
import React from 'react' import UserCard, { UserInfo } from "./components/UserCard"; export default function () { return ( { return ( - 姓名: {userInfo.name}
); }} > ); }Context, React中的provide/inject
通常我们在项目开发中,对于多组件之间的状态管理,在Vue中会使用到Vuex,在React中会使用到redux或者Mobx,但对于小项目来说,使用这些状态管理库就显得比较大材小用了,那么在不使用这些库的情况下,如何去完成数据管理呢?比如面试最常问的祖孙组件通信。在Vue中我们可以使用provide/inject,在React中我们可以使用Context。
假设有这样一个场景,系统现在需要提供一个换肤功能,用户可以切换皮肤,现在我们分别使用Vue和React来实现这个功能。
Vue中的provide/inject
在Vue中我们可以使用provide/inject来实现跨多级组件进行传值,就以上面所说场景为例,我们使用provide/inject来实现以下
首先,修改App.vue内容为以下内容
export default { data() { return { themeInfo: { theme: 'dark' } } }, provide() { return { theme: this.themeInfo } }}
然后在任意层级的子组件中像下面这样使用
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.Provider将theme共享出去
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 }没有了v-model,但也不影响使用
我们知道React和Vue都是单向数据流的,即数据的流向都是由外层向内层组件进行传递和更新的,比如下面这段React代码就是标准的单向数据流.
import React, { useState } from "react";export default function(){ const [name] = useState('子君') return }在vue中使用v-model
如上代码,我们在通过通过value属性将外部的值传递给了input组件,这个就是一个简单的单向数据流。但是在使用Vue的时候,还有两个比较特殊的语法糖v-model和.sync,这两个语法糖可以让Vue组件拥有双向数据绑定的能力,比如下面的代码
export default { data() { return { name:'子君' } } }通过v-model,当用户修改input的值的时候,外部的name的值也将同步被修改。但这是Vue的语法糖啊,React是不支持的,所以React应该怎么办呢?这时候再想想自定义v-model,v-model实际上是通过定义value属性同时监听input事件来实现的,比如这样:
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 }小编刚开始使用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 handleChange(e, setName)}> handleChange(e, setSex)}> }没有了指令,我感觉好迷茫
在Vue中我们一般绘制页面都会使用到template,template里面提供了大量的指令帮助我们完成业务开发,但是在React中使用的是JSX,并没有指令,那么我们应该怎么做呢?下面我们就将Vue中最常用的一些指令转换为JSX里面的语法(注意: 在Vue中也可以使用JSX)
v-show与v-if
在Vue中我们隐藏显示元素可以使用v-show或者v-if,当然这两者的使用场景是有所不同的,v-show是通过设置元素的display样式来显示隐藏元素的,而v-if隐藏元素是直接将元素从dom中移除掉。
看一下Vue中的v-show与v-if的用法
姓名:{{ name }} {{ dept }} export default { data() { return { name: '子君', dept: '银河帝国', showName: false, showDept: true } } }
将v-show,v-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 ( {/**模拟 v-show */} {userInfo.name} {/**模拟 v-show */} {showDept ? {userInfo.dept}: undefined} ) }v-for
v-for在Vue中是用来遍历数据的,同时我们在使用v-for的时候需要给元素指定key,key的值一般是数据的id或者其他唯一且固定的值。不仅在Vue中,在React中也是存在key的,两者的key存在的意义基本一致,都是为了优化虚拟DOM diff算法而存在的。
在Vue中使用v-for
- {{ item.name }}
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 ( { data.map(item => { return - {item.name}
}) }
) }v-bind与v-on
v-bind在Vue中是动态绑定属性的,v-on是用于监听事件的,因为React也有属性和事件的概念,所以我们在React也能发现可替代的方式。
在Vue中使用v-bind与v-on
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 ( ) }使用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 ( ) }以上就是"Vue和React的插槽怎么使用"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。
组件
插槽
内容
属性
事件
数据
代码
功能
卡片
元素
作用
函数
语法
面的
员信息
时候
标签
姓名
就是
指令
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
avast 网络安全软件
c语言同时测试多组数据库
sql 连接外部数据库
保护自己网络安全的做法
国内网络安全性
办公室设置代理服务器
哈密软件开发招聘
安徽时代网络技术分类产品介绍
我国网络安全法颁布的顺序
将云硬盘挂载给弹性云服务器
高效的深圳软件开发公司
pc服务器小型机
北京服务器迁移云主机
服务器显网络连接失败
高中网络安全视频
弘达科技软件开发
网络安全新技术应用培训
无锡智能软件开发大全
http代理服务器实现
戴尔数据库加速
avast 网络安全软件
希利蓝点没有共振数据库
苏州戴尔服务器哪里买
计算机网络技术什么的
职高数据库应用技术知识点
怎么用云服务器搭建视频app
域名和服务器购买价格
服务器电脑主板
通信网络技术中fr指
crm软件开发 彦夏