npmrun 4 years ago
parent
commit
c45c159628
  1. 1
      .gitignore
  2. 1796
      package-lock.json
  3. 6
      package.json
  4. 3
      src/assets/style/common.scss
  5. 9
      src/main.tsx
  6. 1
      src/store/action/index.ts
  7. 17
      src/store/action/todo.ts
  8. 2
      src/store/constant/todo.ts
  9. 8
      src/store/index.ts
  10. 5
      src/store/reducer/index.ts
  11. 26
      src/store/reducer/todo.ts
  12. 4
      src/store/types/todo.d.ts
  13. 111
      src/views/Home/Header.tsx
  14. 42
      src/views/Home/index.module.scss
  15. 67
      src/views/Home/index.tsx
  16. 8
      types/global.d.ts

1
.gitignore

@ -3,3 +3,4 @@ node_modules
dist
dist-ssr
*.local
.idea

1796
package-lock.json

File diff suppressed because it is too large

6
package.json

@ -9,7 +9,10 @@
"classnames": "^2.3.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-router-dom": "^5.2.0"
"react-redux": "^7.2.4",
"react-router-dom": "^5.2.0",
"redux": "^4.1.0",
"styled-jsx": "^3.4.4"
},
"devDependencies": {
"@types/node": "^15.12.5",
@ -17,6 +20,7 @@
"@types/react-dom": "^17.0.0",
"@types/react-router-dom": "^5.1.7",
"@vitejs/plugin-react-refresh": "^1.3.1",
"redux-devtools": "^3.7.0",
"sass": "^1.35.1",
"typescript": "^4.3.2",
"vite": "^2.3.8",

3
src/assets/style/common.scss

@ -9,12 +9,13 @@ textarea {
body{
background-image: url("@/assets/images/0.jpg");
background-attachment: fixed;
background-position: center top 36px;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
a {
// color: initial;
display: inline-block;
text-decoration: none;
color: inherit;
}

9
src/main.tsx

@ -1,14 +1,19 @@
import "@/assets/style/common.scss";
import store from "@/store";
import React from "react";
import ReactDOM from "react-dom";
import "@/assets/style/common.scss";
import "virtual:windi.css";
import {Provider} from 'react-redux'
import "virtual:windi-devtools";
import "virtual:windi.css";
import Router from "./AppRouter";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<Router></Router>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);

1
src/store/action/index.ts

@ -0,0 +1 @@
export * from "./todo"

17
src/store/action/todo.ts

@ -0,0 +1,17 @@
import {ADD, REMOVE} from "@/store/constant/todo"
let nextTodoId = 0
type Action = (param: any) => IAction
export const addTodo: Action = text => ({
type: ADD,
id: nextTodoId++,
text
})
export const removeTodo: Action = id => ({
type: REMOVE,
id: id
})

2
src/store/constant/todo.ts

@ -0,0 +1,2 @@
export const ADD = "ADD_TODO"
export const REMOVE = "REMOVE_TODO"

8
src/store/index.ts

@ -0,0 +1,8 @@
import {combineReducers, createStore} from 'redux'
import reducer from "./reducer"
const reduces = combineReducers(reducer)
const store = createStore(reduces)
export default store

5
src/store/reducer/index.ts

@ -0,0 +1,5 @@
import todo from "./todo"
export default {
todo
}

26
src/store/reducer/todo.ts

@ -0,0 +1,26 @@
import {ADD, REMOVE} from "@/store/constant/todo"
import {combineReducers} from "redux";
let initData: ITodo[] = []
const todos = (state = initData, action: IAction) => {
switch (action.type) {
case ADD:
return [
...state,
{
id: action.id,
text: action.text
}
]
case REMOVE:
const list = state.filter(v => v.id != action.id)
return [
...list
]
default:
return state
}
}
export default todos;

4
src/store/types/todo.d.ts

@ -0,0 +1,4 @@
interface ITodo {
id: number;
text: string;
}

111
src/views/Home/Header.tsx

@ -1,33 +1,94 @@
import React from "react";
import cs from "classnames";
import style from "./index.module.scss";
import { Link } from "react-router-dom";
import React, {useState} from "react";
export default () => {
console.log(style);
const title = "秦时明月";
const [leftMenuList, setLeftMenuList] = useState<any[]>([
{title: "首页", path: "/"},
{title: "角色", children: [{title: "月儿", path: "/about"}]},
]);
const [rightMenuList, setRightMenuList] = useState<any[]>([
{
title: "登录/注册",
click: true
},
]);
function onLeftClick(e: any, menu: any, allMenu: any) {
if (menu.click || !menu.path) {
e.preventDefault();
}
}
function onRightClick(e: any, menu: any, allMenu: any) {
if (menu.click || !menu.path) {
e.preventDefault();
}
}
return (
<div className="h-36px leading-36px shadow bg-white fixed top-0 left-0 right-0">
<div className="container clearfix mx-auto">
<div className={cs(style.logo, "text-size-20px leading-36px")}></div>
<ul className={cs(style.menu, style.left)}>
<li className={cs(style.menuItem, style.hover)}>
<div className={cs(style.menuItemText)}></div>
</li>
<li className={cs(style.menuItem, style.hover)}>
<div className={cs(style.menuItemText)}></div>
<ul className={cs(style.subMenu)}>
<li className={cs(style.subMenuItem, style.hover)}></li>
<li className={cs(style.subMnuItem, style.hover)}></li>
</ul>
</li>
</ul>
<ul className={cs(style.menu, style.right)}>
<li className={cs(style.menuItem)}>
<div className={cs(style.menuItemText)} title="点击登录注册">/</div>
</li>
</ul>
<div className="">
<div className="shadow bg-white h-12 leading-12 fixed top-0 left-0 right-0">
<div className="container h-full clearfix mx-auto">
<div className="h-full float-left cursor-pointer text-size-25px flex items-center">
{title}
</div>
<ul className="h-full float-left ml-10">
{leftMenuList.map((menu, index) => {
return (
<li className="h-full float-left group relative" key={index}>
<a
href={menu.path ? menu.path : '#'}
onClick={(e) => onLeftClick(e, menu, leftMenuList)}
className="h-full px-5 hover:(bg-cool-gray-200 text-black) text-gray-400 text-size-14px flex items-center"
>
{menu.title}
</a>
{menu.children && menu.children.length && (
<ul
className="absolute overflow-hidden transition-all duration-150 max-h-0 group-hover:max-h-500px left-0 top-full shadow">
{menu.children.map((subMenu: any, jndex: number) => {
return (
<li key={jndex} className="float-left relative">
<a
href={subMenu.path ? subMenu.path : '#'}
onClick={(e) =>
onLeftClick(e, subMenu, leftMenuList)
}
className="h-12 px-5 hover:(bg-cool-gray-200 text-black) text-gray-400 text-size-14px flex items-center"
>
{subMenu.title}
</a>
</li>
);
})}
</ul>
)}
</li>
);
})}
</ul>
<ul className="float-right h-full">
{rightMenuList.map((menu, index) => {
return (
<li
key={index}
className="h-full float-left relative cursor-pointer"
>
<a
href={menu.path ? menu.path : '#'}
className="h-full px-5 text-size-14px flex items-center"
onClick={(e) => onRightClick(e, menu, rightMenuList)}
>
{menu.title}
</a>
</li>
);
})}
</ul>
</div>
</div>
<div className="h-12"></div>
</div>
);
};

42
src/views/Home/index.module.scss

@ -1,42 +0,0 @@
.logo {
@apply float-left font-bold inline-block cursor-pointer;
}
.menu {
@apply ml-[30px];
}
.menu.left {
@apply float-left;
}
.menu.right {
@apply float-right;
}
.menuItem {
@apply relative float-left text-gray-800;
}
.menuItem.hover{
@apply hover:bg-cool-gray-200 hover:text-gray-600;
}
.menuItemText {
@apply whitespace-nowrap block px-3 cursor-pointer;
}
.subMenu {
@apply hidden cursor-pointer rounded-b overflow-hidden;
}
.menuItem:hover {
.subMenu {
@apply absolute left-0 top-full block bg-white shadow;
}
}
.subMenuItem {
@apply whitespace-nowrap block px-20px text-gray-800;
}
.subMenuItem.hover{
@apply hover:bg-cool-gray-200 hover:text-gray-600;
}

67
src/views/Home/index.tsx

@ -1,30 +1,69 @@
import React from "react";
import style from "./index.module.scss";
import {addTodo, removeTodo} from "@/store/action/todo";
import PropTypes from 'prop-types'
import React, {FormEvent, useRef} from "react";
import {connect} from "react-redux";
import Header from "./Header";
export default function (props: any) {
console.log(props);
function Home(props: any) {
const {todo, add, remove} = props
const inputRef = useRef<HTMLInputElement>(null);
function addOne(e: FormEvent) {
e.preventDefault()
let text = inputRef.current!.value
if (text) {
inputRef.current!.value = ""
add(text)
}
}
return (
<div>
<Header></Header>
<div className="mt-36px">
<div>
<div className="bg-white min-h-100vh">
<div className="container clearfix mx-auto h-500px">box</div>
</div>
<div className="min-h-100vh">
<div className="container clearfix mx-auto h-500px">
<form onSubmit={(e) => addOne(e)}>
<input ref={inputRef} type="text"/>
<button type="submit"></button>
</form>
{todo
.map((v: ITodo) => {
return <p onClick={() => remove(v.id)} key={v.id}>{v.text}{v.id}</p>;
})}
</div>
</div>
<div className="min-h-100vh"></div>
<div className="bg-white min-h-100vh">
<div className="container clearfix mx-auto">
{[...Array(100)]
.map((v, i) => i)
.map((v) => {
return <p key={v}>v</p>;
})}
</div>
</div>
</div>
</div>
);
}
Home.propTypes = {
todo: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.number.isRequired,
text: PropTypes.string.isRequired
}).isRequired).isRequired,
add: PropTypes.func.isRequired,
remove: PropTypes.func.isRequired
}
const mapStateToProps = (state: any) => {
console.log(state)
return {
todo: state.todo
}
}
const mapDispatchToProps = (dispatch: any) => ({
add: (text: string) => dispatch(addTodo(text)),
remove: (id: string | number) => dispatch(removeTodo(id)),
})
export default connect(mapStateToProps, mapDispatchToProps)(Home);

8
types/global.d.ts

@ -0,0 +1,8 @@
interface IAny{
[props: string]: any;
}
interface IAction extends IAny{
type: string
}
Loading…
Cancel
Save