我习惯于使用 state 在 react 中创建受控组件;但是,我是Vue
新手,我想学习如何将我的代码从 react 重新创建为 Vue 可以使用的东西。我希望输入字段值存储在一段数据中,以便我可以对它们执行某些操作。
<template>
<form @submit="handleSubmit" class="form form--signin">
<h2 class="form__h2">Log into your account</h2>
<label for="email">Email address</label>
<input v-model="email" type="email" id="email" autoComplete="off"/>
<label for="password">Password</label>
<input v-model="password" type="password" id="password" autoComplete="off"/>
<button class="form__btn">Login</button>
</form>
</template>
<script>
从"axios"导入公理;
export default {
name: 'SignIn',
data() {
return {
user: null,
email: null,
password: null
}
},
methods: {
handleSubmit(event) {
event.preventDefault();
this.login(this.email, this.password);
this.email = '';
this.password = '';
},
login(email, password) {
axios.post('http://localhost:8000/api/v1/users/login', {
email,
password
})
.then(res => {
// console.log(this.user);
this.user = res.data.data.user;
if(res.data.status === 'success') {
// setUserStatus(res.data.status);
window.setTimeout(() => {
window.location.assign('/');
}, 1500)
}
})
.catch(err => console.log(err.response.data.message));
}
},
mounted() {
if (!this.user) return;
console.log('Writing to session storage...');
sessionStorage.setItem('user', JSON.stringify(this.user));
}
}
这就是它在Vue
中的样子
Vue.config.devtools = false;
Vue.config.productionTip = false;
const SignIn = Vue.component('sign-in', {
template: `<form @submit="handleSubmit" className="form form--signin">
<h2 className="form__h2">Log into your account</h2>
<label htmlFor="email">Email address</label>
<input v-model="email" type="email" id="email" autoComplete="off"/>
<label htmlFor="password">Password</label>
<input v-model="password" type="password" id="password" autoComplete="off"/>
<button className="form__btn">Login</button>
</form>`,
data() {
return {
user: null,
email: null,
password: null,
}
},
methods: {
handleSubmit(event) {
this.login(this.email, this.password)
this.email = '';
this.password = '';
event.preventDefault();
},
login(email, password) {
}
},
mounted() {
if (!this.user)
return;
console.log('Writing to session storage...');
sessionStorage.setItem('user', JSON.stringify(user));
}
})
var app = new Vue({
el: '#app'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<sign-in></sign-in>
</div>
这就是我在 Vue 中编写相同组件的方法:
<template>
<form @submit.prevent="handleSubmit" class="form form--signin">
<h2 class="form__h2">Log into your account</h2>
<label for="email">Email address</label>
<input v-model="email" type="email" id="email" autocomplete="off">
<label for="password">Password</label>
<input v-model="password" type="password" id="password" autocomplete="off">
<button class="form__btn">Login</button>
</form>
</template>
<script>
const login = async (email, password) => {
// make the api call and return a promise
};
export default {
name: "SignIn",
data: () => ({
email: "",
password: ""
}),
methods: {
async handleSubmit(event) {
console.log("Getting user from API...");
try {
const user = await login(this.email, this.password);
console.log("Writing to session storage...");
sessionStorage.setItem("user", JSON.stringify(user));
this.email = "";
this.password = "";
} catch (e) {
// handle login errors
}
}
}
};
</script>
窗体控件的状态存储在组件的data
属性上,并使用v-model
指令在控件上设置双向绑定。对输入的任何更改都将同步到组件的状态,反之亦然。
Vue 在将事件侦听器添加到模板时提供了一些方便的修饰符,因此通过编写@submit.prevent
可以防止触发默认提交处理程序。
我创建了一个沙盒示例,因此您可以轻松地使用代码并查看其运行情况。
您可以使用 v-model 指令绑定组件数据,使用 v-on 指令绑定组件方法:
<template>
<div>
<div class>Login Form</div>
<form v-on:submit="handleSubmit">
<input v-model="email" placeholder="email" type="text" class="input" />
<br />
<input v-model="password" placeholder="password" type="password" class="input" />
<br />
<button v-on:click="handleSubmit" type="submit" class="submit">Login</button>
</form>
<hr />
<div>Email: {{email}} and Password: {{password}}</div>
<div>User sessions: {{user}}</div>
</div>
</template>
并且可以使用 axios 进行 API 调用来验证和存储来自响应user
会话数据:
<script>
import axios from "axios";
export default {
name: "LoginForm",
props: {},
data: () => ({
email: "",
password: "",
user: {}
}),
methods: {
login() {
axios
.post("http://localhost:8000/api/v1/users/login", {
email: this.email,
password: this.password
})
.then(res => {
console.log(res);
this.user = res.data.data.user;
sessionStorage.setItem("user", JSON.stringify(this.user));
if (res.data.status === "success") {
window.setTimeout(() => {
window.location.assign("/"); // to verify mounted hook
}, 1500);
}
})
.catch(err => console.log(err.response.data.message));
},
handleSubmit: function(e) {
e.preventDefault();
this.login();
}
},
mounted() {
console.debug("mounted");
}
};
</script>
另外,请注意,您可以使用mounted
生命周期挂钩从localStorage
或您选择的任何其他钩子读取数据。
您可以使用 async/await 或 then/catch 来处理异步(基于承诺(API 调用。
这是CodeSandbox。
以下是在 react 中使用与useEffect(() => {}, [])
相同的钩子mounted
方法:
mounted() {
const user = sessionStorage.getItem("user");
if (user) {
this.user = JSON.parse(user);
}
}