其实props的问题并不复杂,但是又很多的朋友都不太了解prop是什么意思中文翻译,因此呢,今天小编就来为大家分享props的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
在舞台表演、影视制作等领域,你是否经常听到“props”这个词?它究竟是什么?又为何如此重要?今天,就让我们一起来揭秘“props”——这个舞台上的秘密武器,看看它是如何助你成为焦点的。
一、什么是props?
让我们来明确一下“props”的定义。在英语中,“props”指的是“道具”,而在舞台上,它则特指用于舞台表演的物品。这些物品可以是真实存在的,如椅子、桌子、武器等,也可以是虚拟的,如魔法棒、幽灵等。
二、props在舞台表演中的作用
1. 增强舞台氛围:通过合适的props,可以营造出独特的舞台氛围,让观众更好地沉浸在表演中。例如,在古装剧中,使用古董家具、装饰品等道具,可以让观众仿佛穿越时空,感受到古代的韵味。
2. 丰富表演内容:props可以丰富表演内容,为演员提供更多表现手法。比如,在魔术表演中,使用神奇的道具可以让观众惊叹不已;在戏剧表演中,使用逼真的武器可以让演员更加投入角色。
3. 辅助演员表演:一些特殊的props可以辅助演员完成表演。例如,在舞蹈表演中,使用道具服装可以突出舞蹈的主题;在武术表演中,使用武器道具可以让观众感受到演员的功底。
三、如何选择合适的props?
1. 符合主题:选择props时,首先要考虑是否符合舞台表演的主题。比如,在爱情剧中,可以使用鲜花、戒指等道具;在恐怖剧中,可以使用血腥、恐怖的道具。
2. 与角色相符:props要与角色性格、特点相符。例如,一个严肃、稳重的角色,可以使用木质、金属等材质的道具;一个活泼、开朗的角色,可以使用色彩鲜艳、造型独特的道具。
3. 考虑舞台效果:选择props时,要考虑舞台效果。比如,在舞台上使用大型的道具,可以增强舞台的气势;使用小型的道具,可以让舞台显得更加精致。
四、props的种类及应用
以下是一些常见的舞台道具及其应用:
| 道具类型 | 应用场景 | 举例 |
|---|---|---|
| 家具 | 戏剧、歌舞剧、话剧等 | 桌子、椅子、床等 |
| 武器 | 武术、战争剧、武侠剧等 | 弓箭、剑、刀等 |
| 服装 | 戏剧、歌舞剧、话剧等 | 古装、现代装、特殊角色装等 |
| 装饰品 | 舞蹈、戏剧、话剧等 | 项链、耳环、手镯等 |
| 舞台布景 | 戏剧、歌舞剧、话剧等 | 房间、街道、森林等 |
通过本文的介绍,相信大家对“props”有了更深入的了解。在舞台表演中,合适的props可以起到画龙点睛的作用,助你成为焦点。所以,在今后的表演中,不妨多关注一下道具的选择和运用,让你的舞台表演更加精彩!
如何操作vue组件使用props传递数据
这次给大家带来如何操作vue组件使用props传递数据,操作vue组件使用props传递数据的注意事项有哪些,下面就是实战案例,一起来看一下。
在 Vue中,父子组件的关系可以总结为 props向下传递,事件向上传递。父组件通过 props给子组件下发数据,子组件通过事件给父组件发送消息。看看它们是怎么工作的。
一、基本用法
组件不仅仅是要把模板的内容进行复用,更重要的是组件间要进行通信。
在组件中,使用选项props来声明需要从父级接收的数据, props的值可以是两种,一种是字符串数组,一种是对象。
1.1字符串数组:
<p id=”app4″>
<my-component4 message=”数据来自父组件”></my-component4>
</p>
Vue.component('my-component4',{
props: ['message'],
template:'<p>{{message}}</p>'
});
var app4= new Vue({
el:'#app4'
});渲染后的结果为:
<p id=” app4”>
<p>来自父组件的数据</ p>
</p>props中声明的数据与组件data函数return的数据主要区别就是props的来自父级,而data中的是组件自己的数据,作用域是组件本身,这两种数据都可以在模板template及计算属性computed和方法methods中使用。
上例的数据message就是通过props从父级传递过来的,在组件的自定义标签上直接写该props的名称,如果要传递多个数据,在props数组中添加项即可。
有时候,传递的数据并不是直接写死的,而是来自父级的动态数据,这时可以使用指令v-bind来动态绑定props的值,当父组件的数据变化时,也会传递给子组件。
<p id=”app5″>
<input type=”text” v-model=”text”>
<my-component5:my-text=”text”></my-component5>
</p>
Vue.component('my-component5',{
props: ['myText'],
template:'<p>{{myText}}</p>'
});
var app5= new Vue({
el:'#app5',
data:{
text:'动态传递父组件数据'
}
});注意的几个点:
1.如果你要直接传递数字、布尔值、数组、对象,而且不使用v-bind,传递的仅仅是字符串。
2.如果你想把一个对象的所有属性作为 prop进行传递,可以使用不带任何参数的 v-bind(即用 v-bind而不是 v-bind:prop-name)。例如,已知一个 todo对象:
1.2对象:
当prop需要验证时,就需要对象写法。
一般当你的组件需要提供给别人使用时,推荐都进行数据验证,比如某个数据必须是数字类型,如果传入字符串,就会在控制台弹出警告。
<p id=”app6″>
<input type=”text” v-model=”number”>
<my-component6:my-text=”number”></my-component6>
</p>
Vue.component('my-component6',{
props:{
'myText':{
type: Number,//必须是数字类型的
required: true,//必须传值
default: 1//如果未定义,默认值就是1
}
},
template:'<p>{{myText}}</p>'
});
var app6= new Vue({
el:'#app6',
data:{
number: 1
}
});验证的type类型可以是:
? String
? Number
? Boolean
? Object
? Array
? Function
type也可以是一个自定义构造器,使用instanceof检测。
当prop验证失败时,在开发版本下会在控制台抛出一条警告。
二、单向数据流
Vue 2.x与Vue l.x比较大的一个改变就是, Vue2.x通过props传递数据是单向的了,也就是父组件数据变化时会传递给子组件,但是反过来不行。
业务中会经常遇到两种需要改变prop的情况,
2.1一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域下可以随意使用和修改。(Prop作为初始值传入后,子组件想把它当作局部数据来用;)
这种情况可以在组件data内再声明一个数据,引用父组件的prop,示例代码如下:
<p id=”app7″>
<my-component7:init-count=”1″></my-component7>
</p>
Vue.component('my-component7',{
props: ['initCount'],
template:'<p>{{count}}</p>',
data: function(){
return{
count: this.initCount
}
}
});
var app7= new Vue({
el:'#app7'
});组件中声明了数据count,它在组件初始化时会获取来自父组件的initCount,之后就与之无关了,只用维护c ount,这样就可以避免直接操作initCount。
2.2prop作为需要被转变的原始值传入。(Prop作为原始数据传入,由子组件处理成其它数据输出。)
这种情况用计算属性就可以了,示例代码如下:
<p id=”app8″>
<my-component8:width=”100″></my-component8>
</p>
Vue.component('my-component8',{
props: ['width'],
template:'<p:style=”style”>组件内容</p>',
computed:{
style: function(){
return{
width: this.width+'px'
}
}
}
});
var app8= new Vue({
el:'#app8'
});注意在 JavaScript中对象和数组是引用类型,指向同一个内存空间,如果 prop是一个对象或数组,在子组件内部改变它会影响父组件的状态。
相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!
推荐阅读:
怎么实现微信小程序登录鉴权
使用webpack插件html-webpack-plugin实例详解
react属性展开{…props}
如果你已经有了一个 props对象,你可以使用展开运算符…来在 JSX中传递整个 props对象。以下两个组件是等价的:
你还可以选择只保留当前组件需要接收的 props,并使用展开运算符将其他 props传递下去。
在上述例子中,kind的 prop会被安全的保留,它将不会被传递给 DOM中的<button>元素。所有其他的 props会通过…other对象传递,使得这个组件的应用可以非常灵活。你可以看到它传递了一个onClick和children属性。
属性展开在某些情况下很有用,但是也很容易将不必要的 props传递给不相关的组件,或者将无效的 HTML属性传递给 DOM。我们建议谨慎的使用该语法。
在开始和结束标签之间的 JSX表达式,将作为特定属性 props.children传递给外层组件。
详解React中传入组件的props改变时更新组件的几种实现方法
我们使用react的时候常常需要在一个组件传入的props更新时重新渲染该组件,常用的方法是在componentWillReceiveProps中将新的props更新到组件的state中(这种state被成为派生状态(Derived State)),从而实现重新渲染。React 16.3中还引入了一个新的钩子函数getDerivedStateFromProps来专门实现这一需求。但无论是用componentWillReceiveProps还是getDerivedStateFromProps都不是那么优雅,而且容易出错。所以今天来探讨一下这类实现会产生的问题和更好的实现方案。
何时使用派生状态
咱们先来看一个比较常见的需求,一个用户列表,可以新增和编辑用户,当用户点击‘新建’
按钮用户可以在输入框中输入新的用户名;当点击‘编辑’按钮的时候,输入框中显示被编辑的用户名,用户可以修改;当用户点击‘确定’按钮的时候用户列表更新。
class UserInput extends React.Component{
state={
user: this.props.user
}
handleChange=(e)=>{
this.setState({
user:{
…this.state.user,
name: e.target.value
}
});
}
render(){
const{ onConfirm}= this.props;
const{ user}= this.state;
return(
<div>
<input value={user.name||”} onChange={this.handleChange}/>
<button onClick={()=>{ onConfirm(user)}}>确定</button>
</div>
);
}
}
class App extends React.Component{
state={
users: [
{ id: 0, name:’bruce’},
{ id: 1, name:’frank’},
{ id: 2, name:’tony’}
],
targetUser:{}
}
onConfirm=(user)=>{
const{ users}= this.state;
const target= users.find(u=> u.id=== user.id);
if(target){
this.setState({
users: [
…users.slice(0, users.indexOf(target)),
user,
…users.slice(users.indexOf(target)+ 1)
]
});
} else{
const id= Math.max(…(users.map(u=> u.id)))+ 1;
this.setState({
users: [
…users,
{
…user,
id
}
]
});
}
}
render(){
const{ users, targetUser}= this.state;
return(
<div>
<UserInput user={targetUser} onConfirm={this.onConfirm}/>
<ul>
{
users.map(u=>(
<li key={u.id}>
{u.name}
<button onClick={()=>{ this.setState({ targetUser: u})}}>编辑</button>
</li>
))
}
</ul>
<button onClick={()=>{ this.setState({ targetUser:{}})}}>新建</button>
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById(‘root’));
运行后,效果如图:
现在点击‘编辑’和‘新建’按钮,输入框中的文字并不会切换,因为点击‘编辑’和‘更新’时,虽然UserInput的props改变了但是并没有触发state的更新。所以需要实现props改变引发state更新,在UserInput中增加代码:
componentWillReceiveProps(nextProps){
this.setState({
user: nextProps.user
});
}
或者
static getDerivedStateFromProps(props, state){
return{
user: props.user
};
}
这样就实现了UserInput每次接收新的props的时候自动更新state。但是这种实现方式是有问题的。
派生状态导致的问题
首先来明确组件的两个概念:受控数据(controlled data lives)和不受控数据(uncontrollered data lives)。受控数据指的是组件中通过props传入的数据,受到父组件的影响;不受控数据指的是完全由组件自己管理的状态,即内部状态(internal state)。而派生状态揉合了两种数据源,当两种数据源产生冲突时,问题随之产生。
问题一
当在修改一个用户的时候,点击‘确定’按钮,输入框里的文字又变成了修改之前的文字。比如我将‘bruce’修改为‘bruce lee’,确定后,输入框中又变成了‘bruce’,这是我们不愿意看到的。
出现这个问题的原因是,点击确定,App会re-render,App又将之前的user作为props传递给了UserInput。我们当然可以在每次点击确定之后将targetUser重置为一个空对象,但是一旦状态多了之后,这样管理起来非常吃力。
问题二
假设页面加载完成后,会异步请求一些数据然后更新页面,如果用户在请求完成页面刷新之前已经在输入框中输入了一些文字,随着页面的刷新输入框中的文字会被清除。
我们可以在App中加入如下代码模拟一个异步请求:
componentDidMount(){
setTimeout(()=>{
this.setState({
text:’fake request’
})
}, 5000);
}
导致这个问题的原因在于,当异步请求完成,setState后App会re-render,而组件的componentWillReceiveProps会在父组件每次render的时候执行,而此时传入的user是一个空对象,所以UserInput的内容被清空了。而getDerivedStateFromProps调用的更频繁,会在组件每次render的时候调用,所以也会产生该问题。
为了解决这个问题我们可以在componentWillReceiveProps中判断新传入的user和当前的user是否一样,如果不一样才设置state:
componentWillReceiveProps(nextProps){
if(nextProps.user.id!== this.props.user.id){
this.setState({
user: nextProps.user
});
}
}
更好的解决方案
派生状态的数据源的不确定性会导致各种问题,那如果每份数据有且只被一个component管理应该就能避免这些问题了。这种思路有两种实现,一种是数据完全由父组件管理,一种是数据完全由组件自己管理。下面分别讨论:
完全受控组件(fully controlled component)
组件的数据完全来自于父组件,组件自己将不需要管理state。我们新建一个完全受控版的UserInput:
class FullyControlledUserInput extends React.Component{
render(){
const{ user, onConfirm, onChange}= this.props;
return(
<div>
<input value={user.name||”} onChange={onChange}/>
<button onClick={()=>{ onConfirm(user)}}>确定</button>
</div>
)
}
}
App中调用FullyControlledUserInput的方法如下:
…
<FullyControlledUserInput
user={targetUser}
onChange={(e)=>{
this.setState({
targetUser:{
id: targetUser.id,
name: e.target.value
}
});
}}
onConfirm={this.onConfirm}
/>
…
现在FullyControlledUserInput中的所有的数据都来源于父组件,由此解决数据冲突和被篡改的问题。
完全不受控组件(fully uncontrolled component)
组件的数据完全由自己管理,因此componentWillReceiveProps中的代码都可以移除,但保留传入props来设置state初始值:
class FullyUncontrolledUserInput extends React.Component{
state={
user: this.props.user
}
onChange=(e)=>{
this.setState({
user:{
…this.state.user,
name: e.target.value
}
});
}
render(){
const{ user}= this.state;
const{ onConfirm}= this.props;
return(
<div>
<input value={user.name||”} onChange={this.onChange}/>
<button onClick={()=>{ onConfirm(user)}}>确定</button>
</div>
)
}
}
当传入的props发生改变时,我们可以通过传入一个不一样的key来重新创建一个component的实例来实现页面的更新。App中调用FullyUncontrolledUserInput的方法如下::
<FullyUncontrolledUserInput
user={targetUser}
onConfirm={this.onConfirm}
key={targetUser.id}
/>
大部分情况下,这是更好的解决方案。或许有人会觉得这样性能会受影响,其实性能并不会变慢多少,而且如果组件的更新逻辑过于复杂的话,还不如重新创建一个新的组件来的快。
在父组件中调用子组件的方法设置state
如果某些情况下没有合适的属性作为key,那么可以传入一个随机数或者自增的数字作为key,或者我们可以在组件中定义一个设置state的方法并通过ref暴露给父组件使用,比如我们可以在UserInput中添加:
setNewUserState=(newUser)=>{
this.setState({
user: newUser
});
}
在App中通过ref调用这个方法:
…
<UserInput user={targetUser} onConfirm={this.onConfirm} ref=’userInput’/>
<ul>
{
users.map(u=>(
<li key={u.id}>
{u.name}
<button onClick={()=>{
this.setState({ targetUser: u});
this.refs.userInput.setNewUserState(u);
}}>
编辑
</button>
</li>
))
}
</ul>
<button onClick={()=>{
this.setState({ targetUser:{}});
this.refs.userInput.setNewUserState({});
}}>
新建
</button>
…
这个方法不推荐使用,除非实在没法了。
本文源码请参考:ways-to-update-component-on-props-change
文章分享结束,props和prop是什么意思中文翻译的答案你都知道了吗?欢迎再次光临本站哦!




