「复习大纲03」-菜鸡前端知识体系整理

197 阅读6分钟

六、框架

1、vue

1.1、vue生命周期

  • beforeCreate,创建前状态,(当前阶段data,methods,computed,watch上的数据和方法都不能被访问)
  • created,进入数据观测阶段,可以使用和更改数据,(但是不会触发updated函数,当前阶段无法与Dom进行交互)
  • beforeMount,发生在挂载前
  • mounted,挂载完成后,(当前的真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$ refs 属性对Dom 进行操作)
  • beforeUpdate,发生在更新前,可以在当前阶段进行更改数据,不会造成重复渲染
  • updated ,发生在更新后,当前阶段Dom已完成更新。
  • beforeDestroy,销毁前,当前阶段实例完成可以被使用,此阶段可以善后处理一些东西,例如定时器
  • destroyed,销毁后,此时已经Dom已之剩下空壳,组件已被拆解,数绑定被卸除,监听被移除,

1.2、nextTick原理

1.3、diff算法

1.4、vue中组件传值方法有哪些?

参考文献

 props //父->子
 $emit、$on //子->父
 ref // 获取实例方式调用组件的属性或者方法 //子->父
 $parent / $children  //获取父子组件实例
  • 一些实际🌰

  • 子组件向父组件传值 ref/refs
    ref 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;
    如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据。也算是子组件向父组件传值的一种

    父组件

    <template>
      <child ref="childForRef"></child>
    </template>
    <script>
    import child from './child.vue'
      export default {
        components: { child },
        mounted() {
          const childForRef = this.$refs.childForRef;
          console.log(childForRef.name);
          childForRef.sayHello();
        }
      }
    </script>
    

    子组件

    export default {
      data () {
        return {
          name: 'Vue.js'
        }
      },
      methods: {
        sayHello () {
          console.log('hello')
        }
      }
    }
    
  • 兄弟组件通信

eventBus  Vue.prototype.$bus = new Vue
vuex
  • 一些实际🌰

  • 兄弟组件和隔代组件 eventBus eventBus 又称为事件总线,在Vue中可以使用它作为沟通的桥梁,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。

  • 首先需要创建一个事件总线并将其导出, 以便其他模块可以使用或者监听它。 bus.js:

    import Vue from 'vue'
    export const bus = new Vue()
    
  • 发送事件,假设有 child1、child2 两个兄弟组件,在 child1.vue 中发送事件。 parent.vue:

    <template>
      <div>
        <child1></child1>
        <child2></child2>
      </div>
    </template>
    <script>
    import child1 from './child1.vue'
    import child2 from './child2.vue'
    export default {
      components: { child1, child2 }
    }
    </script>
    

    child1.vue:

    <template>
      <div>
        <button @click="additionHandle">+加法器</button>    
      </div>
    </template>
    <script>
    import {bus} from '@/bus.js'
    console.log(bus)
    export default {
      data(){
        return{
          num:1
        }
      },
      methods:{
        additionHandle(){
          bus.$emit('addition', {
            num:this.num++
          })
        }
      }
    }
    </script>
    

    在 child2.vue 中接收事件。

    <template>
      <div>计算和: {{count}}</div>
    </template>
    <script>
    import { bus } from '@/bus.js'
    export default {
      data() {
        return {
          count: 0
        }
      },
      mounted() {
        bus.$on('addition', arg=> {
          this.count = this.count + arg.num;
        })
      }
    }
    </script>
    

    如果想移除事件的监听, 可以像下面这样操作:

    import { bus } from './bus.js'
    Bus.$off('addition', {})
    
  • 跨级通信

vuex
$ attrs / $ listeners   
// $ attrs 里面存放的父组件中绑定的非Props属性
// $ listeners 里面存放的父组件绑定的非原生事件
provide / inject 
// provide:一个对象或返回一个对象的函数 
// inject:一个字符串数组,或 一个对象,对象的 [key] 是本地的绑定名  
  • 一些实际🌰

  • 兄弟组件和隔代组件 Vuex

    vuex的 store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    const state = {
       // 初始化A和B组件的数据,等待获取
       AMsg: '',
       BMsg: ''
     }
    
     const mutations = {
       receiveAMsg(state, payload) {
         // 将A组件的数据存放于state
         state.AMsg = payload.AMsg
       },
       receiveBMsg(state, payload) {
         // 将B组件的数据存放于state
         state.BMsg = payload.BMsg
       }
     }
    
     export default new Vuex.Store({
       state,
       mutations
     })
    
  • 兄弟组件和隔代组件 attrs/attrs / listeners parent.vue

    <template>
      <div>
        <child-a :name="name" :age="age" :gender="gender" :height="height" title="嘿嘿嘿"></child-a>
      </div>
    </template>
    <script>
    import ChildA from './ChildA'
    export default {
      components: { ChildA },
      data() {
        return {
          name: "zhang",
          age: "18",
          gender: "女",
          height: "168"
        };
      }
    };
    </script>
    

    // childCom1.vue

    <template class="border">
      <div>
        <p>name: {{ name}}</p>
        <p>childCom1的$attrs: {{ $attrs }}</p>
        <child-com2 v-bind="$attrs"></child-com2>
      </div>
    </template>
    <script>
    const childCom2 = () => import("./childCom2.vue");
    export default {
      components: {
        childCom2
      },
      inheritAttrs: false, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性
      props: {
        name: String // name作为props属性绑定
      },
      created() {
        console.log(this.$attrs);
         // { "age": "18", "gender": "女", "height": "158", "title": "程序员成长指北" }
      }
    };
    </script>
    

    // childCom2.vue

    <template>
      <div class="border">
        <p>age: {{ age}}</p>
        <p>childCom2: {{ $attrs }}</p>
      </div>
    </template>
    <script>
    
    export default {
      inheritAttrs: false,
      props: {
        age: String
      },
      created() {
        console.log(this.$attrs); 
        // { "gender": "女", "height": "158", "title": "程序员成长指北" }
      }
    };
    </script>
    
  • 兄弟组件和隔代组件 provide / inject 代码执行顺序
    data
    provide
    created
    mounted

1.5、说一下Vue双向绑定的原理

  • 初始化用户传入的data数据
  • 将数据进行观测(new Observer)
  • 进行对象的处理(this.walk(value))
  • 循环对象属性,定义响应式变化(defineReactive)
  • 重新定义数据 (Object.defineProperty)

1.6、computed与watch有什么区别,及运用场景

场景computedwatch
基础区别本质是具备缓存的watcher,
依赖的属性发生变化就会更新视图
没有缓存性,更多的是观察作用,
可以监听某些数据执行回调
适用范围计算比较消耗性能的计算场景
关联多个实时计算的对象
当需要在数据变化响应时,执行异步操作
或者高性能消耗
触发时机-只有值发生改变才会执行,
如果要立即处理,进页面就触发,
可以在watch里面 设置immediate: true

实际例子

  • 当表达式过于复杂时候,在模板中放入过多的逻辑会让模板难以维护,可以使用computed作为计算属性处理。
  • watch,当我们需要深度监听对象中的属性时,可以打开deep:true选项,这样变会对对象中的每个属性进行监听。(同时也会产生性能问题,优化的话可以使用字符串形式监听)。

2、vuex

2.1、基本属性有哪些

  • state
  • getter
  • mutation
  • action
  • module

3、React

参考文献

3.1、React hooks


react-hooks api
useState
useEffect
useContext
useCallback
useRef
useMemo

具体使用

  • 1、useState

  • 1.1、基本语法

    const [state,setState]=useState(initialState)
    
    • 传入的唯一参数:initialState,可以是
      • 数字 useState(0)
      • 字符串
      • 对象 useState({a:1})
      • 数组 useState[1,2]
      • 可以传入函数,来通过逻辑计算出默认值
      function App (props) {
        const [ count, setCount ] = useState(() => {
          return props.count || 0
        })
        return (
          <div>
            点击次数: { count } 
            <button onClick={() => { setCount(count + 1)}}>点我</button>
          </div>
        )
      }
      
    • 返回的是包含两个元素的数组
      • 第一个state 变量

      • 第二个 setState 是修改state值的方法,是一个函数

  • 1.2、看个🌰

    import React, { useState} from "react";
    const [count, setCount]= useState(0)
    
    return(
      <div>
        点击次数:{count}
        <button  onClick={() => { setCount(count + 1)}}>点我</button>
      </div>
    )
    

    上面例子有些需要注意的地方

    • 传入相同值,是不会重新渲染的
    • 组件每渲染一次,useState中函数其实不会每次都执行
    • setUseState时获取上一轮值
    setCount(count=>count+1)
    
    • 多个useState的情况,尽量不要在循环,条件或嵌套函数中调用hook,必须确保是在React函数的最顶层调用。确保hook在每一次渲染中都按照同样的顺序被调用。
  • 2、useEffect

  • 2.1、基本描述

    • 主要提供了页面钩子方法,完成一些类似于class组件中生命周期
      componentDidMount 挂载
      componentDidUpdate 更新
      componentWillUnmount 卸载
      的功能
    • 例如像:网络请求、手动更新DOM、一些事件的监听,都是React更新DOM的一些副作用
    • 举个🌰
    import React, { useEffect} from "react";
    useEffect(()=>{
      console.log('useEffect被执行了')
    })
    
  • 2.2、基本用法

  • 2.2.1、作用:通过useEffect的Hook,告诉React需要在渲染后执行某些操作

  • 2.2.2、参数:useEffect要求我们传入一个回调函数,在React执行完更新DOM操作之后,就会回调这个函数

  • 2.2.3、执行时机:首次渲染之后,或者每次更新状态之后,都会执行这个回调函数

    引起注意的是,useEffect的第二个参数

    • 什么都不传,组件每次 render 之后 useEffect 都会调用 <===> 等同于:componentDidMountcomponentDidUpdate
     useEffect(()=>{
       //TODO
       //具体逻辑
     })
    
    • 传入一个空数组,只会调用一次, <===> 等同于:componentDidMountcomponentDidUpdate
    useEffect(()=>{
      //TODO
      //具体逻辑
    },[])
    
    • 传入一个数组,其中包括变量,只有这些变量变动时,useEffect才会执行
    useEffect(()=>{
      //TODO
      //具体逻辑
    },[count])
    
  • 🤔 2.3、有些时候需要清除Effect

    • 2.3.1、最常见的场景:清除订阅外部数据源,防止引起内存泄露

    参考代码如下

    import React, { useEffect, useState } from 'react'
    useEffect(() => {
      // 默认情况下,每次渲染后都会被调用该函数
      console.log('订阅一些事件')
    
      // 如果要实现 componentWillUnmount,
      // 在末尾处返回一个函数
      // React 在该函数组件卸载前调用该方法
      // 其命名为cleanup 是为了表明此函数的目的
      // 但其实也可返回一个箭头函数或者起一个别名
      return function cleanup() => {
        console.log('取消订阅')  //取消订阅
      }
    })
    
  • 2.3.2、为啥要在Effect中返回一个函数?

    • 这是因为Effect可选的清除机制,每个Effect都可返回一个清除函数

    • 如此可以将添加和移除订阅的逻辑放到一起

    • 都是属于Effect的一部分

  • 3、useContext

  • 4、useCallback

  • 4.1、作用

    • 尤其向子组件传递函数props时,每次render,都会创建新函数,导致子组件不必要的渲染,浪费性能
    const onClick = useCallback(()=>{
      console.log('button click')
    },[])
    
    • 解决当依赖的属性没有改变时
  • 4.2、基本使用

    • useCallback主要是为了进行性能优化
  • 5、useRef

  • 5.1、基本用法

    • useRef返回一个ref对象,返回的ref对象在组件的整个生命周期保持不变
    const refContainer=useRef(initialState)
    
    const refContainer=useRef(0)
    // 返回结果
    {current: 0}
    
  • 5.2、常见使用场景

    • 场景一:保存一个数据,这个对象在整个生命周期可以保持不变
    const [count, setCount] = useState(0);
    const numRef = useRef(count);
    
    // 将上次的count进行保存,在count发生改变时,重新保存count
    // 在点击button时,增加count时,会调用useEffect函数,渲染DOM后,会重新将上一次的值进行保存,使用ref保存上一次的某一个值不会触发render
    useEffect(() => {
      numRef.current = count;
    }, [count]);
    
    <div>count 上次的值:{numRef.current}</div>
    <div>count 这次的值:{count}</div>
    <button onClick={(e) => setCount(count + 10)}>+10</button>
    
    • 场景二:引入DOM(或者组件)元素,但是前提条件需要是class组件
    class childTest extends React.Component {
      render() {
        return <div>childTest</div>
      }
    }
    
    export default function demo() {
      const titleRef = useRef()
      const cpnRef = useRef()
    
      function changeDOM() {
        // 修改DOM
        titleRef.current.innerHTML = 'hello world'
        console.log(cpnRef.current)
      }
    
      return (
        <div>
          {/* 1.修改DOM元素 */}
          <h2 ref={titleRef}>RefHookDemo01</h2>
          {/* 2.获取class组件 */}
          <ChildCpn ref={cpnRef} />
          <button onClick={changeDOM}>修改DOM</button>
        </div>
      )
    }
    

6、useMemo

  • 6.1、作用:

    • 6.1.1、为了进行性能的优化
    • 6.1.2、和Vue中的computed计算属性类似,都是根据依赖的值计算出结果,如果依赖的值未发生改变的时候,不触发状态改变
    const [count, setCount] = useState(0);
    const add = useMemo(() => {
      return count + 1;
    }, [count]);
    
    <div>
      点击次数: {count}
      <br />
      次数加一: {add}
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        点我
      </button>
    </div>
    
  • 6.2、注意的是:

    • 6.2.1、 useMemo会在渲染的时候执行,而不是渲染之后执行,这个与useEffect,不一样
    • 6.2.2、useMemo,也还是会有第二个参数,用法和useEffect类似

七、计算机网络知识

1、DNS是个啥

2、HTTP、HTTPS是什么,区别是怎样的

3、HTTP1.0\HTTP1.1\HTTP2.0的区别?

4、TCP、IP网络模型

5、UDP和TCP的区别

6、从输入URL到页面加载都经历了什么