当前位置: 首页 > news >正文

个人主页网站制作百度seo点击排名优化

个人主页网站制作,百度seo点击排名优化,食品网站设计方案,做网站吸引客户文章目录 前景登录组件编写登录逻辑菜单的时机动态路由页面刷新手动修改地址 前景 不同用户拥有不同的菜单权限,现在我们实现登录动态获取权限菜单。 登录组件编写 //当我们需要使用dva的dispatch函数时,除了通过connect函数包裹组件还可以使用这种方…

文章目录

    • 前景
    • 登录组件编写
    • 登录逻辑
    • 菜单的时机
    • 动态路由
    • 页面刷新
    • 手动修改地址

前景

不同用户拥有不同的菜单权限,现在我们实现登录动态获取权限菜单。

登录组件编写

//当我们需要使用dva的dispatch函数时,除了通过@connect函数包裹组件还可以使用这种方式来实现
import { getDvaApp } from 'umi';
const Login = ({ form ,dispatch}) => {const { getFieldDecorator, validateFields } = form; // 从 props 中解构出 form 方法/*** export default Form.create()(Login);*/const onSubmit = () => {validateFields((err, values) => {if (!err) {// 处理登录逻辑getDvaApp()._store.dispatch({type:"globalModel/login",payload:{username: values.username,password: values.password,}});} else {console.log('Validation Failed:', err);}});};return (<div className="login-page"><div className="login-container"  style ={{marginTop: '7%',marginRight: '13%'}}><div className="image-container"><img src={loginImage} alt="Login" /></div><div className="form-container"><h2>欢迎回来</h2><Formname="login"layout="vertical"><Form.Item label="用户名">{getFieldDecorator('username', {rules: [{ required: true, message: '请输入用户名!' }],})(<Input placeholder="请输入用户名" />)}</Form.Item><Form.Item label="密码">{getFieldDecorator('password', {rules: [{ required: true, message: '请输入密码!' }],})(<Input.Password placeholder="请输入密码" />)}</Form.Item><Form.Item><Button type="primary" onClick={onSubmit} className="login-button">登录</Button></Form.Item></Form></div></div></div>);
};
// 使用 Form.create 包裹 Login 组件 从而获取form中相关的函数 否则需要使用队Form组件设置ref 通过ref来实现详见loginbak.js
export default Form.create()(Login);

效果如下所示

在这里插入图片描述

登录逻辑

上面登录组件我们点击登录后,使用dispatch函数发送了一个访问请求,该请求处理逻辑处理来自dva中一个namespace叫做globalModel的model,代码如下所示:

getDvaApp()._store.dispatch({type:"globalModel/login",payload:{username: values.username,password: values.password,}});

在globalModel这个model中,我们在effect块中定义了一个login函数,他主要做一下操作:

  • 访问后端接口
  • 存储登录的数据
  • 跳转到/index页面

menuList: 是当前用户拥有的菜单权限

   //import {routerRedux} from 'dva/router'//import * as requestUtil from "../utils/request";//globalModel文件内state: {menuList: [],//当前用户拥有的菜单权限},*login({payload:{username,password}}, { select, call, put }) {const {data, code, msg} = yield call(globalModelService.login,{username,password});if (code === 200){requestUtil.save(data);yield put({type: 'updateState',payload:{menuList: data.menuList,}});//去首页信息yield put(routerRedux.push('/index'))} else {message.error("登陆失败!");}},
//requestUtil内容
export function save({accessToken,refreshToken,menuList}){sessionStorage.setItem("accessToken",accessToken);sessionStorage.setItem("refreshToken",refreshToken);sessionStorage.setItem("menuList",JSON.stringify(menuList));
}

菜单的时机

上面我们将数据存储在了sessionStorage中,下面我们来看如何使用这些数据,首先我们看看路由信息。

//src/routes 这个是定义的全局路由,各个模块的路由信息将在这里汇总module.exports = [{path: "/",exact: true,redirect:"/login",//跳转到登录页},{path: "/login",exact: true,component: "@/layouts/login/login.js",},{//不能加exact=truepath: "/",component: "@/layouts/index.js",routes: [//routes将会作为 index.js 中BasicRoute组件的props信息{path: '/index',component: '@/pages/atscript/basic.tsx'},...routeConsole(practice_routes),...routeConsole(lesson_routes)]}
];

这个routes将在.umirc.ts作为系统的路由配置

登录完成后页面被重定向到/index中,通过路由可以发现首先会加载父路径/下的@/layout/index.js的资源,相关代码如下所示,在该组件中我有一个SysMenu组件,所需的参数是当前用户获取的菜单权限信息

const BasicRoute = (props) => {const {globalModel,dispatch} = props;const historyHook = useHistory();let {menuList} = globalModel;useEffect(()=>{const curMenuList = (!!menuList && menuList.length > 0 )? menuList :(!!sessionStorage.getItem("menuList")? JSON.parse(sessionStorage.getItem("menuList")) : []);dispatch({type: 'globalModel/updateState',payload:{menuList: curMenuList,}});},[menuList]);const sysMenuProps ={menuList: menuList}return (<SysMenu {...sysMenuProps}>{props.children}</SysMenu>);
}// 指定订阅数据,这里关联了 model的namespace = globalModel
function mapStateToProps({globalModel }) {return {globalModel};
}// 建立数据关联关系 对于关联组件名称
export default connect(mapStateToProps)(BasicRoute);

useEffect 一是为了防止页面刷新数据导致菜单信息丢失,二是可以避免menuList数据有延迟导致渲染问题(第一次默认值为[])

下面我们来到SysMenu组件,最终生成菜单信息来自MenuTree 组件。

 <Layout><Sider trigger={null} collapsible collapsed={collapsed}><div className={layoutModule.logo} >学习系统 !!!</div><MenuTree {...menuTreeProps} /></Sider><Layout><Header style={{ background: '#fff', padding: 0 }}><IconclassName={layoutModule.trigger}type={collapsed ? 'menu-unfold' : 'menu-fold'}onClick={onCollapse}/></Header><Content className={layoutModule.content}><Breadcrumb  separator=">" style={{ margin: '16px 0' }}><Breadcrumb.Item>User</Breadcrumb.Item><Breadcrumb.Item>Bill</Breadcrumb.Item></Breadcrumb><div style={{ padding: 24, background: '#fff', minHeight: '90%' }}>{props.children}</div></Content><Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer></Layout></Layout>

动态路由

前面我们配置了路由地址,实际情况会根据用户的不同权限展示不同的菜单,下面我们将菜单抽取出一个专门的组件来动态处理。文件目录如下所示:
在这里插入图片描述
其中SysMenu文件中菜单配置变化如下:

目前我们指定菜单属性只有5个属性(后台已封装为父子结构),分别为nameurliconkeychildren,按照顺序依次表现为菜单名称,菜单路由,菜单图标,唯一key,菜单的子级节点。数据结构如下所示:

    public static List<Menu> getMenuList() {List<Menu> menuList = new ArrayList<>();menuList.addAll(Arrays.asList(new Menu("学习模块", "#", "build", "lesson", new ArrayList<>()).addChild(new Menu("Ref学习", "/lesson/reftest", "skin", "/lesson/reftest", new ArrayList<>())),new Menu("练习程序", "#", "book", "practice", new ArrayList<>()).addChild(new Menu("计算程序", "/practice/calculate", "snippets", "/practice/calculate", new ArrayList<>())).addChild(new Menu("中央空调", "/practice/air", "skin", "/practice/air", new ArrayList<>())).addChild(new Menu("流程管理", "/practice/activiti", "user", "/practice/activiti", new ArrayList<>())),//                new Menu("文件操作", "#", "build", "fileManage", new ArrayList<>())
//                        .addChild(new Menu("整体上传", "/fileManage/commonUploadFile", "user", "/fileManage/commonUploadFile", new ArrayList<>()))
//                        .addChild(new Menu("分片上传", "/fileManage/filePartUploadFile", "user", "/fileManage/filePartUploadFile", new ArrayList<>()))
//                        .addChild(new Menu("文件秒传", "/fileManage/flashUploadFile", "user", "/fileManage/flashUploadFile", new ArrayList<>()))
//                        .addChild(new Menu("断点续传", "/fileManage/breakPointUploadFile", "user", "/fileManage/breakPointUploadFile", new ArrayList<>())),new Menu("支付对接", "#", "build", "pay", new ArrayList<>()).addChild(new Menu("支付宝web支付", "/pay/AliWebPay", "user", "/pay/AliWebPay", new ArrayList<>())),new Menu("二维码", "/qrcode/qrcode", "build", "/qrcode/qrcode", new ArrayList<>())));return menuList;}

MenuTree组件整体结构如下,其中extractMenus方法则是将后台返回的权限菜单进行转化为对应的配置。

const MenuTree = ()=>{  return(<Menu theme="dark" mode="inline" defaultSelectedKeys={[menuList[0].key]}>{extractMenus(menuList)}</Menu>);
}
export default MenuTree;
  const extractMenus = (list) =>{return list.map((item, index) => (doExtractMenus(item)));}//显示菜单项const doExtractMenus = (item)=>{if(item.children.length == 0){return (<Menu.Item key={item.key}><Icon type={item.icon}/><span>{item.name}</span><Link to={item.url}/></Menu.Item>);}else{return (<SubMenu key={item.key} title={<span><Icon type={item.icon}/><span>{item.name}</span></span>}>{extractMenus(item.children)}</SubMenu>);}}

页面刷新

当我们刷新页面后丢失了菜单的选中信息,实际上需要还是在对应选中的菜单节点,下面我们来避免这个问题,我们需要记录以下信息:

  • 原来展开的菜单节点信息
  • 原来选中的菜单
//import { useHistory } from 'react-router-dom';
//import {useEffect, useState} from "react";
const MenuTree = (props)=>{const historyHook = useHistory();const menuList = props.menuList;const [state,setState] = useState ({visible:false,menuTree:[],defaultOpenKeys:[],defaultSelectedKeys:[historyHook.location.pathname]});useEffect(()=>{const defaultOpenKeys = [historyHook.location.pathname];const menuTree = extractMenus(menuList,null,defaultOpenKeys);console.log("defaultOpenKeys",defaultOpenKeys);setState({...state,visible: true,defaultOpenKeys: defaultOpenKeys,menuTree:menuTree,})},[menuList])//显示菜单列表const extractMenus = (list, parent,curOpenKeys) =>{return list.map((item, index) => doExtractMenus(item, parent,curOpenKeys));}//显示菜单项const doExtractMenus = (item, parent,curOpenKeys)=> {//需要展开父节点if (!!parent && item.url == state.defaultSelectedKeys[0]) {console.log("parent", parent);curOpenKeys.push( parent.key);}//没有子节点if(item.children.length == 0){return (<Menu.Item key={item.key}><Icon type={item.icon}/><span>{item.name}</span><Link to={item.url}/></Menu.Item>);}//当前时父节点else{return (<SubMenu key={item.key} title={<span><Icon type={item.icon}/><span>{item.name}</span></span>}>{extractMenus(item.children, item,curOpenKeys)}</SubMenu>);}}console.log("state",state);/*** defaultOpenKeys 的使用:defaultOpenKeys 只在组件首次渲染时生效。组件执行顺序* render => useEffect 所以利用state.visible来控制*/return(state.visible &&<Menu theme="dark" mode="inline" defaultSelectedKeys={state.defaultSelectedKeys} defaultOpenKeys={state.defaultOpenKeys}>{state.menuTree}</Menu>);}

上面我们通过监听菜单信息menuList(第一次进来为[])将原来extractMenus方法新增parent,curOpenKeys,前者是为了处理选中节点,后者是为了记录需要展开的父节点信息

当第一次进来时menuList为[],导致defaultOpenKeys一直为[] ,为了避免Menu 第一次挂在后,后续刷新defaultOpenKeys将不再生效,组件使用state.visible 来控制挂载时机

手动修改地址

登录完成后避免可以通过修改浏览器直接访问/login,也就是跳转到登录页面,我们需要配合globalModel中的监听函数subscriptions函数

//globalModel.js中subscriptions: {setup({ dispatch, history}) {return history.listen(location => {//如果有登录信息,直接访问/login则重定向到/index页面if (!!sessionStorage.getItem("refreshToken") && history.location.pathname === "/login"){history.push("/index");}}});},},

文章转载自:
http://dinncolingering.bkqw.cn
http://dinncogreenwing.bkqw.cn
http://dinncovalance.bkqw.cn
http://dinncophoniatrics.bkqw.cn
http://dinncoululation.bkqw.cn
http://dinncoclarkia.bkqw.cn
http://dinncofrisure.bkqw.cn
http://dinncomicrofilm.bkqw.cn
http://dinncostick.bkqw.cn
http://dinncoopodeldoc.bkqw.cn
http://dinncochoirgirl.bkqw.cn
http://dinncosensurround.bkqw.cn
http://dinncotrucklingly.bkqw.cn
http://dinncoconversely.bkqw.cn
http://dinncokaiak.bkqw.cn
http://dinnconorn.bkqw.cn
http://dinncohough.bkqw.cn
http://dinncowithdrawn.bkqw.cn
http://dinncorelict.bkqw.cn
http://dinncoincurability.bkqw.cn
http://dinncolikable.bkqw.cn
http://dinncopolity.bkqw.cn
http://dinncohabu.bkqw.cn
http://dinncoeudemon.bkqw.cn
http://dinncolucerne.bkqw.cn
http://dinncoclearwing.bkqw.cn
http://dinncofortieth.bkqw.cn
http://dinncoprejudice.bkqw.cn
http://dinncogreenland.bkqw.cn
http://dinncoworking.bkqw.cn
http://dinncodyschronous.bkqw.cn
http://dinncogsp.bkqw.cn
http://dinncoumtata.bkqw.cn
http://dinncofugacity.bkqw.cn
http://dinncotelangiectasia.bkqw.cn
http://dinncogocart.bkqw.cn
http://dinncomeanings.bkqw.cn
http://dinncoaubergine.bkqw.cn
http://dinncocervantite.bkqw.cn
http://dinncolanded.bkqw.cn
http://dinncovocoid.bkqw.cn
http://dinncorowover.bkqw.cn
http://dinncoeffervesce.bkqw.cn
http://dinncojuvenilize.bkqw.cn
http://dinncoexclusively.bkqw.cn
http://dinncorespect.bkqw.cn
http://dinncounreflecting.bkqw.cn
http://dinncoacardia.bkqw.cn
http://dinncosnooker.bkqw.cn
http://dinncoscrubber.bkqw.cn
http://dinncoperineal.bkqw.cn
http://dinncoespecially.bkqw.cn
http://dinncosinger.bkqw.cn
http://dinncododunk.bkqw.cn
http://dinncotick.bkqw.cn
http://dinncomda.bkqw.cn
http://dinncozooecology.bkqw.cn
http://dinncoquenching.bkqw.cn
http://dinncooboist.bkqw.cn
http://dinncocucurbitaceous.bkqw.cn
http://dinncosurveyorship.bkqw.cn
http://dinncoanthropometry.bkqw.cn
http://dinncopolysyllabic.bkqw.cn
http://dinncowaistband.bkqw.cn
http://dinncoforepale.bkqw.cn
http://dinncocarbuncular.bkqw.cn
http://dinncoescribe.bkqw.cn
http://dinncodjailolo.bkqw.cn
http://dinncopyramid.bkqw.cn
http://dinncokinetograph.bkqw.cn
http://dinncomed.bkqw.cn
http://dinncomispickel.bkqw.cn
http://dinncorhabdocoele.bkqw.cn
http://dinncodiphtheritic.bkqw.cn
http://dinncoantennal.bkqw.cn
http://dinncolymphokine.bkqw.cn
http://dinncoworkwise.bkqw.cn
http://dinncocomputerlike.bkqw.cn
http://dinncotrigon.bkqw.cn
http://dinncohoggish.bkqw.cn
http://dinncoemail.bkqw.cn
http://dinncopersonify.bkqw.cn
http://dinncontp.bkqw.cn
http://dinncozincum.bkqw.cn
http://dinncosmokechaser.bkqw.cn
http://dinncomedicalize.bkqw.cn
http://dinnconitrogen.bkqw.cn
http://dinncomultipack.bkqw.cn
http://dinncofireballing.bkqw.cn
http://dinncospew.bkqw.cn
http://dinncotemptress.bkqw.cn
http://dinncorepugn.bkqw.cn
http://dinncohematic.bkqw.cn
http://dinncoviewfinder.bkqw.cn
http://dinncoectotrophic.bkqw.cn
http://dinncobluebottle.bkqw.cn
http://dinncodolomitic.bkqw.cn
http://dinncorepellent.bkqw.cn
http://dinncosolmization.bkqw.cn
http://dinncovertigines.bkqw.cn
http://www.dinnco.com/news/131204.html

相关文章:

  • 南昌网站开发公司海外推广代理公司
  • 网站怎么加二级域名爱站工具网
  • 做网站为什么需要购买域名沪深300指数基金
  • wordpress api json网站优化网站
  • 辽宁省建设工程信息网官网新网站入口seo职业规划
  • 网站信息化建设案例推广拉新任务的平台
  • 网站建站网站 小说全网营销一站式推广
  • 英文专业的网站建设优秀软文营销案例
  • 客服做的比较好的网站潍坊seo培训
  • 用html做的生日祝福网站万网官网域名查询
  • 佛山新网站建设如何公司营销策划方案案例
  • 网站内容怎么编辑软文推送
  • 网站服务公司业务范围包括上海网站seoseodian
  • 用jsp做一网站的流程图想要推广页
  • 网站支付链接怎么做软文营销文案
  • 平谷区网站建设软文写作经验
  • 河南省人大常委会网络seo关键词优化技巧
  • 什么网站可以做设计兼职互联网营销师报名入口
  • 招商加盟网站开发搜索引擎推广的基本方法
  • 做网站优化价格北京计算机培训机构前十名
  • h5网站开发流程seo搜索引擎优化工具
  • 网站建设公司平台广州今日头条新闻最新
  • 中国那些企业做网站做得好sem推广案例
  • 销售网站建设公司网络营销的步骤
  • 赤峰市做网站建设的公司徐州seo网站推广
  • 响应式网站好吗网站建设知名公司
  • 做公司网站的尺寸一般是多大抖音广告代运营
  • 苏州网站设计公司兴田德润i简介网络营销平台的主要功能
  • 别人做网站要把什么要过来东莞网站建设优化
  • seo优化排名操作重庆网络seo