2022/3/31

关于虚拟dom,其实就是为了减少对真实dom的存在而产生的,但是虚拟dom最后还是要变成真正的dom。
至于为什么要用虚拟dom,看这两段代码对比就知道了。
// 方式一:平均 60ms 80ms

 for (var i = 0; i < 10000; i++) {
let tmp=Number(document.getElementById('test').innerHTML)
document.getElementById('test').innerHTML=tmp+1
 }
 console.timeEnd('test');

//方式二: 平均 1ms 0.6ms

let num=0
console.time('test')
 for (var i = 0; i < 10000; i++) {
   num++
 }
document.getElementById('test').innerHTML=num
console.timeEnd('test');

出处:https://www.cnblogs.com/1549983239yifeng/p/13786866.html

VUE中有个虚拟dom,长这样:

(function anonymous(
) {
	with(this){return _c('div',{attrs:{"id":"app"}},[_c('p',{staticClass:"p"},
					  [_v("节点内容")]),_v(" "),_c('h3',[_v(_s(foo))])])}})

通过VNode,vue可以对这颗抽象树(上面这个虚拟dom函数)进行创建节点,删除节点以及修改节点的操作, 经过diff算法得出一些需要修改的最小单位,再更新视图,减少了dom操作,提高了性能

createElement 创建 VNode 的过程,每个 VNode 有 children,children 每个元素也是一个VNode,这样就形成了一个虚拟树结构,用于描述真实的DOM树结构

#参考文献:https://vue3js.cn/interview/vue/vnode.html#%E4%B8%89%E3%80%81%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E8%99%9A%E6%8B%9Fdom

数据请求在created和mouted的区别
created是在组件实例一旦创建完成的时候立刻调用,这时候页面dom节点并未生成mounted是在页面dom节点渲染完毕之后就立刻执行的触发时机上created是比mounted要更早的两者相同点:都能拿到实例对象的属性和方法讨论这个问题本质就是触发的时机,放在mounted请求有可能导致页面闪动(页面dom结构已经生成),但如果在页面加载前完成则不会出现此情况建议:放在create生命周期当中

vue项目部署后刷新报404 :这是因为用的是history模式,而history模式需要服务端支持,否则就会
404报错。

hash路由和history路由的区别:https://zhuanlan.zhihu.com/p/130995492

mixin是vue2中的compositionapi,但是它可能会导致取名重复问题,具体链接:https://v3.cn.vuejs.org/guide/mixins.html#%E9%80%89%E9%A1%B9%E5%90%88%E5%B9%B6

css盒子垂直居中:https://www.cnblogs.com/plsmile/p/11119728.html

面试了。

唉,今天面试的时候面试官问了我一下vue-router的两种方式,突然没想起来,经过提示以后才知道原来是hash和history…
hash路由和history路由,没说好。。就说了#区别,以及history刷新可能会出现404错误。
但是忘记为什么会出现404了,出现404以后的解决方案是什么。。。
首先,为什么history路由刷新会出现错误呢,因为它不像hash,它会包括在http请求中,对服务端有影响,所以需要配置location。
其次,出现404以后,需要后端人员配置一下nginx的url重定向。重定向到首页路由。

还有就是还问了一个websocket和http,其实知道websocket是全双工通信,http是单向协议,虽然说websocket是tcp协议,
但是它跟http还是有联系的。websocket为了兼容互联网现状采用了相同的端口,并利用HTTP消息切入Websocket协议。
http是单向的,无状态协议,而此时服务端便是被动的,健忘的,有了websocket,就能解决这个问题。只要建立一次http握手,
websocket就能建立起持久连接了。

websocket和nginx…nginx就相当于它的接线员。

今天发现面试有些东西跟nginx这个反向代理服务器有很大关系,可惜nginx我是刚学不久的,如果知道它history路由和跟webscoket
的关系就好多了。。

就当一次教训吧。。= =

继续学react了.

关于父子组件,今天在看效果的时候好像突然明白了一些东西,就是组件的数据显示。如果组件的数据显示是依赖于父组件的话,
那么这些数据的删除,修改,都要跟父组件建议联系了。这也就是为什么组件需要props和触发函数。

简单来讲父子组件数据联系的结果无非还是这几样:获取,删除,修改。!!从子组件决定从父组件上获取数据开始,数据产生联系,子组件关于这些数据的删除,修改,添加等操作,都是一次触发函数,触发函数后交给父组件去操作。

也就是说,父组件负责对需要显示它的数据的子组件进行真正的增删改操作,这些逻辑的数据操作都是交给父组件去处理,只是交互交给子组件处理了。

react的父子组件和vue的父子组件区别在于,react中子组件通过this.props就可以直接拿到父组件的属性和方法,某种程度上来说
叫做直接用,无需触发,比如this.props.delete(this.props.index),而在vue中需要通过emit去触发函数调用,这就不同了。

发现react父子组件传值比vue容易多了,,又或者是因为我看了react好像明白vue了。。
上代码:
父组件 TodoList:

import React from 'react';
import TodoItem from './TodoItem';
class TodoList extends React.Component{
    constructor(props){
        super(props)
        this.state={
            list:[],
            input:''
        }
    }
    handleInputChange(e){
        this.setState({
            input:e.target.value
        })
    }
    handleAdd(){
        this.setState({
            list:[...this.state.list,this.state.input],
            input:''
        })
    }
    handleDelete(index){
        const list = this.state.list;
        list.splice(index,1)
        this.setState({
            list:list
        })
    }   

    render(){
        return(
          <div>
              <input value={this.state.input} onChange={this.handleInputChange.bind(this)}></input>  <button onClick={this.handleAdd.bind(this)}>add</button>

             <ul>
             {
                  this.state.list.map((item,index)=>{
                      return <TodoItem content={item} key={index} delete={this.handleDelete.bind(this)} index={index}></TodoItem>
                  })
             }
             </ul>
              <TodoItem >
              </TodoItem>
          </div>
        );
    }

}

export default TodoList;

子组件:TodoItem

import React from 'react'
class TodoItem extends React.Component{
    handleDelete() {
        console.log(this.props.index,'this.props.index')
        this.props.delete(this.props.index);
    }  //注意这一段写在render前。
    render(){
        return(
            <div onClick={this.handleDelete.bind(this)}>
                {this.props.content}
            </div>
        )
    }
}
export default TodoItem;

总结:子组件数据显示源于父组件的,在子组件发生的该数据的删除,增加,修改操作皆需要交给父组件做逻辑处理。
组件之间的数据联系无非就是因为涉及到数据的增删改查罢了。对数据的操作(除了显示),子组件一律需将数据交给父组件管理。


关于react, < div onClick = { this.handleDelete.bind(this)} 像这句话:onClick = { this.handleDelete.bind(this)
最重点就在于我们要理解this到底是什么意思,这个意思我之前在studentFunc讲过(也就是2022/3/29做的笔记)


一个习惯修改,因为在button标签中直接使用this.handleDelete.bind(this)会影响性能,不推荐使用,因此推荐在构造函数里
写:
this.handleInputChange = this.handleInputChange.bind(this) 在button 里写 onClick={this.handleInputChange} 即可。
但是最好的办法还是在button标签里写回调函数,这样就不需要重新绑定this了。

我觉得我到现在还没有理解为什么要在构造函数里写this.handleInputChange = this.handleInputChange.bind(this) ,理解不了,
只能理解为什么要用回调函数,以及为什么button里写this.handleDelete.bind(this)这两个方法。
用回调函数的话是因为回调函数的作用域,在回调函数里,this指的是外部,回调函数中this不会发生改变,因为没有赋值给onClick.
(回调函数阻止了onclick事件更改this指向)

好像突然知道为什么了,理解一下bind函数吧:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
这句话:bind() 最简单的用法是创建一个函数,不论怎么调用,这个函数都有同样的 this 值。JavaScript新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,期望方法中的 this 是原来的对象(比如在回调中传入这个方法)。如果不做特殊处理的话,一般会丢失原来的对象。
基于这个函数,用原始的对象创建一个绑定函数,巧妙地解决了这个问题。
在构造函数中使用this.handleInputChange = this.handleInputChange.bind(this)是因为构造函数里有this,这个this是我们最想要的
this.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值