卷不动也得继续学!紧跟vue3的步伐,再来get一波进阶新特性!

vue3进阶新特性

vue3进阶新特性

  • 一、📗watch和watchEffect
    • 1、watch和watchEffect的区别
    • 2、举个例子
      • (1)wtach监听
      • (2)watchEffect监听
  • 二、📘setup如何获取组件实例
      • (1)为什么需要获取组件实例
      • (2)举个例子
  • 三、📒 Vue3为何比Vue2快
    • 1、Proxy响应式
    • 2、PatchFlag
      • (1)什么是PatchFlag
      • (2)举个例子🌰
    • 3、hoistStatic
      • (1)什么是hoistStatic
      • (2)举个例子🌰
    • 4、cacheHandler
      • (1)什么是cacheHandler
      • (2)举个例子🌰
    • 5、SSR优化
      • (1)什么是SSR优化
      • (2)举个例子🌰
    • 6、tree-shaking
      • (1)什么是tree-shaking
      • (2)举个例子🌰
  • 四、📚Vite为什么启动非常快
    • 1、Vite是什么
    • 2、Vite为何启动快?
    • 3、ES Module演示
      • (1)基本使用
      • (2)ES Module在浏览器中的应用
        • 1)基本演示
        • 2)引入外链
        • 3)远程引用
        • 4)动态引入
  • 五、📙全局API修改
    • 1、Vue2全局API
    • 2、Vue3全局API
      • (1)Vue3新写法
      • (2)常见配置更新
  • 六、📮结束语

之前写了一篇文章谈论 vue3 的新特性,然鹅……周一最近又 get 到了几个比较进阶的新特性, 比如: vue2watchvue3 为什么用 watchEffect 。还有 vue3 为什么比 vue2 快, vite 为什么启动会非常快,以及 vue3 对全局注册 API 做出的重大改变。

一起来了解一波 vue3 新特性📷

一、📗watch和watchEffect

1、watch和watchEffect的区别

我们在 vue2 时,经常用 watch监听数据。但现在的 vue3 已经改用 watchEffect 来进行数据监听了。这两者具体有以下区别:

  • 两者都可以监听 data 属性变化;
  • watch 需要明确监听哪个属性
  • watchEffect 会根据其中的属性,自动监听其变化。

2、举个例子

(1)wtach监听

我们用 watch监听数据具体代码如下:

<template><!-- <p>watch vs watchEffect</p> --><p>{{numberRef}}</p><p>{{name}} {{age}}</p>
</template><script>
import { reactive, ref, toRefs, watch, watchEffect } from 'vue'export default {name: 'Watch',setup() {const numberRef = ref(100)const state = reactive({name: 'monday',age: 18})watch(numberRef, (newNumber, oldNumber) => {console.log('ref watch', newNumber, oldNumber)}, {immediate: true // 初始化之前就监听,可选})setTimeout(() => {numberRef.value = 200}, 1500)watch(// 第一个参数,确定要监听哪个属性() => state.age,// 第二个参数,回调函数(newAge, oldAge) => {console.log('state watch', newAge, oldAge)},// 第三个参数,配置项{immediate: true, // 初始化之前就监听,可选// deep: true // 深度监听})setTimeout(() => {state.age = 25}, 1500)setTimeout(() => {state.name = 'mondayLab'}, 3000)return {numberRef,...toRefs(state)}}
}
</script>

此时浏览器的显示效果如下:

watch

综上,我们可以知道,当使用 watch 进行属性监听时,需要明确要监听哪一个属性,并且如果想要在初始化时就被监听,需要加上第三个可选参数 immediate:true 。这样看来,如果我们要监听多个属性时,那就要写很多个 watch ,属实有点麻烦。所以, vue3 就引进了 watchEffect 来解决这几个问题。

(2)watchEffect监听

我们用 watchEffect监听数据具体代码如下:

<template><!-- <p>watch vs watchEffect</p> --><p>{{numberRef}}</p><p>{{name}} {{age}}</p>
</template><script>
import { reactive, ref, toRefs, watch, watchEffect } from 'vue'export default {name: 'Watch',setup() {const numberRef = ref(100)const state = reactive({name: 'monday',age: 18})watchEffect(() => {// 初始化时,一定会先执行一次(收集要监听的数据)console.log('numberRef', numberRef.value)console.log('state.age', state.age)console.log('state.name', state.name)})setTimeout(() => {numberRef.value = 2000}, 1000)setTimeout(() => {state.age = 25}, 1500)setTimeout(() => {state.name = 'mondayLab'}, 3000)return {numberRef,...toRefs(state)}}
}
</script>

此时浏览器的显示效果如下:

watchEffect

从上图中可以看到, watchEffect 只要做一次监听,就可以同时监听到三个属性。同时,值得注意的是, watchEffect需要初始化,且初始化时一定会先执行一次,这个初始化的目的在于收集要监听的数据。所以,控制台打印的第一组数据就是初始化时的数据。

第一次收集到它要监听这三个属性后,在此之后呢,这三个属性也相应地拥有了响应式的功能。相对应的三个计时器再打印出三组数据出来,所以一共是四组数据。

二、📘setup如何获取组件实例

(1)为什么需要获取组件实例

刚听到这个概念时,我其实时有点懵的。为什么要用setup来获取组件的实例?其实说的就是一个this的指向问题。

vue2 中, Options API 可以使用 this 来获取组件的实例,但是到现在的 vue3 ,已经被摒弃掉了。在 setup 和其他 Composition API 中没有 this ,但是它提供了一个 getCurrentInstance 来获取当前的实例。

(2)举个例子

我们先用 Options API 来获取实例。具体代码如下:

<template><p>get instance</p>
</template><script>
import { onMounted, getCurrentInstance } from 'vue'export default {name: 'GetInstance',data() {return {x: 1,y: 2}},mounted() {console.log('this2', this)console.log('x', this.x, 'y', this.y)}
}
</script>

此时浏览器的显示效果如下:

optionAPI

正如我们所想的,用 options API ,具体的实例都可以如期的被调用出来。


下面我们用 Composition API 来看看,是否可以调用出来。具体代码如下:

<template><p>get instance</p>
</template><script>
import { onMounted, getCurrentInstance } from 'vue'export default {name: 'GetInstance',data() {return {x: 1,y: 2}},setup() {//无法获取this实例console.log('this1', this)const instance = getCurrentInstance()console.log('instance', instance)onMounted(() => {//无法获取this实例console.log('this in onMounted', this)//通过getCurrentInstance获取this实例console.log('x', instance.data.x)})}
}
</script>

此时浏览器的显示效果如下:

CompositionAPI

通过上图我们可以知道,如果用 Composition API 来获取组件实例,是没有办法获取的。需要通过 getCurrentInstance 方法来获取当前的组件实例

三、📒 Vue3为何比Vue2快

有一次看面经的时候发现有一道题:Vue3为何比Vue2快。当时我也挺纳闷的,那个时候我的心里🤯: vue3 的出现不就是因为更好才出现嘛?不是更好难道还能更差?

事实证明……是我孤陋寡闻了Vue3 比 Vue2 快的原因主要体现在以下6个方面:

  • Proxy响应式
  • PatchFlag
  • hoistStatic
  • cacheHandler
  • SSR优化
  • tree-shaking

接下来就让我们一起来了解一下吧🙋

1、Proxy响应式

vue3 中实现响应式的 Proxy 会比 vue2 中的 Object.defineProperty 快。具体原因可翻看我的另外一篇文章,这里不再讲述。

2、PatchFlag

(1)什么是PatchFlag

  • 在编译模板时,使用动态节点做标记;
  • 标记,分为不同的类型,如TEXTPROPS ;有的是直接获取 text ,有的则是修改 props
  • diff 算法比较时,可以区分静态节点,以及不同类型的动态节点。此处要注意的是, patchflag 并不是专门对 diff 算法做优化,而是在输入上做一些变更和做一些标记,从而达到对 diff 算法的优化。

(2)举个例子🌰

我们用一个在线网站来演示 patchflag ,在线网站网址为https://vue-next-template-explorer.netlify.app/,大家可以根据需要自行演示~

具体使用方式如下图所示:

在线网站演示

接下来我们来演示 patchflag ,此时右边的 options 不做选择。我们在左边的框输入下面代码:

<div id="app"><span>hello vue3</span><span>{{msg}}</span><span :class="name">monday</span><span :id="name">monday</span><span :id="name">{{mag}}</span><span :id="name" :msg="msg">monday</span>
</div>

此时右边的框显示如下:

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock("div", { id: "app" }, [_createVNode("span", null, "hello vue3"),_createVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),_createVNode("span", { class: _ctx.name }, "monday", 2 /* CLASS */),_createVNode("span", { id: _ctx.name }, "monday", 8 /* PROPS */, ["id"]),_createVNode("span", { id: _ctx.name }, _toDisplayString(_ctx.mag), 9 /* TEXT, PROPS */, ["id"]),_createVNode("span", {id: _ctx.name,msg: _ctx.msg}, "monday", 8 /* PROPS */, ["id", "msg"])]))
}// Check the console for the AST

大家可以看到,除了第一个是静态节点以外,其他都是动态节点。此时模板编译后的结果,在最后边有对应的数字出现,这个数字就是标记vue3 通过给每个动态节点做数字标记,达到优化 diff 算法的效果。

3、hoistStatic

(1)什么是hoistStatic

  • 将静态节点的定义,提升到父作用域上,并缓存起来;
  • 多个相邻的静态节点,会被合并起来;
  • 典型的拿空间换时间的优化策略。

(2)举个例子🌰

我们同样用在线网站来做一个演示。此时我们在左边框输入以下代码:

<div id="app"><span>monday</span><span>monday</span><span>monday</span><span>{{msg}}</span>
</div>

此时右边的框显示如下:

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"const _hoisted_1 = { id: "app" }
const _hoisted_2 = /*#__PURE__*/_createVNode("span", null, "monday", -1 /* HOISTED */)
const _hoisted_3 = /*#__PURE__*/_createVNode("span", null, "monday", -1 /* HOISTED */)
const _hoisted_4 = /*#__PURE__*/_createVNode("span", null, "monday", -1 /* HOISTED */)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock("div", _hoisted_1, [_hoisted_2,_hoisted_3,_hoisted_4,_createVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)]))
}// Check the console for the AST

通过以上代码可以发现, vue3 在每一个静态节点的外部都定义了父节点。这样看好像更冗余了一点,原因在于现在节点还比较少。


下面我们来演示更多的节点,此时右边的 options 选择 hoistStatic我们在左边框输入以下代码:

<div id="app"><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>{{msg}}</span>
</div>

此时右边的框显示如下:

import { createVNode as _createVNode, toDisplayString as _toDisplayString, createStaticVNode as _createStaticVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"const _hoisted_1 = { id: "app" }
const _hoisted_2 = /*#__PURE__*/_createStaticVNode("<span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span><span>monday</span>", 10)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock("div", _hoisted_1, [_hoisted_2,_createVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)]))
}// Check the console for the AST

此时可以看到, vue3 把所有的静态节点都包围成一个父节点了,就好像 vue3 跟它的甲方爸爸说,要不这样吧,我帮你做一个静态节点的集合,帮你把所有内容都定义到一起。

4、cacheHandler

(1)什么是cacheHandler

  • cacheHandler ,指缓存事件的意思。

(2)举个例子🌰

我们同样用在线网站来做一个演示,此时右边的 options 选择 cacheHandler我们在左边框输入以下代码:

<div id="app"><span @click="clickHandler">monday</span>
</div>

此时右边的框显示如下:

import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock("div", { id: "app" }, [_createVNode("span", {onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.clickHandler && _ctx.clickHandler(...args)))}, " monday ")]))
}// Check the console for the AST

观察代码 onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.clickHandler && _ctx.clickHandler(...args))) 可以发现, vue3 在处理点击事件时,会进行缓存。这行代码的意思就是,当有 _cache[1] 的值时就取 _cache[1] ,如果没有 _cache[1] 就再给 _cache[1] 定义一个函数。

5、SSR优化

(1)什么是SSR优化

  • 静态节点会直接进行输出,绕过了 vdom
  • 如果是动态节点,还是需要进行动态渲染

(2)举个例子🌰

我们同样用在线网站来做一个演示,此时右边的 options 选择 SSR我们在左边框输入以下代码:

<div id="app"><span @click="clickHandler">monday</span>
</div>

此时右边的框显示如下:

import { mergeProps as _mergeProps } from "vue"
import { ssrRenderAttrs as _ssrRenderAttrs, ssrInterpolate as _ssrInterpolate } from "@vue/server-renderer"export function ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) {const _cssVars = { style: { color: _ctx.color }}_push(`<div${_ssrRenderAttrs(_mergeProps({ id: "app" }, _attrs, _cssVars))}><span>monday</span><span>monday</span><span>monday</span><span>${_ssrInterpolate(_ctx.msg)}</span></div>`)
}// Check the console for the AST

通过以上代码可以发现,用 SSR 来进行模板编译时,静态节点会直接进行输出,直接绕过 vdom 。而如果是动态节点时,依然需要进行动态渲染。

6、tree-shaking

(1)什么是tree-shaking

  • 编译时,根据不同的情况,引入不同的 API

(2)举个例子🌰

同样用在线网站来做一个演示,此时右边的 options 不做选择。左边框输入以下代码:

<div id="app"><span>monday</span><span>monday</span><span>monday</span><span>{{msg}}</span>
</div>

此时右边的框的第一行显示如下:

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

再来演示另外一种情况。同样我们在左边框输入以下代码:

<div id="app"><span :id="msg"></span><input v-model="msg">
</div>

此时右边的框的第一行显示如下:

import { createVNode as _createVNode, vModelText as _vModelText, withDirectives as _withDirectives, openBlock as _openBlock, createBlock as _createBlock } from "vue"

大家可以发现, vue3 在编译时,它不会一次性引入很多 API ,而是根据我们所需要的,我们要什么它就引入什么,我们不要的,它一概不会帮我们引入。这在某种程度上就优化了很多性能。

四、📚Vite为什么启动非常快

第一次看见 vite 是在 vue3 的官方文档里面,官方文档介绍: vite 是一个 web 开发构建工具,由于其使用 原生ES模块 导入方式,可以实现闪电般冷服务器启动。通过在终端中运行相应的命令,可以使用Vite快速构建 Vue 项目。

1、Vite是什么

  • vite 是一个前端的打包工具,是 vue 作者发起的一个项目;
  • vite 借助 vue 的影响力,发展较快,和 webpack 有着一定的竞争关系;
  • 优势: vite 使得程序在开发环境下无需打包,且启动非常快速。

2、Vite为何启动快?

在开发环境下使用 ES6 Module ,无需打包,速度非常快;

在生产环境下使用 rollup 打包,并不会快很多。

3、ES Module演示

(1)基本使用

vue2 时,我们加载一个工程文件需要先转为 ES5 ,然后经过一些列的打包才能正式加载项目页面。而在 vue3 ,生产环境目前还没有做到,但是在开发环境下,通过 ES6 Module 的方式,无需打包,速度非常快。

下面我们讲演示集中 ES Module 在浏览器中的应用。

(2)ES Module在浏览器中的应用

1)基本演示

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ES Module demo</title>
</head>
<body><p>基本演示</p><script type="module">import plus from './src/plus.js'const res = add(1, 2)console.log('add res', res)</script><script type="module">import { plus, multi } from './src/math.js'</script>
</body>
</html>

我们在 <script> 标签下设置 type="module" ,之后就可以按照我们平常写 vue 程序一样,用 import 引入相应的文件。

2)引入外链

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ES Module demo</title>
</head>
<body><p>外链</p><script type="module" src="./src/index.js"></script>
</body>
</html>

同时,也可以通过 src 的方式直接引入外部js文件。

3)远程引用

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ES Module demo</title>
</head>
<body><p>远程引用</p><script type="module">import { createStore } from 'https://unpkg.com/redux@latest/es/redux.mjs'console.log('createStore', createStore)</script>
</body>
</html>

也可以直接引入 cdn 上的网址,即远程引用

4)动态引入

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ES Module demo</title>
</head>
<body><p>动态引入</p><button id="btn1">load1</button><button id="btn2">load2</button><script type="module">document.getElementById('btn1').addEventListener('click', async () => {const add = await import('./src/add.js')const res = add.default(1, 2)console.log('add res', res)})document.getElementById('btn2').addEventListener('click', async () => {const { add, multi } = await import('./src/math.js')console.log('add res', add(10, 20))console.log('multi res', multi(10, 20))})</script>
</body>
</html>

比如说我们要给两个 button 绑定两个事件,并且要让他们引入两个不同的 js 文件,那我们可以在执行点击后,在箭头函数里面进行 import 操作,按需引入,即想要让它引入哪个再引入哪个。

五、📙全局API修改

讲完 vite ,我们再来将一个 vue3 的重大改变,那就是全局 API 的修改。具体看下方。

1、Vue2全局API

Vue2 中,全局API经常会遇到以下问题:

  • 单元测试中,全局配置非常容易污染全局环境
  • 在不同的 apps 中,共享一份有不同配置的 Vue 对象,也变得非常困难。

Vue2入口文件写法:

import Vue from 'vue'
import App from './App.vue'Vue.config.ignoredElements = [/^app-/]
Vue.use(/*...*/)
Vue.mixin(/*...*/)
Vue.component(/*...*/)
Vue.directive(/*...*/)Vue.prototype.customProperty = () = {}new Vue({render: h => h(App)
}).$mount('#app')

2、Vue3全局API

(1)Vue3新写法

因此, Vue3 为了解决 Vue2 的问题,推出了新的写法。具体代码如下:

Vue3的新写法:

import { createApp } from 'vue'
import App from './App.vue'const app = createApp(App)app.config.isCustomElement = tag =>
tag.startsWith('app-')
app.use(/*...*/)
app.mixin(/*...*/)
app.component(/*...*/)
app.directive(/*...*/)app.config.globalProperties.customProperty = () = {}app.mount('#app')

(2)常见配置更新

1)全局配置:Vue.config->app.config

  • config.productionTip被删除
  • config.ignoredElements改名为config.isCustomElement

2)全局注册类API

  • Vue.component -> app.component
  • Vue.directive -> app.directive

3)行为扩展类API

  • Vue.mixin -> app.mixin
  • Vue.use -> app.use

六、📮结束语

到这里,碎碎念一波!在学习过程中,要明白 watchwatchEffect 的不同之处,还要知道 setup 如何获取组件实例,这其中谈论的就是关于 this 的问题。

最后的最后,就是 Vue3 为什么比 Vue2 快,涉及到6个性能优化的方法,学有余力之余,尽量用在线网站演示一波。随之,紧跟着 vue3 的步伐, vite 也成为了很多开发人员在开发环境中使用的工具。还有就是,解决全局污染等各种问题, Vue3 对全局注册 API 做出的改变。

一波碎碎念结束, vue3 的进阶新特性讲解就结束啦!如有疑问或文章有误欢迎评论区留言或私信我交流~

  • 关注公众号 星期一研究室 ,第一时间关注学习干货,更多有趣的专栏待你解锁~
  • 如果这篇文章对你有用,记得 一键三连 再走哦~
  • 我们下期见!🥂🥂🥂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode349. 两个数组的交集(思路+详解)

一:题目 二:上码 class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {/**思路:本题我们采用的哈希表数据结构是unordered_set,没有用数组因为我们不确定给出的数组中数值的范围如果 强上会出现空间的大量…

高效掌握新技能的「树型思维」

大家好&#xff0c;我是Z哥。不知道你有没有过这样的困惑&#xff0c;想学习某项新技能&#xff0c;但是很容失败。比如&#xff0c;出于职业发展的考虑&#xff0c;想学习一门新的编程语言&#xff0c;或者想了解一个新的技术框架&#xff1b;又或者看了某些综艺节目后想玩一玩…

vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy

一文了解Vue3的响应式原理一、&#x1f7e9;回顾Object.defineProperty二、&#x1f7e8;Proxy基本使用三、&#x1f7e6;学习Proxy语法&#xff1a;Reflect四、&#x1f7e7;Vue3如何用Proxy实现响应式1、实现响应式2、Proxy总结&#xff08;1&#xff09;深度监听&#xff0c…

一名“企业定制化人才”的自诉:“我不愿意,但却无可奈何”

这是头哥侃码的第214篇原创几个月前&#xff0c;我曾在大智慧时期的一位同事跟我聊微信&#xff0c;说自己所在的公司这两年业务一直不温不火&#xff0c;而且从19年底就逐渐缩减技术人员。今年上半年又因为疫情的关系&#xff0c;公司干脆直接砍掉了剩余的三个技术部门&#x…

一文了解分而治之和动态规则算法在前端中的应用

一文了解分而治之和动态规则算法一、分而治之1、分而治之是什么&#xff1f;2、应用场景3、场景剖析&#xff1a;归并排序和快速排序二、动态规则1、动态规则是什么&#xff1f;2、应用场景3、场景剖析&#xff1a;斐波那契数列4、动态规则VS分而治之三、分而治之算法常见应用1…

leetcode1. 两数之和(两种方法)

一:题目 二:上码 1:方法一 class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> v;for(int i 0; i < nums.size() - 1; i) {for(int j i1; j < nums.size(); j) {if(nums[i] nums[j] target) {v.push_…

排坑 | Exceptionless 5.x 无法正常发送邮件

【问题解决】| 作者 / Edison Zhou这是恰童鞋骚年的第282篇原创内容你有碰到过通过docker部署Exceptionless无法发送邮件的问题吗&#xff1f;此解决办法适用于Exceptionless 5.x版本&#xff08;如果你不想升级6.x的话&#xff09;。1问题起因去年这个时候&#xff0c;得知Exc…

一文了解贪心算法和回溯算法在前端中的应用

一文了解贪心算法和回溯算法在前端中的应用一、贪心算法1、贪心算法是什么&#xff1f;2、应用场景3、场景剖析&#xff1a;零钱兑换二、回溯算法1、回溯算法是什么&#xff1f;2、什么问题适合选用回溯算法解决&#xff1f;2、应用场景3、场景剖析&#xff1a;全排列三、贪心算…

leetcode454. 四数相加 II(思路+详解)

一:题目 二:上码 class Solution { public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {/**思路:1.我们用map容器的key值存进去前两个数的和并记录其个数,然后在后面两个数…

ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用

一文了解集合和字典在前端中的应用一、&#x1f4dd;集合1、集合是什么&#xff1f;2、前端与集合&#xff1a;使用ES6中的Set3、用Set模拟并集、交集和差集&#xff08;1&#xff09;模拟并集运算&#xff08;2&#xff09;模拟交集运算&#xff08;3&#xff09;模拟差集运算…

leetcode383. 赎金信(两种做法)

一&#xff1a;题目 二:上码 1:第一种方法 class Solution { public:bool canConstruct(string ransomNote, string magazine) {unordered_map<char,int>m,m1;for(int j 0; j < magazine.size(); j) {m[magazine[j]];}for(int i 0; i < ransomNote.size(); i) …

使用BeetleX在Linux下部署.NET多站点服务

在windows下常用IIS来部署.NET的多站点服务&#xff0c;但在Linux下就没这么方便了&#xff1b;虽然可以使用一些代理服务器如nginx&#xff0c;jexus等来反代或部署应用&#xff0c;但nginx对.NET应用的托管就相对没这么方便了&#xff0c;jexus的确是个不错的服务应用;在这里…

模块化妙用!用vue3实现一个鼠标追踪器和异步加载组件

用vue3实现一个鼠标追踪器和异步加载组件一、&#x1f5b1;️鼠标追踪器1、功能实现2、给静态页面绑定功能二、⚙️异步加载组件1、功能实现2、给静态页面绑定功能3、用泛型改造异步组件功能三、&#x1f4da;结束语周一最近学完 vue3 新特性&#xff0c;就想着用 vue3 来捣鼓…

leetcode15. 三数之和(三指针)

一:题目 二:思路 1.这里的去重是指的是我们在遍历元素的时候&#xff0c;遇到相同的挨着的相同的元素的时候要跳过 2.对元素进行排序&#xff0c;为了后面的比较 3.我们用的是三个指针&#xff0c;第一个指针i指向第一个元素&#xff0c;第二个指针left指向第二个元素,第三个指…

vue3的传送门teleport究竟有多神奇?suspense发起异步请求有多简约?

一文讲解vue3的Teleport和Suspense一、&#x1f44b;用teleport实现打开模态框操作1、teleport是什么2、实现模态框功能&#xff08;1&#xff09;设置锚点&#xff08;2&#xff09;定义子组件&#xff08;3&#xff09;定义父组件二、&#x1f91a;用Suspense1、Suspense是什…

【BCVP】实现基于 Redis 的消息队列

聆听自己的声音如果自己学不动了&#xff0c;或者感觉没有动力的时候&#xff0c;看看书&#xff0c;听听音乐&#xff0c;跑跑步&#xff0c;休息两天&#xff0c;重新出发&#xff0c;偷懒虽好&#xff0c;可不要贪杯。话说上回书我们说到了&#xff0c;Redis的使用修改《【B…

leetcode18. 四数之和(双指针)

一&#xff1a;题目 二&#xff1a;上码 class Solution { public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int> >ans;vector<int> v;sort(nums.begin(),nums.end());for(int i 0; i < nums…

过去3个多月的1200个小时里,我收获了什么?| 2021年年中总结

&#x1f55b;序言 今年三月初&#xff0c;善后了上学期事情之后&#xff0c;我开始在想&#xff0c;我的未来规划。 身边的好朋友和同学都在筹划着自己的未来&#xff0c;考研的考研&#xff0c;考公的考公。父母和老师们也在劝我说考研&#xff0c;问我考不考研。 依稀记得…

WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面

WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面独立观察员 2020 年 9 月 3 日我们在使用 WPF 的 TextBox 作为消息展示框时&#xff0c;如果想在出现滚动条之后&#xff0c;新消息到来时还能够被看到&#xff0c;也就是说让滚动条始终在最下面&#xff0c;或者说光标…

leedcode344. 反转字符串

一:题目 二:上码 class Solution { public:void reverseString(vector<char>& s) {//双指针for(int i 0,j s.size() - 1; i < s.size()/2; i,j--) {swap(s[i],s[j]);}} };