当前位置:首页 » 网页前端 » 前端节点树
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

前端节点树

发布时间: 2022-12-20 09:29:54

Ⅰ 家谱树前端特效怎么实现

首先确定点到点的向量范围

然后做枝叶的随机,将最终节点设置为LEAF
我只给出结构,剩下的LZ自己来吧
function Node(){
this.nodeCount=0;子节点数量
this.isLeaf=false;
this.LChild=[];左枝叶
this.RChild=[];右枝叶
}
结构请按照二叉树的生成来

Ⅱ 自学web前端开发,请问从何入手呢

学习前端,要从学习HTML和CSS开始着手。关于这部分的学习,网上可选择的资料就太多了,这里不一一列举,题主网络搜索栏搜索HTML 教程,或者css 教程,就可找到相关资料。

接着是学习前端的一个难点、也是重点,就是JavaScript。

首先,初学一门语言,要秉承一个原则:“能动手的,尽量别吵吵”

另外,你需要一个能够从简到难的知识体系,一步一步跟下来。

下面是干货。

体系:上图。

(四)、工作流(跟JS原生关系不大,不详细展开了)

  1. webpack

  2. gulp

上面的内容结束后,就可以进入前端框架的海洋中畅游了。

Ⅲ antv G6 分层树怎么将图片插入作为树节点

  • 你看下这个代码能不能套用 不是完全复制哈

  • usingSystem;

  • usingSystem.Collections.Generic;

  • usingSystem.Linq;

  • usingSystem.Text;

  • usingSystem.ComponentModel;

  • usingKingdee.BOS;

  • usingKingdee.BOS.Util;

  • usingKingdee.BOS.Core;

  • usingKingdee.BOS.Core.DynamicForm;

  • usingKingdee.BOS.Core.DynamicForm.PlugIn;

  • usingKingdee.BOS.Core.DynamicForm.PlugIn.Args;

  • usingKingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;

  • usingKingdee.BOS.Core.Metadata;

  • namespaceJDSample.FormPlugIn.DynamicForm

  • {

  • ///<summary>

  • ///分批分层加载树节点

  • ///</summary>

  • ///<remarks>

  • ///案例背景:

  • ///界面上使用树控件,需显示大量的节点;

  • ///如果一次性加载到客户端,显示渲染会非常慢;

  • ///因此,需要分层、分批下载

  • ///

  • ///案例说明:

  • ///新增一个动态表单,挂上本插件,并在界面有一个树控件F_JD_TreeView;

  • ///界面初始化时,仅加载第一层节点;

  • ///用户点击节点时,才加载其包含的子节点,而且每次最多加载10个;

  • ///单层超过10个节点,通过"点击加载更多..."节点,分批下载

  • ///</remarks>

  • [Description("分批分层加载树节点")]

  • publicclassS160107TreeEdit:AbstractDynamicFormPlugIn

  • {

  • ///<summary>

  • ///本地变量,存储需加载到前端的所有节点信息,以及其是否已经加载标志

  • ///</summary>

  • privateDictionary<string,NodeInfo>_dctNodes=newDictionary<string,NodeInfo>();

  • ///<summary>

  • ///本地变量,存储已经被加载过的父节点Id,避免重复搜索其子节点,浪费时间

  • ///</summary>

  • privateHashSet<string>_loadedNodeIds=newHashSet<string>();

  • ///<summary>

  • ///界面初始化结束,触发此事件,通知插件开始加载树节点:在此事件,加载第一层节点

  • ///</summary>

  • ///<paramname="e"></param>

  • publicoverrideList<TreeNode>GetTreeViewData(TreeNodeArgse)

  • {

  • if(e.Key.EqualsIgnoreCase("F_JD_TreeView")==false)

  • {

  • //需加载是其他树控件的节点,略过

  • returnnewList<TreeNode>();

  • }

  • //加载全部节点信息到内存

  • this.LoadNodes();

  • //记录已经加载过根节点

  • this._loadedNodeIds.Add("0");

  • //展开树控件节点

  • TreeViewtv=this.View.GetControl<TreeView>("F_JD_TreeView");

  • tv.SetExpanded(true);

  • //构造根目录下的第一层节点并返回

  • List<TreeNode>nodes=this.BuildTreeNodes("0");

  • returnnodes;

  • }

  • ///<summary>

  • ///用户点击节点时触发此事件:加载更多子节点

  • ///</summary>

  • ///<paramname="e"></param>

  • (TreeNodeArgse)

  • {

  • if(e.Key.EqualsIgnoreCase("F_JD_TreeView")==false)

  • {

  • //点击的是其他树控件,略过

  • return;

  • }

  • //判断是否已经加载过此节点的子节点,如果加载过,则不再加载

  • if(this._loadedNodeIds.Contains(e.NodeId))

  • {

  • return;

  • }

  • this._loadedNodeIds.Add(e.NodeId);

  • TreeViewtv=this.View.GetControl<TreeView>("F_JD_TreeView");

  • stringparentId=e.NodeId;

  • if(parentId.StartsWith("more"))

  • {//当前点击的节点,是"点击加载更多..."

  • string[]keys=parentId.Split('|');

  • parentId=keys[1];//第2部分为父节点部分

  • //"点击加载更多..."节点已经被点击过,不再需要了,移除之

  • tv.RemoveNode(e.NodeId);

  • }

  • //开始加载更多的子节点

  • List<TreeNode>childNodes=this.BuildTreeNodes(parentId);

  • if(childNodes.Count>0)

  • {

  • tv.AddNodes(parentId,childNodes);

  • }

  • }

  • ///<summary>

  • ///构建树控件所需要的节点对象

  • ///</summary>

  • ///<paramname="parentId">父节点Id,为0表示第一层节点</param>

  • ///<returns></returns>

  • privateList<TreeNode>BuildTreeNodes(stringparentId)

  • {

  • List<TreeNode>nodes=newList<TreeNode>();

  • //遍历全部节点,找指定节点中,未加载的子节点的子节点

  • intcount=0;

  • intindex=0;

  • foreach(varitemin_dctNodes)

  • {

  • NodeInfonodeInfo=item.Value;

  • if(nodeInfo.Loaded==false

  • &&nodeInfo.ParentId==parentId)

  • {

  • nodeInfo.Loaded=true;

  • count++;

  • TreeNodenode=newTreeNode()

  • {

  • id=nodeInfo.Id,

  • text=nodeInfo.Caption,

  • parentid=nodeInfo.ParentId,

  • };

  • nodes.Add(node);

  • }

  • if(count>=10)

  • {//本次加载超过了10个

  • //生成一个特殊的节点(加载更多...),并停止本批加载更多子节点

  • TreeNodenode=newTreeNode()

  • {

  • //需要基于如下需求,生成一个特殊的节点Id

  • //1.需要与其他普通节点进行区分:以more为前缀

  • //2.需要能够提取出父节点Id:包含父节点Id

  • //3.每次产生的特殊节点Id不能重复:需包含当前节点索引

  • id=string.Format("more|{0}|{1}",parentId,index),

  • text="点击加载更多...",

  • parentid=parentId,

  • };

  • nodes.Add(node);

  • break;

  • }

  • index++;

  • }

  • returnnodes;

  • }

  • ///<summary>

  • ///到数据库加载全部节点信息:本示例直接手工构建一批有层次的节点信息

  • ///</summary>

  • privatevoidLoadNodes()

  • {

  • //节点名称,包含其子节点的数量,以提示用户,可以展开查看子节点

  • //第一层节点

  • _dctNodes.Add("1",newNodeInfo(){Id="1",ParentId="0",Caption="江西(100)"});

  • _dctNodes.Add("2",newNodeInfo(){Id="2",ParentId="0",Caption="广东(3)"});

  • //循环添加100个第一层节点

  • for(inti=3;i<=100;i++)

  • {

  • _dctNodes.Add(i.ToString(),newNodeInfo()

  • {Id=i.ToString(),ParentId="0",Caption=string.Format("省份{0}(0)",i)});

  • }

  • //第二层节点:

  • _dctNodes.Add("1.1",newNodeInfo(){Id="1.1",ParentId="1",Caption="南昌(0)"});

  • _dctNodes.Add("1.2",newNodeInfo(){Id="1.2",ParentId="1",Caption="九江(0)"});

  • _dctNodes.Add("1.3",newNodeInfo(){Id="1.3",ParentId="1",Caption="赣州(0)"});

  • //循环添加100个第二层节点

  • for(inti=4;i<=100;i++)

  • {

  • _dctNodes.Add(string.Format("1.{0}",i),

  • newNodeInfo()

  • {

  • Id=string.Format("1.{0}",i),

  • ParentId="1",

  • Caption=string.Format("城市{0}(0)",i)

  • });

  • }

  • _dctNodes.Add("0201",newNodeInfo(){Id="0201",ParentId="02",Caption="广州(0)"});

  • _dctNodes.Add("0202",newNodeInfo(){Id="0202",ParentId="02",Caption="深圳(2)"});

  • _dctNodes.Add("0203",newNodeInfo(){Id="0203",ParentId="02",Caption="惠州(0)"});

  • //第三层节点:

  • _dctNodes.Add("020201",newNodeInfo(){Id="020201",ParentId="0202",Caption="南山区"});

  • _dctNodes.Add("020202",newNodeInfo(){Id="020202",ParentId="0202",Caption="宝安区"});

  • }

  • }

  • ///<summary>

  • ///节点信息对象

  • ///</summary>

  • classNodeInfo

  • {

  • ///<summary>

  • ///本节点Id

  • ///</summary>

  • publicstringId{get;set;}

  • ///<summary>

  • ///父节点Id

  • ///</summary>

  • publicstringParentId{get;set;}

  • ///<summary>

  • ///本节点标题

  • ///</summary>

  • publicstringCaption{get;set;}

  • ///<summary>

  • ///是否已经加载标志:默认为false,未加载到前端

  • ///</summary>

  • publicboolLoaded{get;set;}

  • }

  • }

Ⅳ 组件分享之前端组件——bootstrap-treeview 简单的tree树组件

近期正在探索前端、后端、系统端各类常用组件与工具,对其一些常见的组件进行再次整理一下,形成标准化组件专题,后续该专题将包含各类语言中的一些常用组件。欢迎大家进行持续关注。

本次分享的组件是用于前端开发使用的tree树组件。
下面是其开源库中的描述内容:

需要的支持文件:

使用说明:
1、在页面中引用对应css和js文件

2、创建一个容器,作为生成的树存储位置

3、进行启动加载,具体data格式可以参考上面的开源库地址中的README。

虽然前端现在已经被vue、react等占据,但仍然有一些小伙伴们仍在使用一体化开发,jsp开发等,这类前端组件文章主要就用于这类场景下的快速使用,有需要的可以持续关注。

Ⅳ 整理涵盖很全很广的前端知识点

HTML、CSS相关

html5新特性、语义化

浏览器渲染机制、重绘、重排

网页生成过程:

重排(也称回流): 当 DOM 的变化影响了元素的几何信息( DOM 对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。 触发:

重绘: 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。 触发:

重排优化建议:

transform 不重绘,不回流 是因为 transform 属于合成属性,对合成属性进行 transition/animate 动画时,将会创建一个合成层。这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘。浏览器会通过重新复合来创建动画帧。

css盒子模型

所有 HTML 元素可以看作盒子,在CSS中, "box model" 这一术语是用来设计和布局时使用。 CSS 盒模型本质上是一个盒子,封装周围的 HTML 元素,它包括:边距,边框,填充,和实际内容。 盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。

css样式优先级

!important>style>id>class

什么是BFC?BFC的布局规则是什么?如何创建BFC?BFC应用?

BFC 是 Block Formatting Context 的缩写,即块格式化上下文。 BFC 是CSS布局的一个概念,是一个环境,里面的元素不会影响外面的元素。 布局规则:Box是CSS布局的对象和基本单位,页面是由若干个Box组成的。元素的类型和display属性,决定了这个Box的类型。不同类型的Box会参与不同的 Formatting Context 。 创建:浮动元素 display:inline-block position:absolute 应用: 1.分属于不同的 BFC 时,可以防止 margin 重叠 2.清除内部浮动 3.自适应多栏布局

DOM、BOM对象

BOM(Browser Object Model) 是指浏览器对象模型,可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作。 使 JavaScript 有能力与浏览器"对话"。 DOM (Document Object Model) 是指文档对象模型,通过它,可以访问 HTML 文档的所有元素。 DOM 是 W3C (万维网联盟)的标准。 DOM 定义了访问 HTML 和 XML 文档的标准: "W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。" W3C DOM 标准被分为 3 个不同的部分:

什么是 XML DOM ? XML DOM 定义了所有 XML 元素的对象和属性,以及访问它们的方法。 什么是 HTML DOM? HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。

JS相关

js数据类型、typeof、instanceof、类型转换

闭包(高频)

闭包是指有权访问另一个函数作用域中的变量的函数 ——《JavaScript高级程序设计》

当函数可以记住并访问所在的词法作用域时,就产生了闭包,

即使函数是在当前词法作用域之外执行 ——《你不知道的JavaScript》

原型、原型链(高频)

原型: 对象中固有的 __proto__ 属性,该属性指向对象的 prototype 原型属性。

原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype 所以这就是我们新建的对象为什么能够使用 toString() 等方法的原因。

特点: JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。

this指向、new关键字

this 对象是是执行上下文中的一个属性,它指向最后一次调用这个方法的对象,在全局函数中, this 等于 window ,而当函数被作为某个对象调用时,this等于那个对象。 在实际开发中, this 的指向可以通过四种调用模式来判断。

new

作用域、作用域链、变量提升

继承(含es6)、多种继承方式

(1)第一种是以 原型链的方式来实现继承 ,但是这种实现方式存在的缺点是,在包含有引用类型的数据时,会被所有的实例对象所共享,容易造成修改的混乱。还有就是在创建子类型的时候不能向超类型传递参数。

(2)第二种方式是使用 借用构造函数 的方式,这种方式是通过在子类型的函数中调用超类型的构造函数来实现的,这一种方法解决了不能向超类型传递参数的缺点,但是它存在的一个问题就是无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到。

(3)第三种方式是 组合继承 ,组合继承是将原型链和借用构造函数组合起来使用的一种方式。通过借用构造函数的方式来实现类型的属性的继承,通过将子类型的原型设置为超类型的实例来实现方法的继承。这种方式解决了上面的两种模式单独使用时的问题,但是由于我们是以超类型的实例来作为子类型的原型,所以调用了两次超类的构造函数,造成了子类型的原型中多了很多不必要的属性。

(4)第四种方式是 原型式继承 ,原型式继承的主要思路就是基于已有的对象来创建新的对象,实现的原理是,向函数中传入一个对象,然后返回一个以这个对象为原型的对象。这种继承的思路主要不是为了实现创造一种新的类型,只是对某个对象实现一种简单继承,ES5 中定义的 Object.create() 方法就是原型式继承的实现。缺点与原型链方式相同。

(5)第五种方式是 寄生式继承 ,寄生式继承的思路是创建一个用于封装继承过程的函数,通过传入一个对象,然后复制一个对象的副本,然后对象进行扩展,最后返回这个对象。这个扩展的过程就可以理解是一种继承。这种继承的优点就是对一个简单对象实现继承,如果这个对象不是我们的自定义类型时。缺点是没有办法实现函数的复用。

(6)第六种方式是 寄生式组合继承 ,组合继承的缺点就是使用超类型的实例做为子类型的原型,导致添加了不必要的原型属性。寄生式组合继承的方式是使用超类型的原型的副本来作为子类型的原型,这样就避免了创建不必要的属性。

EventLoop

JS 是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。微任务队列的代表就是, Promise.then , MutationObserver ,宏任务的话就是 setImmediate setTimeout setInterval

原生ajax

ajax 是一种异步通信的方法,从服务端获取数据,达到局部刷新页面的效果。 过程:

事件冒泡、捕获(委托)

event.stopPropagation() 或者 ie下的方法 event.cancelBubble = true; //阻止事件冒泡

ES6

Vue

简述MVVM

MVVM 是 Model-View-ViewModel 缩写,也就是把 MVC 中的 Controller 演变成 ViewModel。Model 层代表数据模型, View 代表UI组件, ViewModel 是 View 和 Model 层的桥梁,数据会绑定到 viewModel 层并自动将数据渲染到页面中,视图变化的时候会通知 viewModel 层更新数据。

谈谈对vue生命周期的理解?

每个 Vue 实例在创建时都会经过一系列的初始化过程, vue 的生命周期钩子,就是说在达到某一阶段或条件时去触发的函数,目的就是为了完成一些动作或者事件

computed与watch

watch 属性监听 是一个对象,键是需要观察的属性,值是对应回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,监听属性的变化,需要在数据变化时执行异步或开销较大的操作时使用

computed 计算属性 属性的结果会被缓存,当 computed 中的函数所依赖的属性没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取。除非依赖的响应式属性变化时才会重新计算,主要当做属性来使用 computed 中的函数必须用 return 返回最终的结果 computed 更高效,优先使用

使用场景 computed :当一个属性受多个属性影响的时候使用,例:购物车商品结算功能 watch :当一条数据影响多条数据的时候使用,例:搜索数据

v-for中key的作用

vue组件的通信方式

父子组件通信

父->子 props ,子->父 $on、$emit` 获取父子组件实例 parent、 parent 、children Ref 获取实例的方式调用组件的属性或者方法 Provide、inject` 官方不推荐使用,但是写组件库时很常用

兄弟组件通信

Event Bus 实现跨组件通信 Vue.prototype.$bus = new Vue() Vuex

跨级组件通信

$attrs、$listeners Provide、inject

常用指令

双向绑定实现原理

当一个 Vue 实例创建时,Vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新。

v-model的实现以及它的实现原理吗?

nextTick的实现

vnode的理解,compiler和patch的过程

new Vue后整个的流程

思考:为什么先注入再提供呢??

答:1、首先来自祖辈的数据要和当前实例的data,等判重,相结合,所以注入数据的initInjections一定要在 InitState 的上面。2. 从上面注入进来的东西在当前组件中转了一下又提供给后代了,所以注入数据也一定要在上面。

vm.[Math Processing Error]mount(vm.mount(vm.options.el) :挂载实例。

keep-alive的实现

作用:实现组件缓存

钩子函数:

原理: Vue.js 内部将 DOM 节点抽象成了一个个的 VNode 节点, keep-alive 组件的缓存也是基于 VNode 节点的而不是直接存储 DOM 结构。它将满足条件 (pruneCache与pruneCache) 的组件在 cache 对象中缓存起来,在需要重新渲染的时候再将 vnode 节点从 cache 对象中取出并渲染。

配置属性:

include 字符串或正则表达式。只有名称匹配的组件会被缓存

exclude 字符串或正则表达式。任何名称匹配的组件都不会被缓存

max 数字、最多可以缓存多少组件实例

vuex、vue-router实现原理

vuex 是一个专门为vue.js应用程序开发的状态管理库。 核心概念:

你怎么理解Vue中的diff算法?

在js中,渲染真实 DOM 的开销是非常大的, 比如我们修改了某个数据,如果直接渲染到真实 DOM , 会引起整个 dom 树的重绘和重排。那么有没有可能实现只更新我们修改的那一小块dom而不要更新整个 dom 呢?此时我们就需要先根据真实 dom 生成虚拟 dom , 当虚拟 dom 某个节点的数据改变后会生成有一个新的 Vnode , 然后新的 Vnode 和旧的 Vnode 作比较,发现有不一样的地方就直接修改在真实DOM上,然后使旧的 Vnode 的值为新的 Vnode 。

diff 的过程就是调用 patch 函数,比较新旧节点,一边比较一边给真实的 DOM 打补丁。在采取 diff 算法比较新旧节点的时候,比较只会在同层级进行。 在 patch 方法中,首先进行树级别的比较 new Vnode 不存在就删除 old Vnode old Vnode 不存在就增加新的 Vnode 都存在就执行diff更新 当确定需要执行diff算法时,比较两个 Vnode ,包括三种类型操作:属性更新,文本更新,子节点更新 新老节点均有子节点,则对子节点进行 diff 操作,调用 updatechidren 如果老节点没有子节点而新节点有子节点,先清空老节点的文本内容,然后为其新增子节点 如果新节点没有子节点,而老节点有子节点的时候,则移除该节点的所有子节点 老新老节点都没有子节点的时候,进行文本的替换

updateChildren 将 Vnode 的子节点Vch和oldVnode的子节点oldCh提取出来。 oldCh和vCh 各有两个头尾的变量 StartIdx和EndIdx ,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了 key ,就会用 key 进行比较,在比较的过程中,变量会往中间靠,一旦 StartIdx>EndIdx 表明 oldCh和vCh 至少有一个已经遍历完了,就会结束比较。

你都做过哪些Vue的性能优化?

你知道Vue3有哪些新特性吗?它们会带来什么影响?

更小巧、更快速 支持自定义渲染器 支持摇树优化:一种在打包时去除无用代码的优化手段 支持Fragments和跨组件渲染

模板语法99%保持不变 原生支持基于class的组件,并且无需借助任何编译及各种stage阶段的特性 在设计时也考虑TypeScript的类型推断特性 重写虚拟DOM 可以期待更多的编译时提示来减少运行时的开销 优化插槽生成 可以单独渲染父组件和子组件 静态树提升 降低渲染成本 基于Proxy的观察者机制 节省内存开销

检测机制 更加全面、精准、高效,更具可调试式的响应跟踪

实现双向绑定 Proxy 与 Object.defineProperty 相比优劣如何?

React

1、react中key的作用,有key没key有什么区别,比较同一层级节点什么意思?

2、你对虚拟dom和diff算法的理解,实现render函数

虚拟DOM 本质上是 JavaScript 对象,是对 真实DOM 的抽象表现。 状态变更时,记录新树和旧树的差异 最后把差异更新到真正的 dom 中 render函数:

3、React组件之间通信方式?

Context 提供了一个无需为每层组件手动添加 props ,就能在组件树间进行数据传递的方法.如果你只是想避免层层传递一些属性,组件组合( component composition )有时候是一个比 context 更好的解决方案。 5. 组件组合缺点:会使高层组件变得复杂

4、如何解析jsx

5、生命周期都有哪几种,分别是在什么阶段做哪些事情?为什么要废弃一些生命周期?

componentWillMount、componentWillReceiveProps、componentWillUpdate在16版本被废弃,在17版本将被删除,需要使用UNSAVE_前缀使用,目的是向下兼容。

6、关于react的优化方法

使用return null而不是CSS的display:none来控制节点的显示隐藏。保证同一时间页面的DOM节点尽可能的少。

不要使用数组下标作为key 利用 shouldComponentUpdate 和 PureComponent 避免过多 render function ; render 里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。 尽量将 props 和 state 扁平化,只传递 component 需要的 props (传得太多,或者层次传得太深,都会加重 shouldComponentUpdate 里面的数据比较负担),慎将 component 当作 props 传入

使用 babel-plugin-import 优化业务组件的引入,实现按需加载 使用 SplitChunksPlugin 拆分公共代码 使用动态 import ,懒加载 React 组件

7、绑定this的几种方式

8、对fiber的理解

9、setState是同步还是异步的

10、Rex、React-Rex

Rex的实现流程

用户页面行为触发一个 Action ,然后 Store 调用 Recer ,并且传入两个参数:当前 State 和收到的 Action 。 Recer 会返回新的 State 。每当 state 更新之后, view 会根据 state 触发重新渲染。

React-Rex:

Provider :从最外部封装了整个应用,并向 connect 模块传递 store 。 Connect :

11、对高阶组件的理解

高阶组件是参数为组件,返回值为新组件的函数。 HOC 是纯函数,没有副作用。 HOC 在 React 的第三方库中很常见,例如 Rex 的 connect 组件。

高阶组件的作用:

12、可以用哪些方式创建 React 组件?

React.createClass()、ES6 class 和无状态函数

13、 React 元素与组件的区别?

组件是由元素构成的。元素数据结构是普通对象,而组件数据结构是类或纯函数。

Vue与React对比?

数据流:

react 主张函数式编程,所以推崇纯组件,数据不可变,单向数据流,

vue 的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。

监听数据变化实现原理

组件通信的区别:jsx和.vue模板。

性能优化

vuex 和 rex 之间的区别?

从实现原理上来说,最大的区别是两点:

Rex 使用的是不可变数据,而 Vuex 的数据是可变的。 Rex 每次都是用新的 state 替换旧的 state ,而 Vuex 是直接修改

Rex 在检测数据变化的时候,是通过 diff 的方式比较差异的,而 Vuex 其实和Vue的原理一样,是通过 getter/setter 来比较的(如果看 Vuex 源码会知道,其实他内部直接创建一个 Vue 实例用来跟踪数据变化)

浏览器从输入url到渲染页面,发生了什么?

网络安全、HTTP协议

TCP UDP 区别

Http和Https区别(高频)

GET和POST区别(高频)

理解xss,csrf,ddos攻击原理以及避免方式

XSS ( Cross-Site Scripting , 跨站脚本攻击 )是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当被攻击者登陆网站时就会执行这些恶意代码,这些脚本可以读取 cookie,session tokens ,或者其它敏感的网站信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等。

CSRF ( Cross-site request forgery ) 跨站请求伪造 :攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

XSS避免方式:

CSRF 避免方式:

DDoS 又叫分布式拒绝服务,全称 Distributed Denial of Service ,其原理就是利用大量的请求造成资源过载,导致服务不可用。

Ⅵ Web前端面试题第六道—链接标记target与Dom,Bom

(1)链接标记target属性的_self、_top、_parent、_blank、main、left、top各有何用处?

target属性的_self、_top、_parent都是针对框架的。比如你写了这样一个网页page,网页page分成frame1、frame2,frame1又分成frame1-1、frame1-2,frame1-1又分成frame1-1-1,frame1-1-2。

假如你在frame1-1-1中放了一个链接。

如果这个链接的target="_self",那么链接会在frame1-1-1中打开。

如果target="_parent",那么链接会在frame1-1中打开。

如果target="_top",那么链接会在page中打开。

如果target="_blank",浏览器会另开一个新窗口显示page文档。

未经验证,根据说法应该是这个意思。

(2)链接标记target属性的main、left、top各有何用处?

main、left、top是由Adobe Dreamweaver生成的主、左、上框架集的框架默认名。

(3)什么是Bom什么是Dom?你如何理解Dom?

DOM和BOM是JS的三大组成部分之一,下面讲解BOM与DOM以及两者的关系

DOM讲解

DOM即文档对象模型,通过创建节点树来表示文档,是HTML和XML的应用程序接口(API),描述了处理网页内容的方法和接口,从而使开发者对文档的内容和结构具有空前的控制力,用DOM API可以轻松地删除、添加和替换节点以及设置文档中标签的属性。将一个html文档用DOM树表示如下图所示 。

HTML的DOM树节点包括:

1. 元素节点:上图中<html>、<body>、<p>都是元素节点即标签

2. 文本节点:向用户展示的内容,如<li>...</li>中的javascript、Dom、CSS等文本。

3. 属性节点:元素属性,如<a>标签的链接属性

BOM讲解

BOM是browser object model的缩写,简称浏览器对象模型。简单说即是javascript访问,操作浏览器的一个中介。

BOM主要用于管理浏览器窗口之间的通讯,由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。通过BOM我们可以学到与浏览器窗口交互的一些对象,可以移动,调整浏览器大小的window对象,可以用于导航的location对象与history对象,可以获取浏览器,操作系统与用户屏幕信息的navigator与screen对象,可以使用document作为访问HTML文档的入口,管理框架的frames对象等。因此它的核心对象是window。

Window对象是BOM中所有对象的核心,是BOM中所有对象的父对象。所以,尽管frame ,history……都是window的子对象,我们只要知道BOM操作的是对象是浏览器窗口(window),那么这些对象就可以直接使用,无需通过“window.”来访问

BOM和DOM的关系

要想操作网页,需要DOM来进行访问,但是仅仅只是网页内容。浏览器除了有显示的内容,还有一个重要的部分就是一个载体,它承载我们看到的内容。好比是一个框架,而操作这个载体的对象我们把它叫做BOM。所以这样的结构,使得BOM,DOM各司其职,BOM负责跟浏览器框架打交道,DOM负责浏览器内容Document打交道。从上图中能更好的理解两者的关系。