欢迎访问皮皮网官网
皮皮网

【Java寻秦源码文本】【智能分析指标源码】【ueditor 源码被过滤】jssetstate源码

时间:2024-11-25 01:52:41 分类:休闲 来源:仿公益网站源码

1.jssetstateԴ?源码?
2.js / ajax 成功提交后怎么跳转到另外一个页面?
3.reactadmin?
4.React Fiber原理?

jssetstate源码

jssetstateԴ??

       基于preact.3.4版本进行分析,完整注释请参阅链接。源码阅读源码建议采用跳跃式阅读,源码遇到难以理解的源码部分先跳过,待熟悉整体架构后再深入阅读。源码如果觉得有价值,源码Java寻秦源码文本不妨为项目点个star。源码

       一直对研究react源码抱有兴趣,源码但每次都半途而废,源码主要原因是源码react项目体积庞大,代码颗粒化且执行流程复杂,源码需要投入大量精力。源码因此,源码转向研究preact,源码一个号称浓缩版react,源码体积仅有3KB。市面上已有对preact源码的解析,但大多存在版本过旧和分析重点不突出的问题,如为什么存在_nextDom?value为何不在diffProps中处理?这些都是解析代码中的关键点和收益点。

       一. 文件结构

       二. 渲染原理

       简单demo展示如何将App组件渲染至真实DOM中。

       vnode表示节点描述对象。在打包阶段,babel的transform-react-jsx插件会将jsx语法编译为JS语法,即转换为React.createElement(type, props, children)形式。preact中需配置此插件,使React.createElement对应为h函数,编译后的jsx语法如下:h(App,null)。

       执行render函数后,先调用h函数,然后通过createVNode返回虚拟节点。最终,h(App,null)的执行结果为{ type:App,props:null,key:null,ref:null},该虚拟节点将被用于渲染真实DOM。

       首次渲染时,旧虚拟节点基本为空。diff函数比较虚拟节点与真实DOM,创建挂载完成,执行commitRoot函数,该函数执行组件的did生命周期和setState回调。

       2. diff

       diff过程包含diff、diffElementNodes、diffChildren、diffProps四个函数。diff主要处理函数型虚拟节点,非函数型节点调用diffElementNodes处理。判断虚拟节点是否存在_component属性,若无则实例化,执行组件生命周期,调用render方法,保存子节点至_children属性,进而调用diffChildren。智能分析指标源码

       diffElementNodes处理HTML型虚拟节点,创建真实DOM节点,查找复用,若无则创建文本或元素节点。diffProps处理节点属性,如样式、事件监听等。diffChildren比较子节点并添加至当前DOM节点。

       分析diff执行流程,render函数后调用diff比较虚拟节点,执行App组件生命周期和render方法,保存返回的虚拟节点至_children属性,调用diffChildren比较子节点。整体虚拟节点树如下:

       diffChildren遍历子节点,查找DOM节点,比较虚拟节点,返回真实DOM,追加至parentDOM或子节点后。

       三. 组件

       1. component

       Component构造函数设置状态、强制渲染、定义render函数和enqueueRender函数。

       强制渲染通过设置_force标记,加入渲染队列并执行。_force为真时,diff渲染不会触发某些生命周期。

       render函数默认为Fragment组件,返回子节点。

       enqueueRender将待渲染组件加入队列,延迟执行process函数。process排序组件,渲染最外层组件,调用renderComponent渲染,更新DOM后执行所有组件的did生命周期和setState回调。

       2. context

       使用案例展示跨组件传递数据。createContext创建context,包含Provider和Consumer组件。Provider组件跨组件传递数据,Consumer组件接收数据。

       源码简单,createContext后返回context对象,包含Consumer与Provider组件。Consumer组件设置contextType属性,渲染时执行子节点,等同于类组件。

       Provider组件创建函数,渲染到Provider组件时调用getChildContext获取ctx对象,diff时传递至子孙节点组件。组件设置contextType,通过sub函数订阅Provider组件值更新,值更新时渲染订阅组件。ueditor 源码被过滤

       四. 解惑疑点

       理解代码意图。支持Promise时,使用Promise处理,否则使用setTimeout。了解Promise.prototype.then.bind(Promise.resolve())最终执行的Promise.resolve().then。

       虚拟节点用Fragment包装的原因是,避免直接调用diffElementNodes,以确保子节点正确关联至父节点DOM。

       hydrate与render的区别在于,hydrate仅处理事件,不处理其他props,适用于服务器端渲染的HTML,客户端渲染使用hydrate提高首次渲染速度。

       props中value与checked单独处理,diffProps不处理,处理在diffChildren中,找到原因。

       在props中设置value为空的原因是,遵循W3C规定,不设置value时,文本内容作为value。为避免MVVM问题,需在子节点渲染后设置value为空,再处理元素value。

       组件异常处理机制中,_processingException和_pendingError变量用于标记组件异常处理状态,确保不会重复跳过异常组件。

       diffProps中事件处理机制,为避免重复添加事件监听器,只在事件函数变化时修改dom._listeners,触发事件时仅执行保存的监听函数,移除监听在onChange设置为空时执行。

       理解_nextDom的使用,确保子节点与父节点关联,避免在函数型节点渲染时进行不必要的关联操作。

js / ajax 成功提交后怎么跳转到另外一个页面?

       sx/ajax提交成功后采用以下方式跳转:

       1、本页面跳转:"window.location.href"、"location.href" 

       2、上一层页面跳转:"parent.location.href"

       3、最外层的页面跳转:"top.location.href"

       @RequestMapping(value="searchUser")

       publicvoidsearchHome(HttpServletResponseresponse){

       Stringresult=null;

       ...

       查询用户的方法

       ...

       if(查询成功){

       result=JsonUtil.objectToJson(查询结果对象);//结果对象转化成Json字符串,在ajax的结果中跳转到用户详情的处理方法

       AjaxUtil.ajax(response,result);

       }else{ //查询失败,返回提示信息

       AjaxUtil.error(response,"查询用户失败");

       }

       }

扩展资料

       jsp页面的ajax:

       此处的重点在于如何在ajax的回调函数中调用普通方法,并将之前查询出的用户数据传到普通方法中(上面伪代码中红色的部分),继而跳转到用户详情页面。

       在body中写隐藏的form表单,在回调函数中把查到的用户数据复制给form表单中的input,然后提交表单跳转到普通方法中,这样就是以post方法提交的数据,并且可以跳转到新页面。

reactadmin?

       开箱即用的钝化kdj指标源码React前端框架——ReactAdmin

       ReactAdmin是一个Github上免费开源的前端框架(不是组件库,也不是模板,它是一个框架),采用es6、React和MaterialDesign构建基于Rest/GraphQlAPI的Web应用程序。在React上star数超过8k。

       ReactAdmin不是个UI组件库,它是一个前端框架,因此你基本上基本上只要按照官网的文档进行一些配置等然后在其基础上开发自己的应用程序即可,可谓开箱即用,意识就是都给你集成好了。

       你可以直接使用以下命令进行安装(这是安装react-admin及所有的依赖)

       下面我们看一下官网提供的一个最简单的示例,你可以在它的主仓库中获取

       我们进入到simple中,大致看一下代码和目录结构

       我们安装一些依赖然后启动

       成功后打开浏览器,这是使用react-admin最简单的一个例子

       一图了解

       由于ReactAdmin是一个非常复杂的框架,你可以参考提供的文档,我这里就不详细介绍了,感兴趣的可以直接看文档,文档是英文的,所有的说明都在文档中。

       ReactAdmin它是一个集合,它将一些前端开发所需要的东西都集成了进来,然后做好,我们直接使用即可,不仅仅适合个人学习,也适合通过它来构建企业级的应用。我们不仅仅是拿过来直接用,我们可看一看别人是怎么实现这样的一个框架的,从源码去学习会更快的提升自己的水平,希望对你有所帮助!

       react-admin一款基于reactjs后台解决方案

       使用ES6,React和MaterialDesign在REST/GraphQLAPI之上构建在浏览器中运行的管理应用程序的一款前端框架。Githubstar8.7K+,MIT协议。由marmelab开源和维护。marmelab还有一款非常热门的angularjs后台解决方案ng-admin基于angularjs感兴趣的同学可以去了解下。react-admin官网示例截图如下:

       该Resource组件是一个配置组件,它允许以限定子组件对于每个管理视图的:list,edit,和create。这些组件使用MaterialUI和react-admin中的自定义组件:

antdesign表格标题下面还有子标题

       一、如图展示表格如何展示下方嵌套的deptName

       在这里插入描述

       官网在这里插入描述

       二、解决方案

       Columnalign="center"title="部门"dataIndex={ ["dept","deptName"]}/

       1

       1

       技术交流分享/面试总结

       微信名片

       打开CSDNAPP,看更多技术内容

       最新发布保姆级教程:AntDesignVue中a-table嵌套子表格

       AntDesignVue中a-table嵌套子表格及只打开一个嵌套表格的方法

       继续访问

       Antd(Ant-design),嵌套子表格(expandedRowRender)的异步获取数据

       使用阿里的ant-design开源框架,要在表格里面嵌套子表格,需要在用户点击父表格的一行数据后,获取该行的key,然后去异步请求后台的数据用来填充子表格的内容。如果这样写(省略无关代码):expandedRowRender=(record)={ dispatch({ type:'flow/getPlanList',payload:{ contractId:record.contract_id,//该参数...

       继续访问

       react-antdesigntable表格多级可编辑表格

       antd-react3X版本多级可编辑table

       继续访问

       react.jsant-design中table树结构三级嵌套时逻辑问题

       实现三级嵌套树结构时,勾选三级里的截取网页源码片段子节点时候父节点也会自动勾选,当子节点大于一项时候取消勾选某一子结构时父节点不变;当子节点只有一项时父节点也会自动取消勾选importStandardTablePagefrom'@/components/StandardTablePage';//用户选中某一行userSelect(record,selected,selectedRows,nativeEvent){ let{ selectedRowKeys}=this.st.

       继续访问

       Reactantd的table表格之嵌套表格

       Reactantd的table表格之嵌套表格最近做了几个pc端的后台管理需求,涉及了table中的嵌套表格,嵌套的子表格大体分为两种效果:效果1-----点击展开新的子表格,旧的子表格关闭效果2-----可同时展开多个子表格效果1:嵌套表格,实现点击展开按钮,展开子表格请求接口数据,点击新的子表格收起原来的子表格效果//设置一个State用来储存展开的行,控制属性const[expandedRowKeys,setExpandedRowKeys]=useStateanygt

       继续访问

       vue嵌套表格组件_支持嵌套对象、多级数组的Vue动态多级表单组件——vue-dynamic-form-component...

       方便不想看完全篇文章的童鞋,简单总结一下,这是篇软广,主要是推广自己在业务中沉淀的一个开源组件vue-dynamic-form-component。基于element-ui实现的vue组件,只需编写类似async-validator的规则,自动生成对应的表单,支持常见输入类型的同时,支持嵌套对象、hashmap、多维数组等复杂类型。有需要的童鞋欢迎使用和贡献代码,顺便给个star(我...

       继续访问

       antdtable嵌套子表格后端动态获取数据rudex写法示例

       有一个需求是可以使主表格里每一栏数据展开,在子table里显示与其相关的子数据项,展开的时候去向后台请求数据显示。用的组件库是Antd。首先我们看Antd官方文档的Table有嵌套子表格的功能,可见我们需要使用expandedRowRender参数,但是尝试在expandedRowRender函数中进行请求,会发现发出了连续的请求,所以我们把请求写在onExpand中,只在点击展开图表的时候发出一次。之后我们写onExpand函数,注意这里的参数要写上expanded,代表是展开还是合并,我之前

       继续访问

       React-Antd-表格-嵌套子表格

       文档地址:链接.import{ Table,Badge,Menu,Dropdown,Space}from"antd";import{ DownOutlined}from"@ant-design/icons";import{ useEffect,useState}from"react";exportdefaultfunctionApp(){ constcolumns=[//定义外层表格头数据{ title:"姓名",dataInde

       继续访问

       ReactantdTable实现单元格点击表头斜线分组等功能

       reactantd单元格添加点击事件自定义单元格

       继续访问

       进阶Ant-Design-Vue你知道table多级表头嵌套展开写法吗?

       前言:在Ant-Design-Vue的前端项目中,我们会经常处理表格,表单这些组件元素,熟练运用并知道它们在使用过程中的联系与区别,这是一个前端必不可少的哟。本文我旨在解决两个问题:(1)如何便于更好的嵌套多级表头(2)如何通过a-checkbox控制全选,单选显示a-table对应的列元素类似于ElementUI,Ant-Design-vue中有很多相似点,但又不完全苟同,有很多自己独有的写法和思想。相信很多人都是先入手ElementUI,再入手Ant,这其实是对开发者比较友好的方式,如果

       继续访问

       前端面试题(react)

       性能优化分为2个方面setState是修改其中的部分状态,相当于Object.assign,只是覆盖,不会减少原来的状态;replaceState是完全替换原来的状态,相当于赋值,将原来的state替换为另一个对象,如果新状态属性减少,那么state中就没有这个状态了接收旧的state和action,返回新的state受控组件就是可以被react状态控制的组件在react中,Inputtextarea等组件默认是非受控组件(输入框内部的值是用户控制,和React无关)

       继续访问

       Antd表格设置表头分组实现可编辑行

       主要通过onCell方法修改children中cloumn的属性。

       继续访问

       antd能自适应吗_admin-antd-react是一个后台前端解决方案,它基于React、AntDesign和UmiJs实现。...

       admin-antd-react是一个后台前端解决方案,它基于React、AntDesign和UmiJs实现。--::?阅读次#介绍[admin-antd-react]()是一个后台前端解决方案,它基于[React](...

       继续访问

       react-antd-Table相似表格不同字段处理

       1、当两个表格字段相似时,但有一两个字段不同,我们可以将不同的字段单独以对象的形式抽出,根据情况push进去即可。2、代码参考constchange={ title:'操作',dataIndex:'operate',key:'operate',width:'%',align:'center',render:(text,record)={

       继续访问

       React中控制AntDesignTable列的显示与隐藏

       React中控制AntDesignTable列的显示与隐藏

       继续访问

       热门推荐使用antd中Table组件某一列有多个变量值需要写入

       当某一列需要有多个变量值写入时,我们就不可以再用dataIndex来定义一个ID,具体解决方案将在文中给出。

       继续访问

       reactant-designtable显示数据以及上传数据显示到另一列中

       需求是:用table展示数据,并在每一行的最后一列中给一个上传附件的按钮,可上传多个附件,上传之后在另一列去显示数据,可以删除附件因为有别的组件用到columns,他不需要上传附件功能,我就把columns的公共部分提出去了,在这个组件需要的时候在push到column中。columns如下:/***处理上传附件列*/handleColumn=()={ letcArr=this.state.columns;

       继续访问

       antd表单一个label下多个内容

       1.如何实现一个label旁并排多项内容比如这样,在other的label下,既有输入文本域,又有toggle开关。同时两者有序地并排在右侧,同一行。方法是再用一层Form.Item分别包裹右侧内容,并且设置noStyle属性示例代码:Form.Itemlabel="DateofBirth:"Form.Itemname="birthDate"noStyle

       继续访问

       React针对antDesignselect组件进行二次封装

       React针对antDesign库select组件进行二次封装由于业务需要对select进行样式上的修改,部分select还需要使用原样式。这种情况可以通过两种方式来实现:1通过className进行样式覆盖2通过二次封装组件,相对于仅修改css样式来说更加的灵活本次介绍第二种方式对组件进行二次封装/**@Date/5/8*@Authorzuolinya*@Descriptionantdselect组件二次封装*1设置为圆角*/import

       继续访问

       React基于AntdDesign的RadioGroup按钮组控件封装

开源Vue后端UI开箱即用解决方案——vuestic-admin

       这是一个Vue的后端开箱即用UI项目框架,和之前的ReactAdmin类似,它是一个框架,也就意味着它帮你完成了很多公用的部分,你只需要在其基础上进行自己的项目扩展即可。大体上这是由Vue和bootstrap4构建的,其中还集成了很多其他的东西。

       如果你使用yarn你也可以使用它安装

       在安装好vuestic后,你就可以使用它进行项目创建了

       创建好后大致看一下目录结构(可能不清晰,你可以直接搭建体验)

       成功后打开localhost:

       如果你想详细的学习,你可以查看官网文档

       浏览器兼容性,很遗憾只支持到IE+和主流的Chrome、FireFox、Safari、Edge等

       目前有很多开箱即用的解决方案,还有一些仅仅是UI模板,每个解决方案都有各自的优势,我们尽可能的减少不必要的开发时间浪费,在通用的基础上在扩展,最主要的还是学习看源码,希望对大家有所帮助,谢谢!

react中实现登录鉴权

       vue中会使用导航守卫判断token,

       react中使用redirect方式

       使用高阶组件定义PrivateRoute导出

       在router中用

PrivateRoute?path="/admin/roles"?exact?component={ Roles}/PrivateRoute

       的方式判断需要token的路由

       import?React,?{ ?Component?}?from?'react'

       import?{ Redirect,?Route}?from?'react-router-dom'

       function?PrivateRoute({ ?component:Children,?...rest?})?{

       return?(

Route

       { ...rest}

       render={ ()?={

let?token?=?localStorage.getItem('token')

       if(token){

       return?Children/

       }else{

       returnRedirect

       to={

       '/login'

       }/

       }

       }

       }

/

       );

}

export?default?PrivateRoute

React Fiber原理?

       Fiber的特点/作用

       Fiber能够使得动画、布局和页面交互变得更加的流畅。

       一:Fiber的概念

         React Fiber是react执行渲染时的一种新的调度策略,JavaScript是单线程的,一旦组件开始更新,主线程就一直被React控制,这个时候如果再次执行交互操作,就会卡顿。

         React Fiber就是通过对象记录组件上需要做或者已经完成的更新,一个组件可以对应多个Fiber。

         在render函数中创建的React Element树在第一次渲染的时候会创建一颗结构一模一样的的Fiber节点树。不同的React Element类型对应不同的Fiber节点类型。一个React Element的工作就由它对应的Fiber节点来负责。

         一个React Element可以对应不止一个Fiber,因为Fiber在update的时候,会从原来的Fiber(我们称为current)clone出一个新的Fiber(我们称之为alternate)。俩个Fiber diff出的变化(side effect)记录在alternate上。所以一个组件在更新时最多会有俩个Fiber与其对应,在更新结束后alternate会取代之前的current称为新的current节点。

         React Fiber重构这种方式,渲染过程采用切片的方式,每执行一会儿,就歇一会儿。如果有优先级更高的任务到来以后呢,就会先去执行,降低页面发生卡顿的可能性,使得React对动画等实时性要求较高的场景体验更好。

       二:什么是Fiber?

         当js在处理大型计算的时候会导致页面出现卡帧的现象,更严重的会出现页面“假死”。所以在这些情况下,必然会导致动画丢帧、不连贯,用户体验就特别差。为了解决这个问题,我们可以将大型的计算拆分成一个个小型计算,然后按照执行顺序异步调用,这样就不会长时间霸占线程,UI也能在俩次小型计算的执行间隙进行更新,从而给与用户及时的反馈,Fiber就是这样做的,并且以一种更高逼格的方式实现了。

       Driving Idea

         如果说v.0之前的React解决了HOW(如何用最少的DOM操作成本来update视图)的问题,那么这一次Fiber的出现,在这个基础上还解决了WHEN(何时update视图的哪一部分)的问题。

          分片优先级!!!

         基于上述这些原因,Fiber实现了一个虚拟调用栈,并给所有的update进行优先级排序,如下:

       'use strict';

       export type PriorityLevel = 0 | 1 | 2 | 3 | 4 | 5;

       module.exports = {

       NoWork: 0, // No work is pending.

       SynchronousPriority: 1, // 用于控制文本输入。同步的副作用.

       AnimationPriority: 2, //需要在下一帧之前完成.

       HighPriority: 3, // 需要很快完成的互动才能产生反应.

       LowPriority: 4, // 数据获取,或更新存储的结果.

       OffscreenPriority: 5, // 将不可见,但做的工作,以防它成为可见.

       };

         然后根据这些update的优先级,来决定执行的顺序。

         我们可以看到动画和页面交互都是优先级比较高的,这也是Fiber能够使得动画、布局和页面交互变得更加的流畅的原因之一。

         可以把Priority分为同步和异步两个类别,同步优先级的任务会在当前帧完成,包括SynchronousPriority和TaskPriority。异步优先级的任务则可能在接下来的几个帧中被完成,包括HighPriority、LowPriority以及OffscreenPriority。

         React v.3.2的优先级,不再这么划分,分为三类:NoWork、sync、async,前两类可以认为是同步任务,需要在当前tick完成,过期时间为null,最后一类异步任务会计算一个。

         expirationTime,在workLoop中,根据过期时间来判断是否进行下一个分片任务,scheduleWork中更新任务优先级,也就是更新这个expirationTime。至于这个时间怎么计算,可以查看源码。

       三:Fiber的基本原则:

         更新任务分成俩个阶段,Reconcilition Phase(调和阶段)和Commit Phase(交付阶段)。Reconciliation Phase的任务干的事情是,找出要做的更新工作(Diff Fiber Tree),就是一个计算阶段,计算结果可以被缓存,也就可以被打断;Commit Phase需要提交所有更新并渲染,为了防止页面抖动,被设置为不能打断。

         PS:componentWillMount

         omponentWillReceiveProps componentWillUpdate 几个生命周期方法,在Reconciliation Phase被调用,有被打断的可能(时间用尽等情况),所以可能被多次调用。其实shouldComponentUpdate 也可能被多次调用,只是它只返回true或者false,没有副作用,可以暂时忽略。

       四:Fiber的数据结构

         fiber是个链表,有child和sibing属性,指向第一个子节点和相邻的兄弟节点,从而构成fiber tree。return 属性指向其父节点。

         更新队列,updateQueue,是一个链表,有first和last俩个属性,指向第一个和最后一个update对象。

         每个fiber有一个属性updateQueue指向其对应的更新队列。

         每个fiber(当前fiber可以称为current)有一个属性alternate,开始时指向一个自己的clone体,update的变化会先更新到alternate上,当更新完毕,alternate替换current。

       五:Fiber的执行流程

       用户操作引起setState被调用以后,先调用enqueueSetState方法,该方法可以划分成俩个阶段(个人理解),第一阶段Data Preparation,是初始化一些数据结构,比如fiber,updateQueue,update。

       新的update会通过insertUpdateIntoQueue方法,根据优先级插入到队列的对应位置,ensureUpdateQueues方法初始化俩个更新队列,queue1和current.updateQueue对应,queue2和current.alternate.updateQueue对应。

       第二阶段,Fiber Reconciler,就开始进行任务分片调度,scheduleWork首先更新每个fiber的优先级,这里并没有updatePriority这个方法,但是干了这件事。当fiber.return === null,找到父节点,把所有diff出的变化(side effect)归结到root上。

       requestWork,首先把当前的更新添加到schedule list中(addRootToSchedule),然后根据当前是否为异步渲染(isAsync参数),异步渲染调用。scheduleCallbackWithExpriation方法,下一步高能!!

       scheduleCallbackWithExpriation这个方法在不同环境,实现不一样,chrome等浏览器中使用requestIdleCallback API,没有这个API的浏览器中,通过requestAnimationFrame模拟一个requestIdCallback,来在浏览器空闲时,完成下一个分片的工作,注意,这个函数会传入一个expirationTime,超过这个时间活没干完,就放弃了。

       执行到performWorkOnRoot,就是fiber文档中提到的Commit Phase和Reconciliation Phase俩阶段。

       第一阶段Reconciliation Phase,在workLoop中,通过一个while循环,完成每个分片任务。

       performUnitOfWork也可以分成俩阶段,蓝色框表示。beginWork是一个入口函数,根据workInProgress的类型去实例化不同的react element class。workInProgress是通过alternate挂载一些新属性获得的。

       实例化不同的react element class时候会调用和will有关的生命周期方法。

       completeUnitOfWork是进行一些收尾工作,diff完一个节点以后,更新props和调用生命周期方法等。

       然后进入Commit Phase阶段,这个阶段不能被打断。

       六:Fiber对开发者有什么影响?

       componentWillMount,componentWillReceiveProps,componentWillUpdate几个生命周期方法不再安全,由于任务执行过程可以被打断,这几个生命周期可能会执行多次,如果它们包含副作用(比如Ajax),会有意想不到的bug。React团队提供了替换的生命周期方法。建议如果使用以上方法,尽量使用纯函数,避免以后踩坑。

       需要关注react为任务片设置的优先级,特别是页面用动画的情况。

       如果一直有更高的级别任务,那么fiber算法会先执行级别更高的任务,执行完毕后再通过callback回到之前渲染到一半的组件,从头开始渲染。(看起来放弃已经渲染完的生命周期,会有点不合理,反而会增加渲染时长,但是react确实是这么干的)

copyright © 2016 powered by 皮皮网   sitemap