精华内容
下载资源
问答
  • 主要给大家介绍了关于vue组件化中slot的基本使用方法,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • Vue 组件化

    千次阅读 2019-09-06 17:01:53
    回忆 ...h(app),new Vue()实例初始init()和原来一样。$mount执行到第一个$mount,判断有无render函数,没有就生成render函数,这里我们是有的。执行第二个$mount,调用mountComponent,到了v...

    文章转自: https://www.jianshu.com/p/b7535850cddc

     

    回忆

            首先,render函数中手写h=>h(app),new Vue()实例初始化init()和原来一样。$mount执行到第一个$mount,判断有无render函数,没有就生成render函数,这里我们是有的。执行第二个$mount,调用mountComponent,到了vm._update(vm._render(), hydrating)。

            下面正式开始组件处理,先是vm._render()生成组件vnode.这个过程主要做了三件事,1、创建组件构造函数(继承于Vue)。2、安装组件钩子函数(在patch流程中触发)。3、组件vnode实例化

            其中细节,vm._render()会调用vm.$createElement. 其中会判断参数tag,若是普通html标签则实例化一个普通vnode节点,否则调用creatComponent创建组件vnode。1、通过Vue.extend得到一个继承于Vue的组件构造器(组件实例化时会执行_init())。2、遍历组件钩子函数(componentVNodeHooks中),若vnode相关data(即vNodeData)中当前hook存在,把组件hook,merge到当前hook上,不然直接赋值。3、通过new VNode()生成组件vnode并返回。

            我们通过 createComponent 创建了组件 VNode,接下来会走到 vm._update,执行 vm.__patch__ 去把 VNode 转换成真正的 DOM 节点。patch 的过程会调用 createElm 创建元素节点,而createElm中会判断 createComponent,true的话直接返回,只执行createComponent中逻辑。createComponent中会判断是否是组件vnode,是的话 先执行init(vnode,hydrating)

            init(vnode,hydrating),通过 createComponentInstanceForVnode(vnode, activeInstance)创建一个 继承于Vue 的实例,然后调用 $mount 方法挂载子组件。

            createComponentInstanceForVnode(vnode, activeInstance)执行new vnode.componentOptions.Ctor(options)(这里的 vnode.componentOptions.Ctor 对应的就是继承于 Vue的子组件的构造函数)。其中options参数,_isComponent 为 true 表示它是一个组件,_parentVnode(new Vue的vnode,其实为$el挂载点的vnode。如果为子组件,为子组件在父组件中的占位符),parent(activeInstance) 表示当前激活的组件实例(即new Vue实例,我们现在 在处理的是new Vue实例中render中的app对象)(注意,这里比较有意思的是如何拿到组件实例,后面会介绍。所以子组件的实例化实际上就是在这个时机执行的,并且它会执行实例的 _init 方法(在extend时定义的)。

           _init(),和new Vue初始化时有些不同,这里首先是合并 options 的过程有变化,_isComponent 为 true,所以走到了 initInternalComponent 过程。

            initInternalComponent(), opt即是当前组件app实例的vm.$options。这个过程我们重点记住以下几个点即可:opts.parent = options.parent、opts._parentVnode = parentVnode。它们其实是把之前我们通过 createComponentInstanceForVnode 函数传入的几个参数(vnode,activeInstance)合并到内部的选项 $options 里了。

            _init()最后会执行$mount,由于组件初始化的时候是不传 el 的,因此组件是自己接管了 $mount 的过程,这个过程的主要流程在上一章介绍过了。回到组件 init 的过程,componentVNodeHooks 的 init 钩子函数,在完成实例化的 _init 后,接着会执行 child.$mount(hydrating ? vnode.elm : undefined, hydrating)。这里 hydrating 为 true 一般是服务端渲染的情况,我们只考虑客户端渲染,所以这里 $mount 相当于执行 child.$mount(undefined, false),它最终会调用 mountComponent 方法,进而执行 vm._render() 方法。

           vm._render() 中取到了vm.$options的render和_parentVnode(new Vue的vnode,其实为$el挂载点的vnode),把_parentVnode赋值给vm.$vnode(当前vm实例是app组件实例),通过vm.$creatElement取得组件的vnode(这个app组件的vnode)。通过vnode.parent=_parentVnode建立父子关系

           我们知道在执行完 vm._render 生成 VNode 后,接下来就要执行 vm._update 去渲染 VNode 了

            _update() 过程中有几个关键的代码,首先 vm._vnode = vnode 的逻辑,这个 vnode 是通过 vm._render() 返回的组件渲染 VNode,vm._vnode(组件app实际渲染vnode) 和 vm.$vnode(new Vue的vnode,其实为$el挂载点的vnode) 的关系就是一种父子关系,用代码表达就是 vm._vnode.parent === vm.$vnode。另外,_update()中这个 activeInstance(vm) 作用就是保持当前上下文的 Vue 实例(在处理app组件时,它是new Vue实例,在处理app组件进行_update时它又赋值成当前app组件, 若下面又有组件,把它作为parent传下去),它是在 lifecycle 模块的全局变量( export let activeInstance: any = null),并且在之前我们调用 createComponentInstanceForVnode 方法的时候从 lifecycle 模块获取,并且作为参数parent传入的。因为实际上 JavaScript 是一个单线程,Vue 整个初始化是一个深度遍历的过程,在实例化子组件的过程中,它需要知道当前上下文的 Vue 实例是什么,并把它作为子组件的父 Vue 实例。之前我们提到过对子组件的实例化过程先会调用 initInternalComponent(vm, options) 合并 options,把 parent 存储在 vm.$options 中,在 _init()中会调用 initLifecycle(vm) 

             initLifecycle(vm)中可以看到 vm.$parent 就是用来保留当前 vm 的父实例,并且通过 parent.$children.push(vm) 来把当前的 vm 存储到父实例的 $children 中。

            在 vm._update 的过程中,把当前的 vm 赋值给 activeInstance,同时通过 const prevActiveInstance=activeInstance用 prevActiveInstance 保留上一次的 activeInstance。实际上,prevActiveInstance 和当前的 vm 是一个父子关系,当一个 vm 实例完成它的所有子树的 patch 或者 update 过程后,activeInstance 会回到它的父实例,这样就完美地保证了 createComponentInstanceForVnode 整个深度遍历过程中,我们在实例化子组件的时候能传入当前子组件的父 Vue 实例,并在 _init 的过程中,通过 vm.$parent 把这个父子关系保留.

            那么回到 _update,最后就是调用 __patch__ 渲染 VNode 了。这里又回到了本节开始的过程,之前分析过负责渲染成 DOM 的函数是 createElm(),注意这里我们只传了 2 个参数,所以对应的 parentElm 是 undefined。

            createElm(),这里我们传入的 vnode 是组件渲染的 vnode,也就是我们之前说的 vm._vnode,如果组件的根节点是个普通元素,那么 vm._vnode 也是普通的 vnode,这里 createComponent(vnode, insertedVnodeQueue, parentElm, refElm) 的返回值是 false。       

            接下来的过程就和我们上一章一样了,先创建一个父节点占位符,然后再遍历所有子 VNode 递归调用 createElm,在遍历的过程中,如果遇到子 VNode 是一个组件的 VNode,则重复本节开始的过程,这样通过一个递归的方式就可以完整地构建了整个组件树。

            由于我们这个时候传入的 parentElm 是空,所以对组件的插入,在 createComponent 中,在完成组件的整个 patch 过程后,最后执行 insert(parentElm, vnode.elm, refElm) 完成组件的 DOM 插入,如果组件 patch 过程中又创建了子组件,那么DOM 的插入顺序是先子后父

    概述:

            Vue.js 另一个核心思想是组件化。所谓组件化,就是把页面拆分成多个组件 (component),每个组件依赖的 CSS、JavaScript、模板、图片等资源放在一起开发和维护。组件是资源独立的,组件在系统内部可复用,组件和组件之间可以嵌套。

            我们在用 Vue.js 开发实际项目的时候,就是像搭积木一样,编写一堆组件拼装生成页面。在 Vue.js 的官网中,也是花了大篇幅来介绍什么是组件,如何编写组件以及组件拥有的属性和特性。

            在这一章节,我们将从源码的角度来分析 Vue 的组件内部是如何工作的,只有了解了内部的工作原理,才能让我们使用它的时候更加得心应手。

            接下来我们会用 Vue-cli 初始化的代码为例,来分析一下 Vue 组件初始化的一个过程。

    vue-cli初始化代码

            这段代码相信很多同学都很熟悉,它也是通过 render 函数去渲染的,不同的这次通过 createElement 传的参数是一个组件而不是一个原生的标签,那么接下来我们就开始分析这一过程。

    createComponent

            首先生成vnode ,会先执行render函数,render对于自己写render函数的会执行vm.$createElement ,而它最终会调用 _createElement 方法,其中有一段逻辑是对参数 tag 的判断,如果是一个普通的 html 标签,像上一章的例子那样是一个普通的 div,则会实例化一个普通 VNode 节点,否则通过 createComponent 方法创建一个组件 VNode

     createElement 

            在组件render函数中传入的是一个 App 对象,它本质上是一个 Component 类型,那么它会走到上述代码的 else 逻辑,直接通过 createComponent 方法来创建 vnode。所以接下来我们来看一下 createComponent 方法的实现,它定义在 src/core/vdom/create-component.js 文件中:

            createComponent 的逻辑也会有一些复杂,但是分析源码比较推荐的是只分析核心流程,分支流程可以之后针对性的看,所以这里针对组件渲染这个 case 主要就 3 个关键步骤:构造子类构造函数,安装组件钩子函数和实例化 vnode

    构造子类构造函数

    构造子类构造函数

            我们在编写一个组件的时候,通常都是创建一个普通对象,还是以我们的 App.vue 为例,代码如下:

    例子

            这里 export 的是一个对象,所以 createComponent 里的代码逻辑会执行到 baseCtor.extend(Ctor),在这里 baseCtor 实际上就是 Vue,这个的定义是在最开始初始化 Vue 的阶段,在 src/core/global-api/index.js 中的 initGlobalAPI 函数有这么一段逻辑:

    baseCtor 实际上就是 Vue

            这里定义的是 Vue.option,而我们的 createComponent 取的是 context.$options,实际上在 src/core/instance/init.js 里 Vue 原型上的 _init 函数中有这么一段逻辑:

     Vue 上的一些 option 扩展到了 vm.$option 

            这样就把 Vue 上的一些 option 扩展到了 vm.$option 上,所以我们也就能通过 vm.$options._base 拿到 Vue 这个构造函数了。mergeOptions 的实现我们会在后续章节中具体分析,现在只需要理解它的功能是把 Vue 构造函数的 options 和用户传入的 options 做一层合并,到 vm.$options 上。

            在了解了 baseCtor 指向了 Vue 之后,我们来看一下 Vue.extend 函数的定义,在 src/core/global-api/extend.js 中。

    extend

            Vue.extend 的作用就是构造一个 Vue 的子类,它使用一种非常经典的原型继承的方式把一个纯对象转换一个继承于 Vue 的构造器 Sub 并返回,然后对 Sub 这个对象本身扩展了一些属性,如扩展 options、添加全局 API 等;并且对配置中的 props 和 computed 做了初始化工作;最后对于这个 Sub 构造函数做了缓存,避免多次执行 Vue.extend 的时候对同一个子组件重复构造。

            这样当我们去实例化 Sub 的时候,就会执行 this._init 逻辑再次走到了 Vue 实例的初始化逻辑,实例化子组件的逻辑在之后的章节会介绍。

    在extend中定义,实例化sub时会执行this._init

    安装组件钩子函数

            我们之前提到 Vue.js 使用的 Virtual DOM 参考的是开源库 snabbdom,它的一个特点是在VNode 的 patch 流程中对外暴露了各种时机的钩子函数方便我们做一些额外的事情,Vue.js 也是充分利用这一点,在初始化一个 Component 类型的 VNode 的过程中实现了几个钩子函数:

    安装组件钩子

    componentVNodeHooks 的钩子函数

    安装过程

            整个 mergeHooks 的过程就是把 componentVNodeHooks 的钩子函数合并到 data.hook 中,在 VNode 执行 patch 的过程中执行相关的钩子函数,具体的执行我们稍后在介绍 patch 过程中会详细介绍。这里要注意的是合并策略,在合并过程中,如果某个时机的钩子已经存在 data.hook 中,那么通过执行 mergeHook 函数做合并,这个逻辑很简单,就是在最终执行的时候,依次执行这两个钩子函数即可。

    实例化 VNode

    通过 new VNode 实例化一个 vnode 并返回

            最后一步非常简单,通过 new VNode 实例化一个 vnode 并返回。需要注意的是和普通元素节点的 vnode 不同,组件的 vnode 是没有 children 的,这点很关键,在之后的 patch 过程中我们会再提。

    patch

            当我们通过 createComponent 创建了组件 VNode,接下来会走到 vm._update,执行 vm.__patch__ 去把 VNode 转换成真正的 DOM 节点。这个过程我们在前一章已经分析过了,但是针对一个普通的 VNode 节点,接下来我们来看看组件的 VNode 会有哪些不一样的地方。

            patch 的过程会调用 createElm 创建元素节点,回顾一下 createElm 的实现,它的定义在 src/core/vdom/patch.js 中:

    createElm

            我们删掉多余的代码,只保留关键的逻辑,这里会判断 createComponent(vnode, insertedVnodeQueue, parentElm, refElm) 的返回值,如果为 true 则直接结束,那么接下来看一下 createComponent 方法的实现:

    createComponent

    createComponent

    首先对 vnode.data 做了一些判断:

    createComponent首先对 vnode.data 做了一些判断

            如果 vnode 是一个组件 VNode,那么条件会满足,并且得到 i 就是 init 钩子函数,回顾上节我们在创建组件 VNode 的时候合并钩子函数中就包含 init 钩子函数,定义在 src/core/vdom/create-component.js 中:

     init 钩子函数

            init 钩子函数执行也很简单,我们先不考虑 keepAlive 的情况,它是通过 createComponentInstanceForVnode 创建一个 继承于Vue 的实例,然后调用 $mount 方法挂载子组件,先来看一下 createComponentInstanceForVnode 的实现:

     createComponentInstanceForVnode 

            createComponentInstanceForVnode 函数构造的一个内部组件的参数,然后执行 new vnode.componentOptions.Ctor(options)。这里的 vnode.componentOptions.Ctor 对应的就是子组件的构造函数,我们上一节分析了它实际上是继承于 Vue 的一个构造器 Sub,相当于 new Sub(options) 这里有几个关键参数要注意几个点,_isComponent 为 true 表示它是一个组件,parent(activeInstance) 表示当前激活的组件实例(即new Vue实例,我们现在 在处理的是new Vue实例中render中的app对象)(注意,这里比较有意思的是如何拿到组件实例,后面会介绍。

            所以子组件的实例化实际上就是在这个时机执行的,并且它会执行实例的 _init 方法(在extend时定义的),这个过程有一些和之前不同的地方需要挑出来说,代码在 src/core/instance/init.js 中:

    组件实例初始化执行_init.js

            这里首先是合并 options 的过程有变化,_isComponent 为 true,所以走到了 initInternalComponent 过程,这个函数的实现也简单看一下:

    initInternalComponent

            opt即是当前处理实例app的vm.$options。这个过程我们重点记住以下几个点即可:opts.parent = options.parent、opts._parentVnode = parentVnode,它们是把之前我们通过 createComponentInstanceForVnode 函数传入的几个参数(vnode,activeInstance)合并到内部的选项 $options 里了。

            _init最后会进行挂载。

    _init挂载

            由于组件初始化的时候是不传 el 的,因此组件是自己接管了 $mount 的过程,这个过程的主要流程在上一章介绍过了,回到组件 init 的过程,componentVNodeHooks 的 init 钩子函数,在完成实例化的 _init 后,接着会执行 child.$mount(hydrating ? vnode.elm : undefined, hydrating)。这里 hydrating 为 true 一般是服务端渲染的情况,我们只考虑客户端渲染,所以这里 $mount 相当于执行 child.$mount(undefined, false),它最终会调用 mountComponent 方法,进而执行 vm._render() 方法

    执行 child.$mount,最终会调用 mountComponent 方法,进而执行 vm._render() 方法

    取到了vm.$options的render和_parentVnode,把_parentVnode赋值给vm.$vnode,通过vm.$creatElement取得组件的vnode。通过vnode.parent=_parentVnode建立父子关系

            我们知道在执行完 vm._render 生成 VNode 后,接下来就要执行 vm._update 去渲染 VNode 了。来看一下组件渲染的过程中有哪些需要注意的,vm._update的定义在 src/core/instance/lifecycle.js 中:

    _update

            _update 过程中有几个关键的代码,首先 vm._vnode = vnode 的逻辑,这个 vnode 是通过 vm._render() 返回的组件渲染 VNode,vm._vnode 和 vm.$vnode 的关系就是一种父子关系,用代码表达就是 vm._vnode.parent === vm.$vnode。还有一段比较有意思的代码:

    _update中的activeInstance即为父实例

            这个 activeInstance 作用就是保持当前上下文的 Vue 实例,它是在 lifecycle 模块的全局变量,定义是 export let activeInstance: any = null,并且在之前我们调用 createComponentInstanceForVnode 方法的时候从 lifecycle 模块获取,并且作为参数传入的。因为实际上 JavaScript 是一个单线程,Vue 整个初始化是一个深度遍历的过程,在实例化子组件的过程中,它需要知道当前上下文的 Vue 实例是什么,并把它作为子组件的父 Vue 实例。之前我们提到过对子组件的实例化过程先会调用 initInternalComponent(vm, options) 合并 options,把 parent 存储在 vm.$options 中,在 $mount 之前会调用 initLifecycle(vm) 方法:

    initLifecycle

            可以看到 vm.$parent 就是用来保留当前 vm 的父实例,并且通过 parent.$children.push(vm) 来把当前的 vm 存储到父实例的 $children 中。

            在 vm._update 的过程中,把当前的 vm 赋值给 activeInstance,同时通过 const prevActiveInstance=activeInstance 用 prevActiveInstance 保留上一次的 activeInstance。实际上,prevActiveInstance 和当前的 vm 是一个父子关系,当一个 vm 实例完成它的所有子树的 patch 或者 update 过程后,activeInstance 会回到它的父实例,这样就完美地保证了 createComponentInstanceForVnode 整个深度遍历过程中,我们在实例化子组件的时候能传入当前子组件的父 Vue 实例,并在 _init 的过程中,通过 vm.$parent 把这个父子关系保留.

    那么回到 _update,最后就是调用 __patch__ 渲染 VNode 了。

    这里又回到了本节开始的过程,之前分析过负责渲染成 DOM 的函数是 createElm,注意这里我们只传了 2 个参数,所以对应的 parentElm 是 undefined。

    我们再来看看它的定义:

    回顾creatElm

            注意,这里我们传入的 vnode 是组件渲染的 vnode,也就是我们之前说的 vm._vnode,如果组件的根节点是个普通元素,那么 vm._vnode 也是普通的 vnode,这里 createComponent(vnode, insertedVnodeQueue, parentElm, refElm) 的返回值是 false。

            接下来的过程就和我们上一章一样了,先创建一个父节点占位符,然后再遍历所有子 VNode 递归调用 createElm,在遍历的过程中,如果遇到子 VNode 是一个组件的 VNode,则重复本节开始的过程,这样通过一个递归的方式就可以完整地构建了整个组件树。

            由于我们这个时“候传入的 parentElm 是空,所以对组件的插入,在 createComponent 有这么一段逻辑:

    在完成组件的整个 patch 过程后,最后执行 insert(parentElm, vnode.elm, refElm) 完成组件的 DOM 插入,如果组件 patch 过程中又创建了子组件,那么DOM 的插入顺序是先子后父。

    总结

            那么到此,一个组件的 VNode 是如何创建、初始化、渲染的过程也就介绍完毕了。在对组件化的实现有一个大概了解后,接下来我们来介绍一下这其中的一些细节。我们知道编写一个组件实际上是编写一个 JavaScript 对象,对象的描述就是各种配置,之前我们提到在 _init 的最初阶段执行的就是 merge options 的逻辑,那么下一节我们从源码角度来分析合并配置的过

    展开全文
  • Vue 组件化开发

    千次阅读 2020-07-15 23:27:05
    为什么需要组件化开发,许多答案都是复用,而我却认为分而治之或许是更好的答案



    在这里插入图片描述


    1.1 组件化简介

    1.1.1 概述

      将实现页面某一部分功能的结构、样式和逻辑封装成为一个整体,使其高内聚,低耦合,达到分治与复用的目的。在前端范畴,我们可以用下面的这张图来简单地理解组件化:

    在这里插入图片描述

      这样看起来,组件化前端开发就像造一辆车,我们将轮子、发动机、悬挂、车身车门等等各部分组装成一辆车,轮子、发动机就是组件,车就是最终产品。我们将页头、侧边栏、页脚、内容区等等组件拼装起来组成了我们的页面。

    1.1.2 意义

      在谈到组件化的意义时,很多人的看法都是组件化的目的是复用。在某一篇博客看到另一种想法,分而治之,我比较这一种想法,良好地组件化以后的组件,会表现出高内聚低耦合的特征,这会给我们带来好处;组件之间不会相互影响,能有效减少出现问题时定位和解决问题的时间;组件化程度高的页面,具有清晰的页面组织和高可读性的 HTML 结构代码,组件之间的关系一目了然;组件化会强迫开发人员划清各个组件的功能边界,使得开发出的功能更加健壮;所以分而治之才是组件化的意义所在,复用只是它的副作用。同时我们还有很多其他方式都可以做到复用,这并不是组件化的专利。

    在这里插入图片描述


    1.1.3 组件化与模块化

      模块化是一种处理复杂系统分解成为更好的可管理模块的方式。它可以通过在不同组件设定不同的功能,把一个问题分解成多个小的独立、互相作用的组件,来处理复杂、大型的软件。似乎在后端领域,组件化和模块化说的是同一件事。但在我的理解中,前端领域的组件化和模块化是两个概念。先说结论:组件化是从产品功能角度进行分割,模块化是从代码实现角度进行分割,模块化是组件化的前提和基础。
      当我们将一段代码写成一个模块的时候,它有可能是一个函数、一个对象或者其他什么做了一件单一事情的东西,我们将它做成模块是因为它完成了一个单一的功能,并且这个功能很多地方都可能用得到。而当一个组件被从产品中抽象出来,它有时候就只是一个模块,但有时候却有相对复杂的实现,它就可能会有多个模块。我们说一个日期选择器是一个组件,但实现它的时候,我们分成了计算模块、渲染模块、用户输入响应模块等等模块来实现。一个单一产品功能的实现,可能是由多个模块来实现的。这样理解起来,其实可以说组件化是更粗粒度的模块化,它是在产品功能上的模块化。

    在这里插入图片描述




    1.2 组件注册

    1.2.1 全局组件

      使用 Vue.component("组件名称", { }) 进行组件注册,全局组件注册后,任何 Vue 实例都可以使用;组件其实也是一个 Vue 实例,因此它在定义时也有:data、methods、生命周期函数等。不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有 el 属性。但是组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板,模板中只能有一个根标签。data 必须是一个函数,不再是一个对象。因此组件复用时各个组件之间互补影响。

    <div id="app">
        <first></first>
    </div>
        
    <script>
        Vue.component("first",{
        	// 使用 ` 将 HTML 代码包裹起来,可以不用加换行符,使用 " 需要加换行符
            template: `
                <div>
                    <h1>China---{{year}}---{{msg}}</h1>
                </div>
            `,
            data() {
                return {
                    msg: "大好河山",
                    year: 2019
                }
            }
        });
    
        var app = new Vue({
            el:"#app"
        });
    </script>
    

    在这里插入图片描述

    1.2.3 局部组件

    局部组件只有在当前注册它的 Vue 实例中使用

    语法

    // 注册组件
    var component_name = { 
    		template:'',
            data(){
                return {}
            }
    };
    
    // 引用组件
    var app = new Vue({
        el:"#app",
        components:{
            component_name: first // 将定义的对象注册为组件
            component_name 		// 组件名与对象名一致时可以简写
        }
    })  
    

    示例

    <div id="app">
        <!-- 组件复用 -->
        <first></first>
        <first></first>
        <first></first>
    </div>
        
    <script>
        var first = {
            template:'<button v-on:click="count++">{{ count }} 次</button>',
            data(){
                return {
                    count:0
                }
            }
        }
    
        var app = new Vue({
            el:"#app",
            components: {
                first
            }
        });
    </script>
    

    在这里插入图片描述




    1.3 单文件组件

    1.3.1 概述

      显然,组件注册的两种写法都是在同一个页面完成的,而且没有 CSS 样式等,这样的组件是没有意义的,因此我们需要将“组件”抽离开来。Vue 单文件组件每个单文件组件的后缀名都是 .vue 优化了传统全局组件的一些弊端(模板缺乏高亮、没有 css 等) 每一个 Vue 单文件组件都由 template、script、style 三部分组成。

    <template>
       <!-- 组件代码区域 -->
    </template>
    
    <style scoped>
       /* 样式代码区域 */
    </style>
    
    <script>
       // js 代码区域
    </script>
    

    1.3.2 编写一个组件

      由于每个组件都是独立的,要想被引用,需要将其暴露出来,使用 export default { } 导出默认成员,使用 export A 可以按需导出。引用组件的那一方需要使用 import 接收名称 from "模块路径" 将其到导入本页面。使用 import { A, B } from "模块路径" 可以按需导入。

    <template>
        <div>
            <span class="font">{{msg}}</span>
            <button @click="fun">组件中的按钮</button>
        </div>
    </template>
    
    <style scoped>
        .font {
            font-size: 24px;
            color: #42b983;
        }
    </style>
    
    <script>
    	// 只能存在一个默认暴露,内容与 Vue 示例类似
        export default {
        	// 组件的名称
            name: 'myComponent',
            // 数据,与 Vue 实例类似
            data() {
                return {
                    msg: "Hello World",
                }
            },
            // 方法,与 Vue 实例类似
            methods: {
                fun() {
                    alert("我是组件的方法")
                }
            }
        }
    	
    	// 单独暴露方法
        export function funC() {
            alert("这是组件中 funC() 方法")
        }
    </script>
    

      如上所示,一个简单的组件就写好了,export default {} 中可以有 Vue 实例中除 el 属性的所有类容。如果我们只想要抽取方法,不想要页面,此时我们虽然可以写在 Vue 单文件组件中,但是非常不方便,我们可以将其写到 JS 文件中。

    export function funA() {
        alert("这是 js 中 funA() 方法")
    }
    
    export function funB() {
        alert("这是 js 中 funB() 方法")
    }
    

      一般我们使用 Vue 进行开发需要抽取的东西就只有组件和方法了,下面我们就可以将 MyComponent.vue 组件和 Fun.js 引入到页面中。页面也不再是熟知的 HTML,而是之前用到的 Vue 单文件组件。因此我们称引用组件的那一方为父组件,被引用的那一方为子组件。下面我们在 views 新建 vue 单文件组件编写我们的代码。Vue 中路径有个新的写法 @/ 表示 src 目录下。

    <template>
        <div>
            <my-component></my-component>
            <button @click="onA">按钮A</button>
            <button @click="onB">按钮B</button>
            <button @click="onC">按钮C</button>
        </div>
    </template>
    
    <style scoped>
    </style>
    
    <script>
    	// 引入文件
        import MyComponent from "@/components/MyComponent";
        import {funC} from "../components/MyComponent";
        import {funA, funB} from "@/components/MyFun";
    
        export default {
        	// 局部注册组件
            components: {
                myComponent: MyComponent,
            },
            data() {
                return {}
            },
            methods: {
                onA() {
                    funA();
                },
                onB() {
                    funB();
                },
                onC() {
                    funC();
                }
            }
        }
    </script>
    

      启动项目,打开 http://localhost:8080/#/test,哎?怎么啥也没有,难道是哪里写错了。发现在 views 文件夹中还有两个文件,我们来访问试试,发现http://localhost:8080/#/home 也没有东西而 http://localhost:8080/#/about 有东西。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
      产生上述问题的原因是 Vue 通过路由来找页面,而我们没有配置路由,所以找不到页面,那为什么自带的 Home.vue 也找不到呢?这是因为该页面配置的路径并不是 /home,查看路由可以发现 Home.vue 配置的路径是 /,所以直接使用 http://localhost:8080/#/ 就可以找到了。路由这里后面后详细说,这里只需要在 /route/index.js 中配好就可以了。参考 About、Home 的配置,我们配置好 Test 的路由,就可以访问到页面了。

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    
    Vue.use(VueRouter)
    
      const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
      },
      {
        path: '/test',
        name: 'Test',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '@/views/Test')
      }
    ]
    
    const router = new VueRouter({
      routes
    })
    
    export default router
    

    在这里插入图片描述





    1.4 组件之间的通信

    1.4.1 父向子通信

      父组件发送信息的形式是以属性的形式绑定值到子组件身上。 然后子组件用属性 props 接收,使用 props 向子组件传递数据,首先要在子组件中定义子组件能接受的 props,然后在父组件中子组件的自定义元素上将数据传递给它。

    子组件(MyComponent.vue)

    <template>
        <div>
            <span class="font">{{msg}}</span>
            <h1 class="font">{{title}}</h1>
            <span class="font">{{text}}</span>
        </div>
    </template>
    
    <style scoped>
        .font {
            font-size: 24px;
            color: #42b983;
        }
    </style>
    
    <script>
        export default {	// 一个 vue 中只能存在一个
            name: 'myComponent',
            props: ['title', 'text'],
            data() {
                return {
                    msg: "Hello World",
                }
            },
            methods: {
    
            }
        }
    </script>
    

    父组件(Test.vue)

    <template>
        <div>
            <my-component :title="title" :text="text"></my-component>
        </div>
    </template>
    
    <style scoped>
    </style>
    
    <script>
        import MyComponent from "@/components/MyComponent";
    
        export default {
            components: {
                myComponent: MyComponent,
            },
            data() {
                return {
                    title: "中国",
                    text: "Java 开发者",
                }
            },
            methods: {
            }
        }
    </script>
    

    在这里插入图片描述


    1.4.2 子向父通信

      但是如果子组件需要向父组件传递数据,则不能通过 props,Vue 2 中强调“单项数据流”,所谓“单向数据流”,即是数据的变动只能由外向内传递,而不能由内向外传递。组件只能将从 props 传递进来的数据进行使用,不能对其进行修改。我们唯一能做的,就是在子组件想要修改数据时,发送事件通知父组件修改。父组件通过监听子组件发送的这个事件,来决定需要做什么。 即:子组件不能直接向父组件传值,我们可以通过操作父组件的方法来实现通信。子组件用 $emit() 触发事件,父组件使用 v-on 来监听事件。

    子组件(MyComponent.vue)

    <template>
        <div>
            子组件的数值:<span class="font">{{num}}</span>
            <br/>
            <button @click="fun"></button>
        </div>
    </template>
    
    <style scoped>
        .font {
            font-size: 24px;
            color: #42b983;
        }
    </style>
    
    <script>
        export default {
            name: 'myComponent',
            props: ['num'],
            data() {
                return {
                }
            },
            methods: {
                fun() {
                    this.$emit("add-num");
                }
            }
        }
    </script>
    

    父组件(Test.vue)

    <template>
        <div>
            父组件的数值:{{num}}
            <br/>
            <my-component :num="num" @add-num="add"></my-component>
        </div>
    </template>
    
    <style scoped>
    </style>
    
    <script>
        import MyComponent from "@/components/MyComponent";
    
        export default {
            components: {
                myComponent: MyComponent,
            },
            data() {
                return {
                    num: 10,
                }
            },
            methods: {
                add() {
                    this.num++;
                }
            }
        }
    </script>
    

    在这里插入图片描述


    1.4.3 兄弟组件通信

      兄弟组件之间传递数据需要借助于中间桥梁,通过中间桥梁传递数据,中间桥梁一般是空的 Vue 实例。 传递数据方,通过 hub.$emit(方法名,参数) 触发事件。接收数据方,通过在 mounted 钩子中用 hub.$on(方法名,(参数) => {}) 监听事件。销毁事件通过 hub.$off(方法名) 进行销毁,销毁之后无法进行传递数据。

    中间桥梁(hub.js)

    import Vue from "vue";
    
    export default new Vue();
    

    组件1(MyComponent1.vue)

    <template>
        <div>
            子组件1的数值:<span class="font">{{numa}}</span>
            &emsp;&emsp;
            <button @click="fun">2 号组件 + 1</button>
        </div>
    </template>
    
    <style scoped>
        .font {
            font-size: 24px;
            color: #42b983;
        }
    </style>
    
    <script>
        import hub from "@/components/hub";
        export default {
            name: 'myComponent1',
            data() {
                return {
                    numa: 0,
                }
            },
            mounted () {
                // 此处需要使用箭头函数,否侧 this 不代表组件
                hub.$on("myComponent1",(value) => {
                    this.numa += value;
                })
            },
            methods: {
                fun() {
                    hub.$emit("myComponent2",1);
                }
            },
        }
    </script>
    

    组件2(MyComponent2.vue)

    <template>
        <div>
            子组件2的数值:<span class="font">{{numb}}</span>
            &emsp;&emsp;
            <button @click="fun">1 号组件 + 2</button>
        </div>
    </template>
    
    <style scoped>
        .font {
            font-size: 24px;
            color: #42b983;
        }
    </style>
    
    <script>
        import hub from "@/components/hub";
    
        export default {
            name: 'myComponent2',
            data() {
                return {
                    numb: 0,
                }
            },
            mounted() {
                hub.$on("myComponent2",(value) => {
                    this.numb += value;
                })
            },
            methods: {
                fun() {
                    debugger
                    hub.$emit("myComponent1",2);
                }
            },
        }
    </script>
    

    父组件(Test.vue)

    <template>
        <div>
            <my-component1 ></my-component1>
            <my-component2 ></my-component2>
        </div>
    </template>
    
    <style scoped>
    </style>
    
    <script>
        import MyComponent1 from "@/components/MyComponent1";
        import MyComponent2 from "@/components/MyComponent2";
    
        export default {
            components: {
                myComponent1: MyComponent1,
                myComponent2: MyComponent2,
            },
            data() {
                return {
                }
            },
            methods: {
            }
        }
    </script>
    

    在这里插入图片描述

    展开全文
  • vue组件化的优点

    千次阅读 2020-04-29 15:45:54
    1.组件化是独立和可复用的代码组织单元。组件系统是vue核心特性之一,它使开发者使用小型、独立和通常可复用的组件构建大型应用; 2.组件化开发能大幅度提高应用开发效率、测试性、复用性等; 3.组件使用按分类有:...

    1.组件化是独立和可复用的代码组织单元。组件系统是vue核心特性之一,它使开发者使用小型、独立和通常可复用的组件构建大型应用;
    2.组件化开发能大幅度提高应用开发效率、测试性、复用性等;
    3.组件使用按分类有:页面组件、业务组件、通用组件;
    4.vue的组件是基于配置的,我们通常编写的组件是组件配置而非组件,框架后续会生成其构造函数,它们基于VueComponent,扩展于Vue;
    5.vue中常见组件化技术有属性prop,自定义事件,插槽等,它们主要用于组件通信、扩展等;
    6.合理的划分组件,有助于提高应用性能;
    7.组件应该是高内聚、低耦合的;
    8.遵循单向数据流的原则。

    注:内容来源于开课吧

    展开全文
  • Vue组件化思想

    千次阅读 2020-05-21 21:42:29
    Vue组件思想 ①它提供了一种抽象,让我们开发出一个个独立可复用的小组将来构造我们的应用。 ②任何的应用都会被抽象成一棵组件树。 一、注册组件的基本步骤 组件的使用分为三个步骤 创建组件构造器 注册组件...

    如果将一个页面中所有的处理逻辑全部放在一起,那么处理起来会非常复杂混乱,而且不利于后续的管理以及扩展。

    如果将页面拆分成一个个小的功能块,每个功能块完成属于自己的独立功能,那么整个页面的管理和维护就变得容易了。

    在这里插入图片描述
    在这里插入图片描述

    一个页面可以分为多个组件,每个组件又可以细分

    Vue的组件思想

    ①它提供了一种抽象,让我们开发出一个个独立可复用的小组将来构造我们的应用。

    ②任何的应用都会被抽象成一棵组件树。

    一、注册组件的基本步骤

    组件的使用分为三个步骤

    1. 创建组件构造器

    2. 注册组件(全局注册、局部注册)

    3. 使用组件

    1.1 调用Vue.extend() API:创建组件构造器:const x = Vue.extend({ })

    2.1 调用Vue.component() API:注册组件

    3.1 在Vue实例范围内使用组件

    1.1.1 创建组件模板:(旧的写法)
    x 是构造器名称,在注册是会引用此名称。组件就相当于一个html页面,最外层要用一个div来包裹,然后再是内容。
    const x = Vue.extend({
    	template:
    		`
    		<div>
    			<h2>我是组件标题</h2>
    		</div>
    		`
    })
    
    2.1.1 全局注册组件: 'my-cpn’是组件的标签名,x 是1.1.1的内容。也就是说,以后用到x 组件时,用<my-cpn></my-cpn>就可以代替了。
    Vue.component('my-cpn',x)
    
    3.1.1 在Vue实例中使用:
    <div id="app">
    	<my-cpn></my-cpn>
    </div>
    

    二、创建组件构造器步骤解析

    1、Vue.extend() 创建的是一个组件构造器,通常在创建组件的地方,传入template代表自定义组件的模板,该模板就是在使用到组件的地方,要显示的HTML代码。旧写法参考1.1.1内容。

    2、Vue.component()要传入两个参数,一个是注册组件的标签名称,一个是组件构造器的名称。如1.1.1中的 x 。

    3、可以多重嵌套使用自定义组件,但组件标签中不能有其他内容<my-cpn>用

    四、父组件和子组件

    先构造两个组件:

    第一个:
    const cpn1 = Vue.extend({
    	template :`<div><h2>组件1</h2></div>`
    })
    
    第二个:把组件1在组件2中注册:
    const cpn2 = Vue.extend({
    	template :`
    	<div>
    		<h2>组件2</h2>
    		<cpn1></cpn1>
    	</div>
    	`,
    	components:{ 
            cpn1:cpn1 // 可以简写为一个cpn1
        } 
    })
    
    组件2在实例中注册
    const app = new Vue({
          el: "#app",
          components: {
            cpn2: cpn2 // 可以简写为一个cpn1
          },
    })
    
    使用:
      <div id="app">
        <cpn1></cpn1> // 未在实例中注册,不可使用
        <cpn2></cpn2> // 已在实例中注册,可以使用
      </div>
    

    其实const app实例也算是一个组件,只不过是页面的最大组件:根组件ROOT,所以vue实例也有template。子组件必须先于父组件创建,否则识别不了子组件。

    五、注册组件的语法糖

    此语法糖是将创建组件的构造器嵌入注册步骤当中。

    原先:遵循1.1->2.1->3.1的顺序

    现在 1.1和2.1结合:(全局)

    Vue.component('my-cpn',{
    	template: `<div><h2>组件标题</h2></div>`
    })
    

    (局部)

    const app = new Vue({
          el: "#app",
          components: {
            	'my-cpn': {
            		template:`<div><h2>组件标题</h2></div>`
            }
          },
      })
    

    六、组件模板抽离的写法

    由于在template中写html语句的便捷性不好,所以将html语句抽离出来写

    6.1 写在<script>标签中:

    <script type="text/x-template" id="cpn1">
    	<div>
    		<h2>组件1</h2>
    	</div>
    </script>
    

    script标签类型为:text/x-template ,并且要指定id,以便于使用

    以全局注册为例:

    Vue.components( 'my-cpn1' , { template: '#cpn1' })
    

    在实例中使用:

    <div id="app">
    	<my-cpn1></my-cpn1>
    </div>
    

    6.2 写在<template>标签中:

    <template id="cpn2">
    	<div>
    		<h2>组件2</h2>
    	</div>
    </template>
    

    给template标签加上id,便于使用。

    以局部注册为例:

    const app = new Vue({
          el: "#app",
          components: {
            	'my-cpn2': {
            		template: '#cpn2'
            }
          },
      })
    

    在实例中使用:

    <div id="app">
    	<my-cpn2></my-cpn2>
    </div>
    

    七、注意点

    1、组件内部不能直接访问实例内部数据或方法等。

    2、组件是一个单独功能模块的封装,有属于自己的html模板。

    3、即使不是直接而是间接地让组件访问到实例中的数据,那么假设一个页面有成千上百个组件,数据全部存放到实例中,会让实例显得臃肿。

    4、vue组件要有存放自己数据的地方。

    八、组件的数据存放

    在注册的时候

    <template id="cpn3">
    	<div>
    		<h2>{{title}}</h2>
    	</div>
    </template>
    
    Vue.components( 'my-cpn3' , 
    	{ 
    		template: '#cpn3',
    			data() {
    				return {
                        title: '组件3'
    				}
    			}
    	})
    

    组件存放自己数据的地方,在与template同级下的 data()函数中,所以需要返回值,这个值是对象类型,与实例中的data:{}不太一样。其实组件的原型是指向vue实例的,所以组件中也有实例的东西,例如生命周期函数等。

    九、为什么组件中的data(){}必须是一个函数?

    1、若是以对象的形式存放

    ①先定义个对象:

    const obj = {name: "小明", age:18}
    

    ②存到data中:

    data(){ return obj }
    

    此时已分配内存空间来存这个对象,假设 内存地址:0x100

    后续操作:

    let obj1 = data() 
    let obj2 = data() 
    obj1.name = '小红'
    console.log(obj1) 
    console.log(obj2) 
    
    结果: name: '小红' age :18
          name: '小红' age :18
    

    obj1、obj2指向的是同一片内存空间的内容,obj1.name = '小红‘,相当于修改这个内存地址中的内容,所以即使obj2没有对这个对象进行修改,但是获取到的内容已经改变了。

    2、若是以函数形式存放

    data(){
    	return{
    		name: "小明",
    		age:18
    	}
    }
    

    仅是定义和声明,在内存中暂无对象存储的空间,有调用到此函数,再开辟内存空间。

    后续操作:

    let obj1 = data() 
    let obj2 = data() 
    obj1.name = '小红'
    console.log(obj1) 
    console.log(obj2) 
    
    结果: name: '小红' age :18
          name: '小明' age :18
    

    obj1调用一次data(),内存开辟空间存 name、age,假设内存地址为0x100

    obj2调用一次data(),内存开辟空间存 name、age,假设内存地址为0x200

    每调用一次data(),就会开辟新的空间来存,所以内存地址不一样,也就是说,obj1、obj2只是内容一样,但没有关系的两块内存空间。在后续操作中,obj1修改了name,只是修改了0x100中的数据,obj2还是保持和第一次获取到的内容一致,没有受影响,二者是独立使用data的。保证了组件的 独立性 和 可 复用性。

    十、父子组件的通信

    1、父组件通过props向子组件传递消息。

    2、子组件通过事件向父组件发送消息。

    在这里插入图片描述

    props的基本用法:从父组件(根组件)传递数据给子组件

    10.1 定义一个模板(子组件)
    <template id="soncpn">
    	<div>
    		<p>{{sonmessage}}</p>
    		<h2>{{sonmovies}}</h2>
    	</div>
    </template> 
    // 先留两个空位给message和movies
    
    10.2 构造组件,构造器名称:cpn
    const cpn = {
         template: "#soncpn",
         props: ['sonmessage','sonmovies']
      }
      // props用来接收父组件传来的数据
    
    10.3 将vue实例视作父组件,将子组件在父组件中注册
    const app = new Vue({
          el: "#app",
          data:{
          	message: "hello world!",
          	movies:['电影1','电影2']
          }
          components: {
            	cpn
          },
      })
    
    10.4 传递数据
    <div id="app">
    	<cpn :sonmessage="message" :sonmovies="movies"></cpn>
    </div>
    

    十一、props的第二种写法及类型验证

    1、写法

    第一种写法:参照10.2

    props:['sonmessage','sonmovies']
    

    第二种写法:

    props:{
    	sonmessage: String,
    	sonmovies: Array
    }
    

    第二种写法扩展:

    props:{
    	sonmessage: {
    		type: String,
    		default: '默认值'
    	}
    	sonmovies: {
    		type: Array,
    		default(){
    			return []
    		}
    	}
    }
    

    第二种写法是强制规定传入的数据类型,当传入类型定义是数组或是对象时,默认值必须使用工厂函数来指定。

    当传入值为多种类型:

    type: [String,Number...]
    

    2、props名注意点:驼峰命名要转换成以-连接

    props:['sonMessageInfo']
    

    在实例中:

    <cpn :son-message-info="xxx"></cpn>
    

    在<template> 中没有关系

    <template>
    	<div>
    		<h2>{{sonMessageInfo}}</h2>
    	</div>
    </template>
    

    十二、子组件向父组件传递数据(自定义事件)

    props的双向绑定

    1、子组件通过$emit发送事件和参数。

    2、父组件通过 v-on / @ 来监听

    如果要对传入的props进行双向绑定,不建议直接 v-model=“props” ,要用data中的一个新变量来代替。这里是举例input输入框的input事件,将动态绑定的value,也就是numberdata,通过$emit传递给父组件,再在父组件模板中监听此事件,并获取到传过来的值,在父组件methods中定义方法,将获取到的值赋给父组件data中数据。

    在这里插入图片描述

    <body>
      <div id="app">
        <h2>{{homeNum}}</h2>
        <cpn :numberprops="homeNum" @numinput="num1change"></cpn>
      </div>
    
      <script src="./js/vue.js"></script>
    
      <template id="cpn">
        <div>
          <h2>子组件:{{numberdata}}</h2>
          <h2>props:{{numberprops}}</h2>
          <input type="text" :value="numberdata" @input="numinput">
    
        </div>
      </template>
    
      <script>
        // 3、在页面中使用组件
        const app = new Vue({
          el: "#app",
          data: {
            homeNum: 2
          },
          methods: {
            num1change(value) {
              this.homeNum = parseInt(value)
              // console.log(value)
            }
          },
          components: {
            cpn: {
              template: "#cpn",
              props: {
                numberprops: Number
              },
              data() {
                return {
                  numberdata: this.numberprops
                }
              },
              methods: {
                numinput() {
                  this.numberdata = event.target.value
                  // console.log(this.number)
                  this.$emit('numinput', this.numberdata)
    
                }
              }
            }
          },
        })
      </script>
    </body>
    

    总结为4步:

    1、子模版添加默认事件。

    2、子组件methods中使用$emit来发送自定义事件。

    3、父模板中 @自定义事件名=“父组件处理事件名” 来监听。

    4、父组件methods中处理: 父组件处理事件名(){ 处理逻辑 }

    十三、父子组件的访问方式

    通过对象直接访问

    父组件访问子组件:$children 、 $refs

    要想使用$refs,必须在组件标签中添加ref属性。

    // 在父模板中
    <div id="app">
    	<cpn ref="aaa"></cpn>
    	<cpn1 ref="bbb"></cpn1>
    	<cpn2></cpn2>
    </div>
    

    this.$refs 就可以获取到所有添加了ref属性的子组件

    this.$refs.aaa 可以取到具体项

    子组件访问父组件:$parent​

    父组件中可能包含多个子组件,所以this.$children获取到的是一个数组类型。

    this.$parent 是单个对象,它只能获取到上一级组件

    补充:获取根实例:this.$root

    展开全文
  • Vue组件化的一些理解

    千次阅读 2019-06-26 22:01:38
    Vue组件化的一些理解 一、基础概念 1、概念:组件是html、css、js等的一个聚合体 2、为什么要使用组件? ​ 1、组件化 将一个具备完整功能的项目的一部分进行多处使用 加快项目的进度 可以进行项目的复用 2...
  • 关于vue组件化的理解

    千次阅读 2020-03-07 21:38:31
    组件化Vue的精髓,Vue应用就是由一个个组件构成的。 1.定义 组件是可复用的 Vue 实例,准确讲它们是VueComponent的实例,继承自Vue。 2.优点 可以增加代码的复用性、可维护性和可测试性。提高开发效率, 方便重复...
  • 3:Vue组件化开发

    千次阅读 2020-04-28 12:24:17
    组件化开发 组件 组件 (Component) 是 Vue.js 最强大的功能之一 组件可以扩展 HTML 元素,封装可重用的代码 思想体现:标准,分治,重用,组合 一:组件注册 全局注册 Vue.component(‘组件名称’, { }) 第1个...
  • vue组件化开发

    千次阅读 多人点赞 2020-09-16 15:41:11
    答:我用vue开发的所有项目,都是采用组件化的思想开发的。一般我在搭建项目的时候,会创建一个views目录和一个commen目录和一个feature目录,views目录中放页面级的组件,commen中放公共组件(如:head,foot,组件...
  • 主要介绍了深入理解Vue.js轻量高效的前端组件化方案 ,需要的朋友可以参考下
  • 基于Vue的前端组件化研究与实践,李曰斌,詹舒波,在这个互联网高速发展的时代,用户交互和用户体验变的越来越重要。前端技术的发展也呈现井喷的趋势,各种新技术,新框架不断涌现
  • vue组件化开发组件拆分原则是什么

    千次阅读 2018-05-23 09:46:00
    原则:可复用、可组合; 两大类:页面组件、功能组件; 除了公共头导航、侧导航、脚部内容,还有: 转载于:https://www.cnblogs.com/yancongyang/p/9075365.html...
  • 京东金融Vue组件化项目实战(完整)

    千次阅读 2019-03-20 16:52:14
    下载地址:百度网盘
  • Vue组件化

    千次阅读 2021-11-22 12:42:34
    Vue组件化 面向组件编程 把一个页面按照模块拆分成N个小块 注意:演示环境为 Vue脚手架搭建的项目上进行演示 创建局部组件 语法格式: Vue.component('my-component-name',{ // ...options... }) 例子: 注册一个...
  • Vue组件化(全局、局部)、props传参

    千次阅读 2018-09-23 15:37:33
    全局组件化 带参数传递的全局组件化(props方式) 局部组件化 带参数传递的局部组件化(props方式) 自定义组件使用注意 全局组件化 &lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &...
  • 二、vue组件化开发(轻松入门vue)

    千次阅读 2020-04-15 17:28:59
    二、vue组件化开发(轻松入门vue) Vue组件化开发五、组件化开发1. 组件注册组件命名规范组件注册注意事项全局组件注册局部组件注册2. Vue调试工具下载3. 组件间数据交互父组件向子组件传值props传递数据原则:单向...
  • vue:组件化思想的理解

    千次阅读 2020-03-23 00:50:49
    vue组件系统提供了一种抽象,让我们可以使用独立可复用的组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树。组件化能提高开发效率,方便重复使用(复用),简化调试步骤,提升项目可维护性,便于多人...
  • Vue.js教程-组件化开发

    千次阅读 多人点赞 2020-08-04 14:15:55
    Vue.js教程-组件化开发前言Vue组件化什么是组件化Vue单页面开发的解释组件化思想组件的使用原理实际开发中的使用-父子组件父子组件传递数据父传子-props用法子传父-this.$emit()自定义事件父组件直接获取子组件的...
  • Vue全家桶之组件化开发

    千次阅读 多人点赞 2020-01-06 07:56:26
    学习组件化开发,首先掌握组件化的开发思想,组件的注册方式,组件间的数据交互方式,组件插槽的用法,vue调式工具的用法,组件的方式来实现业务逻辑功能。 组件化开发思想,组件注册,组件调式,组件间的数据交互,...
  • 1. 基础组件编写 1.1 组件目录结构 1.2 组件文件代码 <template> <transition name="fade"> <div class="notification" :style="style"> <span class="content">{{content}}</...
  • Vue_理解组件化开发

    2020-03-06 22:27:08
    组件化是Vue的精髓,Vue就是由一个一个的组件构成的。Vue的组件化设计到的内容又非常多,当在面试时,被问到:谈一下你对Vue组件化的理解。这时候又有可能...
  • vue组件化项目实践

    千次阅读 2016-10-07 19:48:27
    它提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API。从技术上讲, Vue.js 集中在 MVVM 模式上的视图模型层,并通过双向数据绑定连接视图和模型。实际的 DOM 操作和输出格式被抽象出来成...
  • Vue组件化开发

    千次阅读 2018-05-19 12:50:43
    Vue js组件化开发 Vue js 对象简写 &lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;meta name=&...
  • 1、百度UEditor插件的安装过程请查看我的另篇博文:http://blog.csdn.net/lzc4869/article/details/784381212、组件(1)组件页面ueditor.vue <script :id=id type="text/plain"></script> </template><script> ...
  • Vue.js之组件化应用构建+vue数据请求

    千次阅读 2018-09-15 17:10:29
    本文记录vue组件系统下的创建与使用,包含组件之间如何传值;vue的数据请求。参考来源于IT营的大地老师关于Vue教程,需要的可留言邮箱,我会直接发百度云链接,无偿。  关于组件,借用官方的介绍,很清楚了,下图...
  • vue项目如何进行组件化开发

    千次阅读 2019-08-21 20:35:42
    首先在router文件夹下面进行导入你的vue页面 import zujian from '@/components/zhujian' //紧接着封装组件 //这里两个参数分别代表的是1.自己定义的组件名字 2.是配置的路由名字 Vue.component('zujian1',...
  • 我们前面学习很多关于 vue 的知识了,下面让我们来学习 vue 中一个重要的知识点——组件。这篇文章我们就来看看组件到底是什么吧。
  • vue组件——混入

    千次阅读 2019-07-10 20:45:28
    vue组件——混入混入混入合并策略 混入   前边介绍了组件,我们知道组件包含三个部分 ,HTML 模板、js、css;但是,有时候,我们的模板可能是不同的,但是执行的方法和需要的数据类似,这时候,我们可以使用混入 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 115,233
精华内容 46,093
关键字:

vue组件化

vue 订阅