美文网首页
前端面试集

前端面试集

作者: 云顶天宫写代码 | 来源:发表于2022-12-03 00:43 被阅读0次

1. 如何理解 HTML 语义化?

让人更容易读懂(增加代码可读性)。比如video、audio、header(头部)、footor(底部)

2. script 标签中 defer 和 async 的区别?

defer是“渲染完再执行”,async是“下载完就执行”。
举例: 上课期间老师一直讲课,上课中提了一个问题,
defer 的方式是下课后再和同学交流这个问题
async 是有同学想出来了,上课暂时中断,交流提出的问题

3. 从浏览器地址栏输入 url 到请求返回发生了什么

1.解析URL,构建一个请求
2.DNS域名解析
3.TCP连接(三次握手)
4.请求处理
5.浏览器拿到数据后做相应的操作
6.TCP断开(四次挥手)

5. 盒模型 (指的是宽、高属性依据)

1 标准盒模型 (默认使用)
设置宽高属性后只包含 content
2.IE盒模型
设置宽高属性后包含 content + padding + border

6. css 选择器和优先级

内联 > ID选择器 > 类选择器 > 标签选择器。

重排(reflow)和重绘(repaint)的理解

  1. 发生重排一定会发生重绘
  • 如何减少重排和重绘?
    脱离文档流、虚拟DOM

对 BFC(块级格式上下文) 的理解

  1. 是指当前元素的一个矩形区域

创建 BFC 的方式:
绝对定位元素(position 为 absolute 或 fixed )。
行内块元素,即 display 为 inline-block 。
overflow 的值为 hidden (比较推荐这种方式) 。

可以解决的布局问题

  • 避免 margin 重叠问题。
  • 避免高度塌陷。

水平垂直居中多种实现方式

  • 不定宽高:
    利用绝对定位,设置 left: 50% 和 top: 50% 现将子元素左上角移到父元素中心位置,然后再通过 translate 来调整子元素的中心点到父元素的中心。
.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
  • 定宽高:
    利用绝对定位,子元素所有方向都为 0 ,将 margin 设置为 auto ,由于宽高固定,对应方向实现平分。
.father {
  position: relative;
}
.son {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0px;
  margin: auto;
  height: 100px;
  width: 100px;
}

利用绝对定位,设置 left: 50% 和 top: 50% 现将子元素左上角移到父元素中心位置,然后再通过 margin-left 和 margin-top 以子元素自己的一半宽高进行负值赋值。

.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 200px;
  height: 200px;
  margin-left: -100px;
  margin-top: -100px;
}
  • 定不定宽高无所谓
    利用 flex ,最经典最方便的一种
.father {
  display: flex;
  justify-content: center;
  align-items: center;
}

flex 布局

单词读熟悉 详细请看这里

flex-direction
justify-content
align-items
align-content
flex-wrap 
flex-flow

怎么理解flex:1 ? 可以说是弹性比例的权重,如果有两个元素都设置flex:1, 相当于平分父的宽或高

深拷贝与浅拷贝

深拷贝:增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存
浅拷贝:只是增加了一个指针指向已存在的内存地址

对比举例:

    const a={
        name: "wang",
        age:18
    }
    const b = a;
    b.age = 20;
    console.log(a); // {name:"wang",age:20}
    console.log(b);//{name:"wang",age:20}

实质:如果A拷贝B,修改A中的值,观察B是否变化,如果B变化则是浅拷贝,如果不变化则是深拷贝

浅拷贝实现:

  1. Object.assign() 或者 展开运算符号(...)
var obj = { a: {a: "kobe", b: 39} };
var initalObj = Object.assign({}, obj);
initalObj.a.a = "wade";
console.log(obj.a.a); //wade

当object只有一层的时候,是深拷贝

let obj = {
    username: 'kobe'
    };
let obj2 = Object.assign({},obj);
obj2.username = 'wade';
console.log(obj);   //{username: "kobe"}
  1. 深拷贝实现
  • 方式1: 递归+Object.assign() 或者 ...(展开运算符)
    把浅拷贝 通过递归的方式处理一遍就可以实现深拷贝,因为对象只有一层的时候是深拷贝。
 function checkedType(target) {
      return Object.prototype.toString.call(target).slice(8, -1)
    }
    //实现深度克隆---对象/数组
    function clone(target) {
      //判断拷贝的数据类型
      //初始化变量result 成为最终克隆的数据
      let result, targetType = checkedType(target)
      if (targetType === 'Object') {
        result = {}
      } else if (targetType === 'Array') {
        result = []
      } else {
        return target
      }
      //遍历目标数据
      for (let i in target) {
        //获取遍历数据结构的每一项值。
        let value = target[i]
        //判断目标结构里的每一值是否存在对象/数组
        if (checkedType(value) === 'Object' ||
          checkedType(value) === 'Array') { //对象/数组里嵌套了对象/数组
          //继续遍历获取到value值
          result[i] = clone(value)
        } else { //获取到value值是基本的数据类型或者是函数。
          result[i] = value;
        }
      }
      return result
    }
  • 方式2:如果数据是json格式 通过 JSON.parse(JSON.stringify())
  • 方式3:函数库lodash

0.1+0.2 ! == 0.3 如何做到让其相等呢?

使用 Number.EPSILON 误差范围。

function isEqual(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}
console.log(isEqual(0.1 + 0.2, 0.3)); // true

理解 原型与原型链

原型:每一个 JavaScript 对象(null 除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性,其实就是 prototype 对象。
原型链:由相互关联的原型组成的链状结构就是原型链。

我们声明了一个Person函数,既然函数是对象,那么我们就可以使用“.”来查看它的属性,可以看到有一个prototype属性,这个是每一个函数都有的。

我们在代码里面打印出来看看,理解原型示例代码如下:

<script>
  function Person() { }
  console.log(Person.prototype)
</script>

输出结果:

image.png

理解原型链示例代码:

<script>
  function Person(name) {
    this.name = name;
  }
  // 在函数的原型上添加变量和方法
  Person.prototype.name = "信思智学";
  Person.prototype.say = function () {
    console.log("你好信思智学");
  }


  let obj = new Person("张三");
  console.log(obj.name); // 张三
  obj.say(); // 你好信思智学


  console.log(obj)
</script>
image.png

可通过打印的日志,辅助理解原型链

执行上下文

回答和this相关,可以提到箭头函数
以下代码辅助理解 this

var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2

闭包理解

用途或者说使用场景:封装私有变量

不会引起内存泄漏!!! IE9之前是有问题的,现在的浏览器都没问题

var person = function(){    
    //变量作用域为函数内部,外部无法访问    
    var name = "default";       

    return {    
       getName : function(){    
           return name;    
       },    
       setName : function(newName){    
           name = newName;    
       }    
    }    
}();    

console.log(person.name);//直接访问,结果为undefined    
console.log(person)
console.log(person.getName());    //default
person.setName("abruzzi");    
console.log(person.getName());    //abruzzi

Promise

面试ES6 开始使用的异步编程解决方式,主要用来解决回调地狱的问题,可以有效的减少回调嵌套, 更符合编码思维

在哪用到过呢?

  1. uni-app中关于 request 请求的封装


    image.png
  2. react 中配合async await,实现数据的同步调用



垃圾回收机制

深入了解这里看这篇文章即可:「硬核 JS」你真的了解垃圾回收机制吗

总结一下:

有两种垃圾回收策略:

  • 标记清除:标记阶段即为所有活动对象做上标记,清除阶段则把没有标记(也就是非活动对象)销毁。
function test(){
  let A = new Object()   // 有标记
  let B = new Object()  // 有标记
}

test()  // 执行完毕后 标记为清除对象
  • 引用计数:它把对象是否不再需要简化定义为对象有没有其他对象引用到它。如果没有引用指向该对象(引用计数为 0),对象将被垃圾回收机制回收。
let a = new Object()    // 此对象的引用计数为 1(a引用)
let b = a       // 此对象的引用计数是 2(a,b引用)
a = null        // 此对象的引用计数为 1(b引用)
b = null        // 此对象的引用计数为 0(无引用)
...         // GC 回收此对象

这种方式是不是很简单?确实很简单,不过在引用计数这种算法出现没多久,就遇到了一个很严重的问题——循环引用,即对象 A 有一个指针指向对象 B,而对象 B 也引用了对象 A ,如下面这个例子

function test(){
  let A = new Object()
  let B = new Object()
  
  A.b = B
  B.a = A
}

对象 A 和 B 通过各自的属性相互引用着,按照上文的引用计数策略,它们的引用数量都是 2,但是,在函数 test 执行完成之后,对象 A 和 B 是要被清理的,但使用引用计数则不会被清理,因为它们的引用数量不会变成 0,假如此函数在程序中被多次调用,那么就会造成大量的内存不会被释放

防抖与节流

  • 1.debounce(防抖)和throttle(节流)的定义
    口语版: 小胖减肥
    防抖就是只有当小胖连续10天做运动,卡路里消耗达标。如果在这10天内小胖有一天偷懒,运动时长不达标,减肥没有效果,直到满足了10天连续运动,一个月下来只能达标2次
    节流就是无论小胖运动量与否达标,每隔10天就记录一次达标。一个月下来能达标3次。
    防抖是有条件的周期动作,而节流是没有条件的周期动作。
    书面版:
    防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
    节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。

  • 2.防抖和节流解决的都是短时间高频次的调用问题
    在进行resize、scroll、keyup、keydown、mousedown、mousemove等事件操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,容易导致页面卡顿等影响用户的体验;这时就可以通过debounce(防抖)和throttle(节流)函数来限制事件处理函数的调用频率,提升用户的体验,同时又不影响实际的效果。

  • 3.防抖和节流的应用场景
    防抖
    1.登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖。
    2.文本编辑器实时保存,当无任何更改操作一秒后进行保存。
    3.DOM 元素的拖拽功能实现。
    节流
    1.scroll 事件,每隔一秒计算一次位置信息等。
    2.浏览器播放事件,播放音频、视频、每隔一秒计算一次进度信息等。
    3.input框实时搜索并发送请求展示下拉列表,每隔一秒发送一次请求 (也可做防抖)。

如何避免内存泄漏

  1. 减少不必要的全局变量,使用严格模式避免意外创建全局变量。

例如:无意义的变量提升

  1. 在你使用完数据后,及时解除引用(闭包中的变量,dom引用,定时器清除)。

例如: 轮播图的定时器,setTimeOut /setInterval 要根据ID及时清除

  1. 组织好你的逻辑,避免死循环等造成浏览器卡顿,崩溃的问题。

例如:递归的方法要有终止递归进行的条件判断

React 面试相关

React 16.8 加入的新特性
必须在函数数式组件中使用(类组件可以不用看了,简单了解就行)

  • hooks优势是什么?
    不会造成浏览器阻塞
    不用考虑this的指向性问题
    更容易复用代码
    函数式编程,每个功能都包裹在函数中,整体风格更清爽,更优雅

  • useEffect、useLayoutEffect区别:
    useEffect是异步执行,而useLayoutEffect是同步执行的。useEffect是在页面渲染完毕之后执行hooks,uselayoutEffect是在页面渲染之前执行hooks,所以uselayoutEffect会导致页面渲染堵塞,而useEffect有可能会导致页面闪动,99的情况下都用useeffect。

  • 说对React的理解?有哪些特性?
    React,用于构建用户界面的 JavaScript 库,使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面.
    特性和优势

    • JSX语法
    • 单向数据绑定
    • 虚拟DOM
    • Component(组件化)
    • 高效灵活
    • 组件式开发,提高代码复用率
    • 单向响应的数据流会比双向绑定的更安全,速度更快
  • 类组件和函数组件之间有什么区别

    • 类组件:
      无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props。
      所有 React 组件都必须是纯函数,并禁止修改其自身 props。
      React是单项数据流,父组件改变了属性,那么子组件视图会更新。
      属性 props是外界传递过来的,状态 state是组件本身的,状态可以在组件中任意修改
      组件的属性和状态改变都会更新视图。
    • 函数组件:
      函数组件接收一个单一的 props 对象并返回了一个React元素
      函数组件的性能比类组件的性能要高,为了提高性能,尽量使用函数组件。
  • React.memo() 和 React.useMemo() 的区别

memo 是一个高阶组件,默认情况下会对 props 进行浅比较,如果相等不会重新渲染。多数情况下我们比较的都是引用类型,浅比较就会失效,所以我们可以传入第二个参数手动控制。
useMemo 返回的是一个缓存值,只有依赖发生变化时才会去重新执行作为第一个参数的函数,需要记住的是,useMemo 是在 render 阶段执行的,所以不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴

  • React.useCallback() 和 React.useMemo() 的区别

useCallback 可缓存函数,其实就是避免每次重新渲染后都去重新执行一个新的函数。
useMemo 可缓存值。

  • React 性能优化手段

使用 React.memo 来缓存组件。
使用 React.useMemo 缓存大量的计算
避免使用匿名函数。
使用 React.Fragment 避免添加额外的 DOM。

  • React key 是干嘛用的,同级复用标签的时候为什么要加? key 主要是解决哪一类问题的

Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。

  • 对React中Fragment的理解,它的使用场景是什么?

在React中,组件返回的元素只能有一个根元素。为了不添加多余的DOM节点,我们可以使用Fragment标签来包裹所有的元素,Fragment标签不会渲染出任何元素。React官方对Fragment的解释:

React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。

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

// 一般形式
render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}
// 也可以写成以下形式
render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}
  • 说说对React refs 的理解?应用场景?

Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。
创建ref的形式有四种:

  • 传入字符串,使用时通过 this.refs.传入的字符串的格式获取对应的元素
    只需要在对应元素或组件中ref属性
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref="myref" />;
  }
}

访问当前节点的方式如下:

this.refs.myref.innerHTML = "hello";
  • 传入对象,对象是通过 React.createRef() 方式创建出来,使用时获取到创建的对象中存在 current 属性就是对应的元素
    refs通过React.createRef()创建,然后将ref属性添加到React元素中,如下:
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

当 ref 被传递给 render 中的元素时,对该节点的引用可以在 ref 的 current 属性中访问

const node = this.myRef.current;
  • 传入函数,该函数会在 DOM 被挂载时进行回调,这个函数会传入一个 元素对象,可以自己保存,使用时,直接拿到之前保存的元素对象即可
    当ref传入为一个函数的时候,在渲染过程中,回调函数参数会传入一个元素对象,然后通过实例将对象进行保存
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={element => this.myref = element} />;
  }
}

获取ref对象只需要通过先前存储的对象即可

const node = this.myref 
  • 传入hook,hook是通过 useRef() 方式创建,使用时通过生成hook对象的 current 属性就是对应的元素

通过useRef创建一个ref,整体使用方式与React.createRef一致

function App(props) {
  const myref = useRef()
  return (
    <>
      <div ref={myref}></div>
    </>
  )
}

获取ref属性也是通过hook对象的current属性

const node = myref.current;

应用场景

  • 对Dom元素的焦点控制、内容选择、控制
  • 对Dom元素的内容设置及媒体播放
  • 对Dom元素的操作和对组件实例的操作
    ( antdpro 中 ProTable使用ref 来进行表格数据的重载)
  • 集成第三方 DOM 库
  • React中组件之间如何通信?

可以说整体用的UmiJS 中的model,作为数据共享的基础
以函数式组件为主:

  • 单纯的父子通信用 props
  • 子父通信 用 props 和 callback 方式
react 路由怎么配置

可以说在 umijs中,使用 .umirc.ts 中配置

import { defineConfig } from '@umijs/max';

export default defineConfig({
 antd: {},
 access: {},
 model: {},
 initialState: {},
 request: {},
 layout: {
   title: '@umijs/max',
 },
 routes: [
   {
     path: '/',
     redirect: '/login',
   },
   {
     name: '首页',
     path: '/home',
     component: './Home',
   },
   {
     name: '权限演示',
     path: '/access',
     component: './Access',
   },
   {
     name: '系统管理',
     path: '/system',
     routes:[
       {
         name:'用户管理',
         path:'/system/user',
         component: '@/pages/System/User'
       }
     ]
   },
   {
     name: '登录',
     path: '/login',
     component: './Login',
     layout: false   // 不使用默认布局,左侧菜单不显示
   },
 ],
// 配置代理解决跨域问题
 proxy: {
   '/api': {
     'target': 'https://www.efss.cn/cms',
     'changeOrigin': true,
     'pathRewrite': { '^/api' : '/api' },
   },
   '/auth': {
     'target': 'https://www.efss.cn/cms',
     'changeOrigin': true,
     'pathRewrite': { '^/auth' : '/auth' },
   }
 },
 npmClient: 'yarn',
});

Hooks: React为我们提供很多钩子

最常用的

useState()
useEffect()
其他

不同的钩子为函数引入不同的外部功能,我们发现上面钩子都带有use前缀,React约定,钩子一律使用 use前缀命名。所以,你自己定义的钩子都要命名为useXXX。

  1. userState():状态钩子 - 函数组件局部的状态
import React, {useState} from 'react'
const AddCount = () => {
  const [ count, setCount ] = useState(0)
  const addcount = () => {
    let newCount = count
    setCount(newCount+=1)
  } 
  return (
    <>
      <p>{count}</p>
      <button onClick={addcount}>count++</button>
    </>
  )
}
export default AddCount
  1. useEffect():副作用钩子
    • 第一个参数必须传入函数
    • 第二个参数
      情况1 没有第二个参数,随时(任何状态的变化)都会触发
      情况2 传入空数组[],只在组件初始化(组件渲染完成)的时候触发
      情况3 数组中加入 state,建立一个一一对应的关系。
import React, { useEffect, useState } from "react";

const TownAmount: React.FC = (props:any)=>{
    // useState 是 hook中的一个钩子, 怎么使用:
    // const [状态名字, set状态名字] = useState(状态默认值); 
    // ownerAmount 是一个状态,可以是任何数据类型  setOwnerAmount 是一个方法
    const [ownerAmount, setOwnerAmount] = useState(10);
    const [peoples, setPeoples] = useState(5);  // 常住农业人口
    /**
     * 第一个参数必须传入函数
     * 第二个参数
     * 情况1 没有第二个参数,随时(任何状态的变化)都会触发
     * 情况2 传入空数组[],只在组件初始化(组件渲染完成)的时候触发
     * 情况3 数组中加入 state,建立一个一一对应的关系。
     * 
     */
    useEffect(()=>{
        console.log('副作用发生了')
        // 这里写关联的逻辑
        return ()=>{
            console.log('卸载副作用,类似于clearInterval')
        }
    },[peoples,ownerAmount]);

    const PayAmount = ()=>{
        setOwnerAmount((ownerAmount-2));
    }

    /**
     * 外出1万人
     */
    const OutPeople = ()=>{
        setPeoples(peoples-1);
    }

    return (
        <>  
            <button onClick={PayAmount}>
                支出2万
            </button>
            <button onClick={OutPeople}>
                进城务工 1 万人
            </button>
            <h4>乡镇收到拨款:{props.amount} 目前余额:{ownerAmount} 剩余人口:{peoples}万人</h4>
        </>
    )
}

export default TownAmount;
  1. useContext():共享状态钩子 - 函数组件之间全局的状态
import React,{useContext, useState, createContext} from 'react';
import {Button} from 'antd';
import '../../App.css';
 
const CountContext = createContext();
 
const TestContext = () =>{
    const [count, setCount] = useState(0);
    console.log(CountContext);
    console.log(useContext(CountContext));
    return(
      <div>
          <p>父组件点击次数:{count}</p>
          <Button type={"primary"} onClick={()=>setCount(count+1)}>点击+1</Button>
          <CountContext.Provider value={count}>
            <Counter/>
          </CountContext.Provider>
      </div>
  )
};
 
const Counter = () => {
    const count = useContext(CountContext);
    console.log(CountContext);
    // console.log(count);
    // console.log(useContext(CountContext));
    return (
        <div>
            <p>子组件获得的点击数量:{count}</p>
        </div>
    );
};
  1. useReducer(): 处理复杂的状态,计算一个新的state. setState钩子的底层实现用到了它
const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

const Counter = () => {
  const initialState = {count: 0}
  const [state, dispatch] = useReducer(reducer, initialState);
  
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
    </>
  );
}

小程序相关

微信登录
image.png

首先在前端调用login()方法获取 code
拿到 code后请求我们自己的后端,登录操作由我们自己的后端完成。
后端接收到 code ,携带 code 、appid 和 appSecret后向微信的服务器发送请求,索取该用户的openid。
返回 openid 后,与我们的数据库进行对比,寻找绑定该微信的用户,进而实现自定义登录功能。

直接登录获取openId

uni.login({
    provider: 'weixin',
    onlyAuthorize:true,
    success: function(loginRes) {
        uni.request({
            url: "http://127.0.0.1/login/wechat/" + loginRes.code, //后台地址,将code传递给后端
            success: (res) => {
                // 处理登录成功
            }
        })
    }
});
uni-app 中的跳转方式
  • navigateTo 保留当前页面,跳转到应用内的某个页面,使用 navigateBack 可以返回到原页
  • redirectTo 关闭当前页面,跳转到应用内的某个页面
  • switchTab 跳转到 tabBar 页面,同时关闭其他非 tabBar 页面
  • navigateBack 返回上一页面
  • reLanch 关闭所有页面,打开到应用内的某个页面
生命周期
image.png

执行过程
应⽤的⽣命周期执行过程:

  • ⽤户⾸次打开⼩程序,触发 onLaunch(全局只触发⼀次)

  • ⼩程序初始化完成后,触发onShow⽅法,监听⼩程序显示

  • ⼩程序从前台进⼊后台,触发 onHide⽅法

  • ⼩程序从后台进⼊前台显示,触发 onShow⽅法

  • ⼩程序后台运⾏⼀定时间,或系统资源占⽤过⾼,会被销毁

⻚⾯⽣命周期的执行过程:

  • ⼩程序注册完成后,加载⻚⾯,触发onLoad⽅法
  • ⻚⾯载⼊后触发onShow⽅法,显示⻚⾯
  • ⾸次显示⻚⾯,会触发onReady⽅法,渲染⻚⾯元素和样式,⼀个⻚⾯只会调⽤⼀次
  • 当⼩程序后台运⾏或跳转到其他⻚⾯时,触发onHide⽅法
  • 当⼩程序有后台进⼊到前台运⾏或重新进⼊⻚⾯时,触发onShow⽅法
  • 当使⽤重定向⽅法 wx.redirectTo() 或关闭当前⻚返回上⼀⻚wx.navigateBack(),触发onUnload

微信支付

打开某小程序,点击直接下单

  • wx.login获取用户临时登录凭证code,发送到后端服务器换取openId
    在下单时,小程序需要将购买的商品Id,商品数量,以及用户的openId传送到服务器
  • 服务器在接收到商品Id、商品数量、openId后,生成服务期订单数据,同时经过一定的签名算法,向微信支付发送请求,获取预付单信息(prepay_id),同时将获取的数据再次进行相应规则的签名,向小程序端响应必要的信息
  • 小程序端在获取对应的参数后,调用wx.requestPayment()发起微信支付,唤醒支付工作台,进行支付
  • 接下来的一些列操作都是由用户来操作的包括了微信支付密码,指纹等验证,确认支付之后执行鉴权调起支付
  • 鉴权调起支付:在微信后台进行鉴权,微信后台直接返回给前端支付的结果,前端收到返回数据后对支付结果进行展示
  • 推送支付结果:微信后台在给前端返回支付的结果后,也会向后台也返回一个支付结果,后台通过这个支付结果来更新订单的状态

以下是uni-app 调起微信支付的核心代码

e70dcaf81b37ee43a7e926e8d924864.png

相关文章

  • web前端面试题总结

    web前端试题集 WEB前端面试题

  • 前端最强面经汇总

    面试秘籍 中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上) 前端面试 - 收藏集 - 掘金 2万5千字...

  • 前端面试的经典题

    前端面试的经典题 前端面试三部曲 前端面试概念收集器 前端面试的经典题 前端面试的难题和怪题 Javascript...

  • 上海前端面试集

    写在前面的话:以下是个人在找工作中被考的题目,供大家参考,答案我也在网上找到了附在下面,如果有什么不同的答案,欢迎...

  • 值得看的前端面试文章- 收藏集 - 掘金

    【前端面试 -- 四月二十家前端面试题分享】1-5 套个人解题答案 - 前端 - 掘金前端面试题 前端面试--四月...

  • 前端面试概念收集器

    前端面试概念收集器 前端面试三部曲 前端面试概念收集器 前端面试的经典题 前端面试的难题和怪题 本文分为 概念,原...

  • 前端面试的难题和怪题

    前端面试的难题和怪题 前端面试三部曲 前端面试概念收集器 前端面试的经典题 前端面试的难题和怪题 函数 答案 Er...

  • PHPer 面试指南-扩展阅读资源整理

    前端篇 收集的前端面试题和答案 前端开发面试题 史上最全的web前端面试题汇总及答案 前端工程师手册 HTTP协议...

  • PHPer 面试指南-扩展阅读资源整理

    前端篇 收集的前端面试题和答案 前端开发面试题 史上最全的web前端面试题汇总及答案 前端工程师手册 HTTP协议...

  • 前端面试题集

    面试题 1.TCP与UDP的区别? TCP可靠、面向连接,相对UDP较慢UDP不可靠、不面向连接,相对TCP较快 ...

网友评论

      本文标题:前端面试集

      本文链接:https://www.haomeiwen.com/subject/oofpfdtx.html