返回顶部
首页 > 资讯 > 前端开发 > VUE >Vue 3.0 中怎么实现应用挂载
  • 310
分享到

Vue 3.0 中怎么实现应用挂载

2024-04-02 19:04:59 310人浏览 独家记忆
摘要

Vue 3.0 中怎么实现应用挂载,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、应用挂载在创建完 app 对象之后,就会调用 app.mo

Vue 3.0 中怎么实现应用挂载,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

一、应用挂载

在创建完 app 对象之后,就会调用 app.mount 方法执行应用挂载操作:

<div id="app"></div> <script>    const { createApp, h } = Vue    const app = createApp({ // ①      data() {        return {          name: '我是阿宝哥'        }      },      template: `<div>大家好, {{name}}!</div>`    })    app.mount('#app') // ② </script>

虽然 app.mount 方法用起来很简单,但它内部涉及的处理逻辑还是蛮复杂的。这里阿宝哥利用 Chrome 开发工具的 PerfORMance  标签栏,记录了应用挂载的主要过程:

Vue 3.0 中怎么实现应用挂载

接下来,阿宝哥就会以前面的示例为例,来详细分析一下应用挂载过程中涉及的主要函数。

1.1 app.mount

app.mount 被定义在 runtime-dom/src/index.ts 文件中,具体实现如下所示:

// packages/runtime-dom/src/index.ts app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {   const container = normalizeContainer(containerOrSelector) // ① 同时支持字符串和DOM对象   if (!container) return   const component = app._component   // 若根组件非函数对象且未设置render和template属性,则使用容器的innerhtml作为模板的内容   if (!isFunction(component) && !component.render && !component.template) { // ②     component.template = container.innerHTML   }   container.innerHTML = ''  // 在挂载前清空容器内容   const proxy = mount(container, false, container instanceof SVGElement) // ③   if (container instanceof Element) {     container.removeAttribute('v-cloak') // 避免在网络不好或加载数据过大的情况下,页面渲染的过程中会出现Mustache标签     container.setAttribute('data-v-app', '')   }   return proxy }

在 app.mount 方法内部主要分为以下 3 个流程:

  • 规范化容器,normalizeContainer 函数参数 container 的类型是一个联合类型:Element | ShadowRoot |  string,如果传入参数是字符串类型的话,会通过 document.querySelector api 来获取选择器对应的 DOM  元素。而对于其他类型的话,会直接返回传入的参数。

  • 设置根组件的 template 属性,当根组件不是函数组件且根组件配置对象上没有 render 和 template 属性,则会使用容器元素上  innerHTML 的值作为根组件 template 属性的属性值。

  • 调用 mount 方法执行真正的挂载操作。

1.2 mount

对于 app.mount 方法来说,最核心的流程是 mount 方法,所以下一步我们就来分析 mount 方法。

// packages/runtime-core/src/apiCreateApp.ts export function createAppAPI<HostElement>(   render: RootRenderFunction,   hydrate?: RootHydrateFunction ): CreateAppFunction<HostElement> {   return function createApp(rootComponent, rootProps = null) {     const app: App = (context.app = {       _container: null,       _context: context,      // 省略部分代码              mount(         rootContainer: HostElement,         isHydrate?: boolean,         isSVG?: boolean       ): any {         if (!isMounted) {           const vnode = createVNode( // ① 创建根组件对应的VNode对象             rootComponent as ConcreteComponent,             rootProps           )           vnode.appContext = context // ② 设置VNode对象上的应用上下文属性      // 省略部分代码           if (isHydrate && hydrate) {             hydrate(vnode as VNode<Node, Element>, rootContainer as any)           } else {              render(vnode, rootContainer, isSVG) // ③ 执行渲染操作           }           isMounted = true           app._container = rootContainer           ;(rootContainer as any).__vue_app__ = app           return vnode.component!.proxy         }       },     })      return app   } }

1.3 render

观察以上的 mount 函数可知,在 mount 方法内部会调用继续调用 render 函数执行渲染操作,该函数的具体实现如下:

const render: RootRenderFunction = (vnode, container) => {   if (vnode == null) {     if (container._vnode) {       unmount(container._vnode, null, null, true)     }   } else {       patch(container._vnode || null, vnode, container)   }   flushPostFlushCbs()   container._vnode = vnode }

对于首次渲染来说,此时的 vnode 不为 null(基于根组件创建的 VNode 对象),所以会执行 else 分支的流程,即调用 patch  函数。

1.4 patch

patch 函数被定义在 runtime-core/src/renderer.ts 文件中,该函数的签名如下所示:

// packages/runtime-core/src/renderer.ts const patch: PatchFn = (     n1, // old VNode     n2, // new VNode     container,     anchor = null,     parentComponent = null,     parentSuspense = null,     isSVG = false,     slotScopeIds = null,     optimized = false ) => { //...}

在 patch 函数内部,会根据 VNode 对象的类型执行不同的处理逻辑:

Vue 3.0 中怎么实现应用挂载

在上图中,我们看到了 Text、Comment 、Static 和 Fragment 这些类型,它们的定义如下:

// packages/runtime-core/src/vnode.ts export const Text = Symbol(__DEV__ ? 'Text' : undefined) export const Comment = Symbol(__DEV__ ? 'Comment' : undefined) export const Static = Symbol(__DEV__ ? 'Static' : undefined) export const Fragment = (Symbol(__DEV__ ? 'Fragment' : undefined) as any) as {   __isFragment: true   new (): {     $props: VNodeProps   } }

除了上述的类型之外,在 default 分支,我们还看到了 ShapeFlags,该对象是一个枚举:

// packages/shared/src/shapeFlags.ts export const enum ShapeFlags {   ELEMENT = 1,   FUNCTIONAL_COMPONENT = 1 << 1,   STATEFUL_COMPONENT = 1 << 2,   TEXT_CHILDREN = 1 << 3,   ARRAY_CHILDREN = 1 << 4,   SLOTS_CHILDREN = 1 << 5,   TELEPORT = 1 << 6,   SUSPENSE = 1 << 7,   COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,   COMPONENT_KEPT_ALIVE = 1 << 9,   COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT }

那么 ShapeFlags 标志是什么时候设置的呢?其实在创建 VNode 对象时,就会设置该对象的 shapeFlag  属性,对应的判断规则如下所示:

// packages/runtime-core/src/vnode.ts function _createVNode(   type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,   props: (Data & VNodeProps) | null = null,   children: unknown = null,   patchFlag: number = 0,   dynamicProps: string[] | null = null,   isBlockNode = false ): VNode {   // 省略大部分方法   const shapeFlag = isString(type)// 字符串类型     ? ShapeFlags.ELEMENT     : __FEATURE_SUSPENSE__ && isSuspense(type) // SUSPENSE类型       ? ShapeFlags.SUSPENSE       : isTeleport(type) // TELEPORT类型         ? ShapeFlags.TELEPORT         : isObject(type) // 对象类型           ? ShapeFlags.STATEFUL_COMPONENT           : isFunction(type) // 函数类型             ? ShapeFlags.FUNCTIONAL_COMPONENT             : 0    const vnode: VNode = {     __v_isVNode: true,     [ReactiveFlags.SKIP]: true,   // 省略大部分属性     shapeFlag,     appContext: null   }   normalizeChildren(vnode, children)   return vnode }

1.5 processComponent

由以上代码可知,对于我们示例来说,根组件对应的 VNode 对象上 shapeFlag 的值为  ShapeFlags.STATEFUL_COMPONENT。因此,在执行 patch 方法时,将会调用 processComponent 函数:

// packages/runtime-core/src/renderer.ts   const processComponent = (   n1: VNode | null,    n2: VNode,   container: RendererElement,   anchor: RendererNode | null,   parentComponent: ComponentInternalInstance | null,   parentSuspense: SuspenseBoundary | null,   isSVG: boolean, optimized: boolean   ) => {     if (n1 == null) { // 首次渲染       if (n2.shapeFlag & ShapeFlags.COMPONENT_KEPT_ALIVE) {         // 处理keep-alive组件       } else {         mountComponent(           n2, container, anchor,           parentComponent, parentSuspense,           isSVG, optimized         )       }     } else { // 更新操作       updateComponent(n1, n2, optimized)     } }

1.6 mountComponent

对于首次渲染的场景,n1 的值为 null,我们的组件又不是 keep-alive 组件,所以会调用 mountComponent 函数挂载组件:

// packages/runtime-core/src/renderer.ts   const mountComponent: MountComponentFn = (   initialVNode, container, anchor,    parentComponent, parentSuspense, isSVG, optimized ) => {     // 省略部分代码     // ① 创建组件实例     const instance: ComponentInternalInstance = (initialVNode.component = createComponentInstance(       initialVNode, parentComponent, parentSuspense     ))     // ② 初始化组件实例     setupComponent(instance)     // ③ 设置渲染副作用函数     setupRenderEffect(       instance, initialVNode, container,       anchor, parentSuspense, isSVG, optimized     ) }

在 mountComponent 函数内部,主要含有 3 个步骤:

  • 调用 createComponentInstance 函数创建组件实例;

  • 调用 setupComponent 函数初始化组件实例;

  • 调用 setupRenderEffect 函数,设置渲染副作用函数。

1.7 createComponentInstance

下面我们将会逐一分析上述的 3 个步骤:

// packages/runtime-core/src/component.ts export function createComponentInstance(   vnode: VNode,   parent: ComponentInternalInstance | null,   suspense: SuspenseBoundary | null ) {   const type = vnode.type as ConcreteComponent   // inherit parent app context - or - if root, adopt from root vnode   const appContext =     (parent ? parent.appContext : vnode.appContext) || emptyAppContext    const instance: ComponentInternalInstance = { // 创建组件实例     uid: uid++, vnode, type, parent, appContext,     root: null!, next: null, subTree: null!, update: null!,      render: null, proxy: null, exposed: null, withProxy: null, effects: null,     provides: parent ? parent.provides : Object.create(appContext.provides),     // ...    }      if (__DEV__) {     instance.ctx = createRenderContext(instance)   } else {     instance.ctx = { _: instance } // 设置实例上的上下文属性ctx   }   instance.root = parent ? parent.root : instance   instance.emit = emit.bind(null, instance) // 设置emit属性,用于派发自定义事件    return instance }

调用 createComponentInstance 函数后,会返回一个包含了多种属性的组件实例对象。

1.8 setupComponent

此外,在创建完组件实例后,会调用 setupComponent 函数执行组件初始化操作:

// packages/runtime-core/src/component.ts export function setupComponent(   instance: ComponentInternalInstance,   isSSR = false ) {   isInSSRComponentSetup = isSSR   const { props, children } = instance.vnode   const isStateful = isStatefulComponent(instance) // 判断是否状态组件   initProps(instance, props, isStateful, isSSR) // 初始化props属性   initSlots(instance, children) // 初始化slots    const setupResult = isStateful     ? setupStatefulComponent(instance, isSSR) // 初始化有状态组件     : undefined   isInSSRComponentSetup = false   return setupResult }

在 setupComponent 函数中,会分别调用 initProps 和 initSlots 函数来初始化组件实例的 props 属性和 slots  属性。之后会通过 isStatefulComponent 函数来判断组件的类型:

// packages/runtime-core/src/component.ts export function isStatefulComponent(instance: ComponentInternalInstance) {   return instance.vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT }  // 在createVNode函数内部,会根据组件的type类型设置ShapeFlags标识 const shapeFlag = isString(type)     ? ShapeFlags.ELEMENT     : __FEATURE_SUSPENSE__ && isSuspense(type)       ? ShapeFlags.SUSPENSE       : isTeleport(type)         ? ShapeFlags.TELEPORT         : isObject(type) // ComponentOptions 类型           ? ShapeFlags.STATEFUL_COMPONENT           : isFunction(type) // 函数式组件             ? ShapeFlags.FUNCTIONAL_COMPONENT             : 0

很明显,如果 type 是对象类型,则组件是有状态组件。而如果 type 是函数类型的话,则组件是函数组件。

1.9 setupStatefulComponent

对于有状态组件来说,还会继续调用 setupStatefulComponent 函数来初始化有状态组件:

// packages/runtime-core/src/component.ts function setupStatefulComponent(   instance: ComponentInternalInstance,   isSSR: boolean ) {   const Component = instance.type as ComponentOptions // 组件配置对象      // 0. create render proxy property access cache   instance.accessCache = Object.create(null)   // 1. create public instance / render proxy   // also mark it raw so it's never observed   instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers) // instance.ctx = { _: instance }   // 2. call setup()   const { setup } = Component // 组合式API中配置的setup函数   if (setup) {     // 处理组合式API的setup函数   } else {     finishComponentSetup(instance, isSSR)   } }

在 setupStatefulComponent 函数内部,主要也可以分为 3 个步骤:

  • 在组件实例上设置 accessCache 属性,即创建 render proxy 属性的访问缓存;

  • 使用 Proxy API 设置组件实例的 render proxy 属性;

  • 判断组件配置对象上是否设置了 setup 属性,如果当前组件配置对象不包含 setup 属性,则会走 else 分支,即调用  finishComponentSetup 函数。

接下来,我们来重点分析后面 2 个步骤。首先,我们先来分析 instance.proxy 属性。如果你对 Proxy API 不了解的话,可以看一下  你不知道的 Proxy 这篇文章。至于 proxy 属性有什么的作用,阿宝哥将在后续的文章中介绍。下面我们来回顾一下 Proxy 构造函数:

const p = new Proxy(target, handler)

Proxy 构造函数支持两个参数:

  • target:要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

  • handler:一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

对于 setupStatefulComponent 函数来说,target 参数指向的是组件实例 ctx 属性,即 { _: instance }  对象。而 handler 参数指向的是 PublicInstanceProxyHandlers 对象,该对象内部包含了 3 种类型的捕捉器:

// vue-next/packages/runtime-core/src/componentPublicInstance.ts export const PublicInstanceProxyHandlers: ProxyHandler<any> = {   // 属性读取操作的捕捉器。   get({ _: instance }: ComponentRenderContext, key: string) {     // ...   },   // 属性设置操作的捕捉器。   set(     { _: instance }: ComponentRenderContext,     key: string,     value: any   ): boolean {     // ...   },   // in 操作符的捕捉器。   has(     {       _: { data, setupState, accessCache, ctx, appContext, propsOptions }     }: ComponentRenderContext,     key: string   ) {    // ...   } }

这里我们只要先知道 PublicInstanceProxyHandlers 对象中,包含了 get、set 和 has 这 3  种类型的捕捉器即可。至于捕捉器的内部处理逻辑,阿宝哥将在 Vue 3.0 进阶之应用挂载的过程下篇 中详细介绍。

1.10 finishComponentSetup

在设置好 instance.proxy 属性之后,会判断组件配置对象上是否设置了 setup 属性。对于前面的示例来说,会走 else 分支,即调用  finishComponentSetup 函数,该函数的具体实现如下:

// packages/runtime-core/src/component.ts function finishComponentSetup(   instance: ComponentInternalInstance,   isSSR: boolean ) {   const Component = instance.type as ComponentOptions   // template / render function normalization   if (__NODE_js__ && isSSR) { // 服务端渲染的场景     if (Component.render) {       instance.render = Component.render as InternalRenderFunction     }   } else if (!instance.render) { // 组件实例中不包含render方法     // could be set from setup()     if (compile && Component.template && !Component.render) {       // 编译组件的模板生成渲染函数       Component.render = compile(Component.template, {         isCustomElement: instance.appContext.config.isCustomElement,         delimiters: Component.delimiters       })     }     // 把渲染函数添加到instance实例的render属性中     instance.render = (Component.render || NOOP) as InternalRenderFunction     // for runtime-compiled render functions using `with` blocks, the render     // proxy used needs a different `has` handler which is more performant and     // also only allows a whitelist of globals to fallthrough.     if (instance.render._rc) {       instance.withProxy = new Proxy(         instance.ctx,         RuntimeCompiledPublicInstanceProxyHandlers       )     }   } }

在分析 finishComponentSetup 函数前,我们来回顾一下示例中的代码:

const app = createApp({   data() {     return {       name: '我是阿宝哥'     }   },   template: `<div>大家好, {{name}}!</div>` })

对于该示例而言,根组件配置对象并没有设置 render 属性。而且阿宝哥引入的是包含编译器的 vue.global.js 文件,所以会走 else if  分支。即会调用 compile 函数来对模板进行编译。那么编译后会生成什么呢?通过断点,我们可以轻易地看到模板编译后生成的渲染函数:

(function anonymous() { const _Vue = Vue  return function render(_ctx, _cache) {   with (_ctx) {     const { toDisplayString: _toDisplayString, createVNode: _createVNode,        openBlock: _openBlock, createBlock: _createBlock } = _Vue     return (_openBlock(), _createBlock("div", null, "大家好, " + _toDisplayString(name) + "!", 1))   } } })

观察以上的代码可知,调用渲染函数之后会返回 createBlock 函数的调用结果,即 VNode 对象。另外,在 render 函数中,会通过 with  来设置渲染上下文。那么该渲染函数什么时候会被调用呢?对于这个问题,感兴趣的小伙伴可以先自行研究一下。

出于篇幅考虑,阿宝哥把应用挂载的过程分为上下两篇,在下一篇文章中阿宝哥将重点介绍 setupRenderEffect  函数。介绍完该函数之后,你将会知道渲染函数什么时候会被调用,到时候也会涉及响应式 API 的一些相关知识,对这部分内容还不熟悉的小伙伴可以先看看 Vue 3  的官方文档。

最后,阿宝哥用一张流程图来总结一下本文介绍的主要内容:

Vue 3.0 中怎么实现应用挂载

看完上述内容,你们掌握Vue 3.0 中怎么实现应用挂载的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网VUE频道,感谢各位的阅读!

--结束END--

本文标题: Vue 3.0 中怎么实现应用挂载

本文链接: https://lsjlt.com/news/74625.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Vue 3.0 中怎么实现应用挂载
    Vue 3.0 中怎么实现应用挂载,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、应用挂载在创建完 app 对象之后,就会调用 app.mo...
    99+
    2024-04-02
  • Vue 3.0 中怎么实现双向绑定
    本篇文章为大家展示了Vue 3.0 中怎么实现双向绑定,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。双向绑定由两个单向绑定组成:模型 &mdash;>...
    99+
    2024-04-02
  • Vue 3.0中怎么实现依赖注入
    这篇文章将为大家详细讲解有关Vue 3.0中怎么实现依赖注入,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。使用过 Angular 的小伙伴对 依赖注入 应该...
    99+
    2024-04-02
  • vue-cli@3.0怎么用
    小编给大家分享一下vue-cli@3.0怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!(一)安装:1、下载安装node: ...
    99+
    2024-04-02
  • Ubuntu中怎么实现永久挂载分区
    本篇文章为大家展示了Ubuntu中怎么实现永久挂载分区,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。安装Ubuntu的时/和/home都是单独挂载的,但是还有一个43GB的ext4分区当时没有设置挂...
    99+
    2023-06-13
  • Vue+Typescript中在Vue上挂载axios使用时报错怎么办
    这篇文章将为大家详细讲解有关Vue+Typescript中在Vue上挂载axios使用时报错怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在vue项目开发过程中,为...
    99+
    2024-04-02
  • 怎么理解Vue 3.0的响应式系统
    这篇文章主要介绍“怎么理解Vue 3.0的响应式系统”,在日常操作中,相信很多人在怎么理解Vue 3.0的响应式系统问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解Vu...
    99+
    2024-04-02
  • Vue中怎么实现按需加载
    本篇文章给大家分享的是有关Vue中怎么实现按需加载,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。概念(懒加载)当打包构建应用时,JavaScr...
    99+
    2024-04-02
  • Vue实例挂载的方法是什么
    这篇文章主要介绍“Vue实例挂载的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue实例挂载的方法是什么”文章能帮助大家解决问题。一、思考我们都听过知其然知其所以然这句话。那么不知道大家...
    99+
    2023-06-26
  • docker动态挂载目录怎么实现
    在Docker中实现动态挂载目录有两种常用的方法: 使用`-v`参数进行挂载:可以在运行容器时通过`-v`参数指定要挂载的目录。例...
    99+
    2023-10-26
    docker
  • vue实现自定义组件挂载原型上
    目录自定义组件挂载原型上以elementUI二次分装dialog举例在原型上挂载方法和组件挂在方法,在main.js中挂载组件自定义组件挂载原型上 以elementUI二次分装dia...
    99+
    2022-11-13
    vue自定义组件 vue挂载原型 vue组件挂载原型上
  • vue中怎么利用echarts3.0实现自适应
    vue中怎么利用echarts3.0实现自适应,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。第一种:浏览器自适应通过:在myChart.set...
    99+
    2024-04-02
  • vue中的按需加载怎么实现
    这篇“vue中的按需加载怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vue中的按...
    99+
    2024-04-02
  • openSUSE挂载分区和实例应用是怎样的
    openSUSE挂载分区和实例应用是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。本HOWTO以一个实例一步步描述了使用 iso 镜像安装openSUSE...
    99+
    2023-06-16
  • vue全局挂载如何实现APP全局弹窗
    本篇内容主要讲解“vue全局挂载如何实现APP全局弹窗”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue全局挂载如何实现APP全局弹窗”吧!需求背景app端对接网页端的客服系统,在用户实现网页...
    99+
    2023-06-30
  • VUE中怎么实现路由动态加载
    VUE中怎么实现路由动态加载,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。首先新建vue工程,一般我们不会特殊处理路由,但当项目页面越来越多,...
    99+
    2024-04-02
  • 前端vue中怎么实现文件下载
    这篇文章主要介绍了前端vue中怎么实现文件下载的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇前端vue中怎么实现文件下载文章都会有所收获,下面我们一起来看看吧。第一种方式 前端创建超链接,通过a标签向...
    99+
    2023-07-06
  • vue怎么实现单页面应用
    本篇内容介绍了“vue怎么实现单页面应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一:npm的安装由于新版的node.js已经集成了np...
    99+
    2023-07-04
  • 怎么在fedora系统中实现自动挂载windows分区
    这篇文章给大家介绍怎么在fedora系统中实现自动挂载windows分区,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。终端阿输入su,提示输入超级帐户密码,输入你的系统安装时的密码查看硬盘分区情况,输入fdisk -l...
    99+
    2023-06-07
  • CentOS6.5怎么实现开机自动挂载硬盘
    本篇内容介绍了“CentOS6.5怎么实现开机自动挂载硬盘 ”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!  1、手动挂载磁盘  查看磁盘分...
    99+
    2023-06-10
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作