不会写前端
javascript太难了,做不了一点。
上次做前端还是2013年,那会vue这类现代化框架还没出现呢。
前端只推荐react
推荐react,但是看不惯jsx的省事儿vue真香😋
G: 推荐react,但是看不惯jsx的省事儿vue真香😋
jsx是什么
C: jsx是什么
JSX是一种JavaScript的语法扩展,首先运用于React中,其格式比较像是模版语言,但事实上完全是在JavaScript内部实现的。元素是构成React应用的最小单位,JSX就是用来声明React当中的元素。React主要使用JSX来描述用户界面。
就比如以下使用React构建的登录页面:
import React, { useState, useEffect } from 'react';
import { Form, Input, Button, Card, message, Divider, Spin, Result } from 'antd';
import { UserOutlined, LockOutlined, WechatOutlined } from '@ant-design/icons';
import { useNavigate, useLocation } from 'react-router-dom';
import { login } from '../services/auth';
import api from '../services/api';
const Login = () => {
const [loading, setLoading] = useState(false);
const [weworkLoading, setWeworkLoading] = useState(false);
const [isWeworkLogin, setIsWeworkLogin] = useState(false);
const [errorMsg, setErrorMsg] = useState('');
const [loginSuccess, setLoginSuccess] = useState(false);
const navigate = useNavigate();
const location = useLocation();
const [form] = Form.useForm();
useEffect(() => {
// 检查URL中是否有企业微信的code
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (code) {
setIsWeworkLogin(true);
setErrorMsg('');
handleWeworkLogin(code);
}
}, []);
const handleNavigate = (from) => {
setLoginSuccess(true);
setTimeout(() => {
// navigate(from);
window.location.replace(from);
}, 1000);
};
const handleSubmit = async (values) => {
setLoading(true);
setErrorMsg('');
try {
await login(values);
const from = location.state?.from?.pathname || '/';
handleNavigate(from);
} catch (error) {
message.error(error?.response?.data?.detail || '登录失败');
} finally {
setLoading(false);
}
};
const handleWeworkLogin = async (code) => {
setWeworkLoading(true);
setErrorMsg('');
try {
const response = await api.post('/auth/wework/login', { code });
if (response.token) {
localStorage.setItem('token', response.token);
localStorage.setItem('user', JSON.stringify(response.user));
const from = location.state?.from?.pathname || '/';
handleNavigate(from);
}
} catch (error) {
const errMsg = error?.response?.data?.detail || '企业微信登录失败';
setErrorMsg(errMsg);
} finally {
setWeworkLoading(false);
}
};
const handleWeworkClick = async () => {
setErrorMsg('');
try {
const response = await api.get('/auth/wework/login-url');
// 如果是电脑端
if (window.innerWidth > 768) {
window.location.href = response.login_url;
} else {
window.location.href = response.mobile_url;
}
} catch (error) {
const errMsg = error?.response?.data?.detail || '获取企业微信登录链接失败';
setErrorMsg(errMsg);
message.error(errMsg);
}
};
const renderLoginForm = () => {
if (isWeworkLogin) {
if (loginSuccess) {
return (
<Result
status="success"
title="登录成功"
subTitle="正在跳转..."
/>
);
}
return (
<div style={{ textAlign: 'center', padding: '20px 0' }}>
{weworkLoading ? (
<div style={{ margin: '45px 0 54px 0' }}>
<Spin size="large" />
<div style={{ marginTop: 16 }}>企业微信登录中...</div>
</div>
) : errorMsg ? (
<Result
status="error"
title={errorMsg}
extra={
<Button type="primary" onClick={() => window.location.href = '/login'}>
返回登录
</Button>
}
/>
) : null}
</div>
);
}
if (loginSuccess) {
return (
<Result
status="success"
title="登录成功"
subTitle="正在跳转..."
/>
);
}
return (
<>
<Form
form={form}
onFinish={handleSubmit}
size="large"
>
<Form.Item
name="username"
rules={[{ required: true, message: '请输入用户名' }]}
>
<Input
prefix={<UserOutlined />}
placeholder="用户名"
/>
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: '请输入密码' }]}
>
<Input.Password
prefix={<LockOutlined />}
placeholder="密码"
/>
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
loading={loading}
block
>
登录
</Button>
</Form.Item>
</Form>
<Divider>OAuth Links</Divider>
<Button
type="default"
icon={<WechatOutlined style={{ color: '#07C160' }} />}
onClick={handleWeworkClick}
loading={weworkLoading}
block
style={{ marginBottom: 16 }}
size="large"
>
企业微信登录
</Button>
{errorMsg && (
<Result
status="error"
title={errorMsg}
style={{ padding: '24px 0 0' }}
/>
)}
</>
);
};
return (
<div style={{
maxWidth: 450,
margin: '100px auto',
padding: '0 24px'
}}>
<Card>
<h2 style={{ textAlign: 'center', marginBottom: 24 }}><img src="/newsjc.png" alt="logo" style={{ width: 280, marginBottom: 12 }} /></h2>
{renderLoginForm()}
<div style={{ textAlign: 'center', marginTop: 12 }}>
© 2023-{new Date().getFullYear()}
</div>
</Card>
</div>
);
};
export default Login;
G: JSX是一种JavaScript的语法扩展,首先运用于React中,其格式比较像是模版语言,但事实上完全是在JavaScript内部实现的。元素是构成React应用的最小单位,JSX就是用来声明React当中的元素。React主要使用JSX来描述用户界面。就比如以下使用Re...
太复杂了,搞不懂。
我现在用的Hono,模板是这么写的:
import { html } from"hono/html";
import { PEditProps } from"../route/pEdit";
import Header from"./header"
import Footer from"./footer"
exportdefaultfunction (z: PEditProps) {
returnhtml`
${Header(z)}
<mainclass="container">
${(z.subject || !z.eid) ? html`
<inputname="subject"value="${z.subject}"placeholder="标题">
`: ''}
<divname="content">${z.content}</div>
<buttononclick="save()">提交</button>
</main>
<scriptsrc="/quill.js"></script>
<script>
const quill = new Quill('[name="content"]', { theme: 'snow' });
asyncfunction save() {
const data = new FormData();
if(document.querySelector('[name="subject"]')){
data.set('subject', document.querySelector('[name="subject"]').value);
}
data.set('content', quill.getSemanticHTML());
if ((await fetch(new Request("", {method: "POST", body: data}))).ok) {
window.location=document.referrer
} else { alert('提交失败'); }
};
</script>
${Footer(z)}
`;
}
react写多了
v2016: 前端只推荐react
感觉还是Svelte好点