基础面试题
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等
首先yarn creat umi
这个写法是add到global环境之后再执行create-umi
但是由于我yarn的缓存位置没有使用默认位置,这里就疯狂报错,网上的环境配置和更改.cmd并没有起到帮助
之后通过cnpm create umi
终于解决了,但是cnpm i
一直在报错,然后我把依赖删掉重新用了官网推荐的tyarn
依赖包下了好久,然后第一次启动项目很慢很慢,不过一个下午终于还是启动了
记一下常用的目录和文件
/config/config.ts:配置路由和菜单
/mock/:要学习的模拟数据接口
/public/:静态资源目录
/src/assets/:前端引入资源目录
/src/components/:常用公共组件
/src/layouts/:常用布局
/src/locals/:国际化文件夹
/src/models/:数据模型
/src/pages/:页面和区块组件
/src/services/:接口函数获取数据
/src/utils/:工具文件夹:authorize(权限)、request(请求)、utils(工具函数)
/global.tsx:全局函数
使用区块模板
很简单的用右下角的浮窗启动资产页面
新加入页面之后由于路由config更新不及时的问题,需要断掉重新打开一次项目,才能加入区块组件到新页面
权限管理
打开Authorized.ts
看见getAuthority函数找到authority.ts
有两个一个set一个get
设置权限主要是在model/login.ts中用到
具体细节还没看懂,但是肯定是根据接口拿到的数据来更新权限的
数据请求
首先是能看到mock是我们自己的模拟数据比如mock/user.ts
在页面附近的service.ts中可以看见自定义的调用接口的函数他们调用了mock或者_mock文件的数据
比如个人中心页面service.ts中定义的queryCurrent函数是用来请求根目录下mock/user.ts中的
'GET /api/currentUser'
接口,queryCurrent函数被个人中心页面下的model.ts即模型引用了,最后是index.tsx中使用了connect连接了数据并用了Modalstate接口,整个页面的数据流反向入下面截图
然后因为使用了connect所以数据以及dispatch方法都会在组件的this.props中
model.ts中effect
是我们获取数据的方式其中的yied类型函数中的put相当于调用了reducers方法
这种方式形如redux的dispatch,type对应reducers对象中的属性名
关于connect中的参数其中一个是获取数据的请求另一个loading不知道来源是哪里
然后百度一下看见了一个可能比较容易理解的解释
https://blog.csdn.net/sinat_36146776/article/details/106519540
loading.effects[‘accountAndcenter/fetchCurrent’]表示当调用完毕该effects方法之后由true变为false
好像是dva的东西集成在umi中的一个用法orz
至于connnect中的参数定义在了model文件夹中的connect.d.ts中,会给出loading和其他连接参数的接口定义
手动新建页面
1.不通过umi的导入而是自己编写页面和环境
2.在pages下新建一个自定义的mall文件夹,下面新建index.js
3.config.ts中配置路由
4.更新页面之后就能看到了
umi中mock怎么用?配合service文件
用json模拟然后mock产生数据接口,前端模拟请求
数据来源:https://pvp.qq.com/web201605/js/herolist.json
mock定义的接口可以直接调用不需要请求头http://localhost:8000/api/herolist
的确拿到了数据列表
import herolist from ‘…/…/herolist’
import {Request,Response} from ‘express’
export default{
//可以用GET和POST,可以返回对象或者生成对象的函数
‘GET /api/herolist’:[
…herolist
],
‘GET /api/heros’: function(req:Request,res:Response){
//可以延迟
setTimeout(()=>{
res.json({herolist,state:“ok”})
},3000)
}
}
export default () => {
fetch(‘/api/herolist’).then(res=>{
//console.log(res)
return res.json()
}).then(res=>{
console.log(res)
})
fetch(‘/api/heros’).then(res=>{
//console.log(res)
return res.json()
}).then(res=>{
console.log(res)
})
return (
<>
mall新页面
</>
);
};
现在目前为止都是测试mock,但是项目中真正应用接口应该配置service中的异步函数(然后在model中调用)
把index.js改成index.tsx,重新启动项目
import React from ‘react’;
import {getHeroList}from ‘…/…/services/heros’
export default () => {
// fetch(‘/api/herolist’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// fetch(‘/api/heros’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
getHeroList().then((res)=>{
console.log(res)
})
return (
<>
mall新页面
</>
);
};
数据请求后放到状态管理model
全局数据放到全局model,单页面数据放到页面文件夹model(方便识别管理)
这里在model文件夹下面新建mall.ts
import {Effect,Reducer} from ‘umi’
import{getHeroList}from ‘…/services/heros’
const HerosModel:any={
//命名空间
namespace:‘heros’,
//状态
state:{
herolist:[],
},
effects:{
*fetchHeroList(_,{call,put}){
const res= yield call(getHeroList)
//console.log(res)
yield put({
type:‘saveHerolist’,
payload:res
})
}
},
reducers:{
saveHerolist(state:any,action:any){
return{
…state,
herolist:action.payload
}
}
}
}
export default HerosModel
然后修改mall/index.tsx
import React, { useEffect } from ‘react’;
import { getHeroList } from ‘…/…/services/heros’
import { connect, Dispatch } from ‘umi’
const HeroMall = (props: any) => {
console.log(props)
useEffect(() => {
let { dispatch } = props
dispatch({
type: ‘heros/fetchHeroList’,
})
}, [])
// fetch(‘/api/herolist’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// fetch(‘/api/heros’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// getHeroList().then((res)=>{
// console.log(res)
// })
return (
<>
mall新页面
</>
);
}
export default connect(({ heros }: any) => ({ heros }))(HeroMall)
这里注意规范的import和export
另外connect的两个括号第一个放(返回值为(对象)的函数)形如({ heros }: any) => ({ heros })
,不然取不到state,第二个放组件
import React, { useEffect } from ‘react’;
// import { getHeroList } from ‘…/…/services/heros’
import { connect, Dispatch } from ‘umi’
const HeroMall = (props: any) => {
console.log(props)
useEffect(() => {
let { dispatch } = props
dispatch({
type: ‘heros/fetchHeroList’,
})
}, [])
// fetch(‘/api/herolist’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// fetch(‘/api/heros’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// getHeroList().then((res)=>{
// console.log(res)
// })
let { heros } = props
let herolist = heros && heros.herolist && heros.herolist.herolist
console.log(herolist)
return (
<>
mall--王者荣耀英雄
{herolist&&herolist.map((item:any,index:number)=>{
return(
- {item.cname}{'->'}{item.title}
)
})}
</>
);
}
export default connect(({ heros }: any) => ({ heros }))(HeroMall)
之后引入个Table做好看一点
import React, { useEffect } from ‘react’;
// import { getHeroList } from ‘…/…/services/heros’
import { connect, Dispatch } from ‘umi’
import { Table, Tag } from ‘antd’;
const HeroMall = (props: any) => {
console.log(props)
useEffect(() => {
let { dispatch } = props
dispatch({
type: ‘heros/fetchHeroList’,
})//触发model中的effect,带上命名空间
}, [])
// fetch(‘/api/herolist’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// fetch(‘/api/heros’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// getHeroList().then((res)=>{
// console.log(res)
// })
let { heros } = props
let herolist = heros && heros.herolist && heros.herolist.herolist
console.log(herolist)
// ename: 105
// cname: “廉颇”
// title: “正义爆轰”
// new_type: 0
// hero_type: 3
// skin_name: “正义爆轰|地狱岩魂”
const columns = [
{
title: ‘Id’,
dataIndex: ‘ename’,
key: ‘ename’,
render: text => {text},
},
{
title: ‘英雄’,
dataIndex: ‘cname’,
key: ‘cname’,
},
{
title: ‘皮肤’,
dataIndex: ‘title’,
key: ‘title’,
},
{
title: ‘Tags’,
key: ‘skin_name’,
dataIndex: ‘skin_name’,
render: (tags:string) => (
<>
{tags&&tags.split(‘|’).map(tag => {
let color = tag.length > 3 ? ‘geekblue’ : ‘green’;
return (
{tag}
);
})}
</>
),
},
];
return (
<>
mall--王者荣耀英雄
{/*
{herolist && herolist.map((item: any, index: number) => {
return (
- {item.cname}{'->'}{item.title}
)
})}
*/}</>
);
}
export default connect(({ heros }: any) => ({ heros }))(HeroMall)
页面内数据管理
在页面文件夹下面使用_mock.ts、model.ts、services.ts就可以了 建立方法和全局一样,路径要自己配置
import React, { useEffect } from ‘react’; // import { getHeroList } from ‘…/…/services/heros’
import { connect, Dispatch } from ‘umi’;
import { Table, Tag } from ‘antd’;
import HeroTableSearch from ‘./HeroTableSearch’;
const HeroMall = (props: any) => {
console.log(props);
useEffect(() => {
let { dispatch } = props;
dispatch({
type: ‘mall/fetchHeroList’,
}); //触发model中的effect,带上命名空间
}, []); // fetch(‘/api/herolist’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// fetch(‘/api/heros’).then(res=>{
// //console.log(res)
// return res.json()
// }).then(res=>{
// console.log(res)
// })
// getHeroList().then((res)=>{
// console.log(res)
// })
let { mall } = props;
let herolist = mall && mall.herolist && mall.herolist.herolist;
console.log(herolist); // ename: 105
// cname: “廉颇”
// title: “正义爆轰”
// new_type: 0
// hero_type: 3
// skin_name: “正义爆轰|地狱岩魂”
const columns = [
{
title: ‘Id’,
dataIndex: ‘ename’,
key: ‘ename’,
render: text => {text},
},
{
title: ‘英雄’,
dataIndex: ‘cname’,
key: ‘cname’,
},
{
title: ‘皮肤’,
dataIndex: ‘title’,
key: ‘title’,
},
{
title: ‘Tags’,
key: ‘skin_name’,
dataIndex: ‘skin_name’,
render: (tags: string) => (
<>
{tags &&
tags.split(‘|’).map(tag => {
let color = tag.length > 3 ? ‘geekblue’ : ‘green’;
return (
{tag}
);
})}
</>
),
},
];
return (
<>
mall--王者荣耀英雄
{/*
{herolist && herolist.map((item: any, index: number) => {
return (
- {item.cname}{'->'}{item.title}
)
})}
*/}</>
);
};
export default connect(({ mall }: any) => ({
mall,
}))(HeroMall);
顺便修改connect
加个搜索功能
用umi的控制加个高级搜索
表单组件代码修改
import styles from “./index.less”;
import React, { useState } from “react”;
import { Form, Row, Col, Input, Button } from “antd”;
import { DownOutlined, UpOutlined } from “@ant-design/icons”;
const AdvancedSearchForm = () => {
const [form] = Form.useForm();
const getFields = () => {
const children = [];
children.push(
(
<Form.Item
name=“hero”
label=‘英雄’
rules={[{
required:true,
最后前端到底应该怎么学才好?
如果你打算靠自己摸索自学,那么你首先要了解学习前端的基本大纲,这是你将要学习的主要内容,理解以及掌握好这些内容,便可以找到一份初级的前端开发工作。你还需要有一套完整的前端学习教程,作为初学者最好的方式就是看视频教程学习,初学者容易理解接受。
不要选择买书学习,这样的方式没有几个人能学会,基本都是看不下去书,也看不懂书。如果喜欢看书的学弟,可以买一些经典的书籍作为辅助即可,主要还是以看教程为主。每天抽出固定几个小时学习,做好长期学习的准备。学习编程并不是每天光看视频,你学习编程最重要的目的是为了编写软件产品,提供给大众使用,所以用手写出代码实现功能才是我们要做的事情。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
果喜欢看书的学弟,可以买一些经典的书籍作为辅助即可,主要还是以看教程为主。每天抽出固定几个小时学习,做好长期学习的准备。学习编程并不是每天光看视频,你学习编程最重要的目的是为了编写软件产品,提供给大众使用,所以用手写出代码实现功能才是我们要做的事情。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】