Vuejs将动态数据从父组件传递给子组件
Posted
技术标签:
【中文标题】Vuejs将动态数据从父组件传递给子组件【英文标题】:Vuejs Passing dynamic data from parent to child component 【发布时间】:2021-04-22 11:08:35 【问题描述】:我有一个视图和一个组件。我正在尝试在这里进行身份验证。
作为用户,我输入用户名和密码,点击login
。这个emits
向父组件发送信息,它向AWS 中的API 网关发出获取请求。这个获取响应有一个我感兴趣的标头X-Session-Id
。
我的 emit
位工作正常。
但是,我无法将标头值传递回组件,也无法将new_password_required
设置为true
,这将为新密码添加新输入字段,以及替换带有reset password
按钮的login button
。
我觉得我需要用道具来做这件事,但我无法成功地将值从父母传递给孩子。
另外,重置密码位是否应该有自己的组件?
下面是我的代码。这是我的第一个前端,所以我不熟悉我应该如何分享它(例如与游乐场)。另外,由于我正在学习,我现在正在尝试坚持使用 vanilla vue(我认为我只安装了 vue-router)
父母:
<template>
<div id="app" class="small-container">
<login-form @login:user="loginUser($event)" />
</div>
</template>
<script>
import LoginForm from "@/components/LoginForm.vue";
export default
name: "Login",
components:
LoginForm
,
data()
return
session_id: String,
new_password_required: Boolean
;
,
methods:
async loginUser(loginEvent)
try
const response = await fetch(
process.env.VUE_APP_API_GATEWAY_ENDPOINT + "/login/user",
method: "POST",
body: JSON.stringify(loginEvent)
);
const data = await response.json();
console.log(data);
if (data.headers["X-Session-Id"] != null)
this.session_id = data.headers["X-Session-Id"];
this.new_password_required = true;
catch (error)
console.error(error);
,
async resetPassword(resetPasswordEvent)
try
const response = await fetch(
process.env.VUE_APP_API_GATEWAY_ENDPOINT + "/reset/user/password",
method: "POST",
body: JSON.stringify(resetPasswordEvent)
);
const data = await response.json();
console.log(data);
catch (error)
console.error(error);
;
</script>
组件:
<template>
<div id="login-form">
<h1>Serverless App</h1>
<form>
<label for="email_address">Email Address:</label><br />
<input
v-model="login_details.email_address"
type="text"
id="email_address"
name="email_address"
/><br />
<label for="password">Password:</label><br />
<input
v-model="login_details.password"
type="password"
id="password"
name="password"
/>
<label v-if="new_password_required" for="new_password"
>New Password:</label
><br />
<input
v-if="new_password_required"
v-model="login_details.new_password"
type="password"
id="new_password"
name="new_password"
/>
</form>
<button v-if="!new_password_required" @click="loginUser($event)">
Login
</button>
<button v-if="new_password_required" @click="resetPassword($event)">
Reset Password
</button>
</div>
</template>
<script>
export default
name: "LoginForm",
props:
session_id: String,
new_password_required:
type: Boolean,
default: () => false
,
data()
return
login_details:
email_address: "",
password: "",
new_password: ""
;
,
methods:
loginUser()
console.log("testing loginUser...");
const loginEvent =
email_address: this.login_details.email_address,
password: this.login_details.password
;
this.$emit("login:user", loginEvent);
,
resetPassword()
console.log("testing resetPassword...");
const resetPasswordEvent =
email_address: this.login_details.email_address,
password: this.login_details.password,
new_password: this.login_details.new_password,
session_id: this.login_details.sessionId
;
this.$emit("reset:Password", resetPasswordEvent);
;
</script>
【问题讨论】:
您能否说明您打算在子组件中使用X-Session-Id
的原因和方式?
当然。我正在使用 amazon cognito 进行身份验证。登录使用 Cognito InitiateAuth()
方法查看用户状态。初次登录时,状态将为FORCE_CHANGE_PASSWORD
。如果不需要更改密码,用户将获得不记名令牌。当需要重置密码时,再次请求AdminRespondToAuthChallenge()
方法,该方法以X-Session-Id
为参数。该参数通过父类中的resetPassword()
方法发送到api网关
如果添加ref attribute to your child,您可以通过this.$refs.childRefName.resetPassword(sessionId)
从父级访问实例方法。这是一种方法,可能是最简单的方法。
您希望何时将 new_password_required 设置为 true?
@Amaarrockz 我想通了,请参阅下面的答案。如果父级的loginUser()
fetch 响应在标题中有X-Session-Id
,我想将new_password_required
设置为true。如果后端对 aws cognito InitiateAuth()
方法的请求响应告诉我重置用户密码(这需要会话 ID),则此标头由我的后端 golang lambda 返回。
【参考方案1】:
您的子组件看起来不错,但是,您需要在父组件中传递道具,如下所示:
<login-form @login:user="loginUser($event)" :session-id="xidhere"
:new-password-required="newPasswordRequired"/>
随着这些值在父组件中更新,子组件也应该更新。
请注意,使用驼峰命名您的道具,然后在您的 html 中使用 kebab-case。
所以你的登录表单属性应该更新为:
props:
sessionId: String,
newPasswordRequired:
type: Boolean,
default: () => false
,
另外,当您向父级发送事件时,可能不需要将会话 ID 发送给子级,只需在发送之前将其添加到您的 api 调用中。
【讨论】:
干杯。还没有完全确定 CamelCase here kebab-case there bits。我知道这是一件事,但它已被取消优先级哈。这是一个比我想出的更好的解决方案,而且只有一个组件,因此重复更少。不知道制作一个单独的组件是如何神奇地让我弄清楚我需要用:new-password
将道具发送给孩子的@
干得好。一点一点你就会到达那里!继续加油!【参考方案2】:
想通了。我创建了一个用于重置密码的新子组件。也许它可以干一点?我是新来的。很高兴任何指针:)
家长
<template>
<div id="app" class="small-container">
<login-form v-if="!new_password_required" @login:user="loginUser($event)" />
<reset-password-form
v-if="new_password_required"
:session_id="session_id"
@reset:password="resetPassword($event)"
/>
</div>
</template>
<script>
import LoginForm from "@/components/LoginForm.vue";
import ResetPasswordForm from "@/components/ResetPasswordForm.vue";
export default
name: "Login",
components:
LoginForm,
ResetPasswordForm
,
data()
return
session_id: "",
new_password_required: false
;
,
methods:
async loginUser(loginEvent)
try
const response = await fetch(
process.env.VUE_APP_API_GATEWAY_ENDPOINT + "/login/user",
method: "POST",
body: JSON.stringify(loginEvent)
);
const data = await response.json();
console.log(data);
if (data.headers["X-Session-Id"] != null)
this.session_id = data.headers["X-Session-Id"];
this.new_password_required = true;
catch (error)
console.error(error);
,
async resetPassword(resetPasswordEvent)
try
const response = await fetch(
process.env.VUE_APP_API_GATEWAY_ENDPOINT + "/reset/user/password",
method: "POST",
body: JSON.stringify(resetPasswordEvent)
);
const data = await response.json();
console.log(data);
catch (error)
console.error(error);
;
</script>
儿童:登录表单
<template>
<div id="login-form">
<h1>Serverless Release Dashboard</h1>
<form>
<label for="email_address">Email Address:</label><br />
<input
v-model="login_details.email_address"
type="text"
id="email_address"
name="email_address"
/><br />
<label for="password">Password:</label><br />
<input
v-model="login_details.password"
type="password"
id="password"
name="password"
/>
</form>
<button @click="loginUser($event)">
Login
</button>
</div>
</template>
<script>
export default
name: "LoginForm",
data()
return
login_details:
email_address: "",
password: ""
;
,
methods:
loginUser()
console.log("testing loginUser...");
const loginEvent =
email_address: this.login_details.email_address,
password: this.login_details.password
;
this.$emit("login:user", loginEvent);
;
</script>
儿童:重置密码表格
<template>
<div id="reset-password-form">
<h1>Serverless Release Dashboard</h1>
<form>
<label for="email_address">Email Address:</label><br />
<input
v-model="login_details.email_address"
type="text"
id="email_address"
name="email_address"
/><br />
<label for="password">Password:</label><br />
<input
v-model="login_details.password"
type="password"
id="password"
name="password"
/>
<label for="new_password">New Password:</label><br />
<input
v-model="login_details.new_password"
type="password"
id="new_password"
name="new_password"
/>
</form>
<button @click="resetPassword($event)">
Reset Password
</button>
</div>
</template>
<script>
export default
name: "ResetPasswordForm",
props:
email_address: String,
password: String,
session_id: String
,
data()
return
login_details:
email_address: "",
password: "",
new_password: "",
session_id: ""
;
,
methods:
resetPassword()
console.log("testing resetPassword...");
const loginEvent =
email_address: this.email_address,
password: this.password,
new_password: this.login_details.new_password,
session_id: this.session_id
;
this.$emit("reset:password", loginEvent);
;
</script>
【讨论】:
以上是关于Vuejs将动态数据从父组件传递给子组件的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用角度的ng的情况下将输入值从父组件传递给子组件?