内置组件

动态组件

  • 动态组件适用于多个组件频繁切换的处理。
  • 用于将一个 ‘元组件’ 渲染为动态组件,以is属性值决定渲染哪个组件。
  • is 设置内容是个组件名称
    // 动态组件
    用于实现多个组件的快速切换,例如选项卡效果。var ComA = { template: <**div**>A组件内容 <input **type**="text"></**div**>} var ComB = { template: <**div**>B组件内容 <input **type**="text"></**div**>} var ComC = { template: <**div**>C组件内容 <input **type**="text"></**div**>}new Vue({ el:”#app”, data:{ titles:[‘ComA’,’ComB’,’ComC’], currentCom:’ComA’ }, components:{ ComA,ComB,ComC } })

is特性

  • is属性会在每次切换组件时,Vue都会创建一个新的组件实例。(tab切换时会销毁老组件,创建新组件)

    • 例如:给子组件内添加一个输入框,输入内容后切换发现不会被保留

      keep-alive组件

  • 主要用于保留组件状态或避免组件重新渲染。

  • 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中

问题

  • 动态组件component 的频繁切换回导致组件的重新渲染且无法保留状态

解决

  • 用标签包裹,不对组件进行重新渲染,保留组件内部状态(缓存)
  • is绑定的是属性/计算属性 。不是方法! 修改上面的tab切换

属性
官网地址

  • include属性 用于指定哪些组件会被缓存,具有多种设置方式。
  • 如果include是属性绑定,可以为他设置字符串,数组或者正则
    • include=”ComA,ComB,ComC” 注意不能加空格
    • :include=”[‘ComA’,’ComB’,’ComC’]” 可以直接写数组,也可以放data中。
    • :include=”/Com[ABC]/“
  • exclude属性 不包含
  • max属性,最多缓存多少个

    异步组件

  • Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。

  • Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染

异步组件async-example在1s后传递配置模板
Vue.component(‘async-example’, function (resolve, reject) { setTimeout(function () { // 向 resolve 回调传递组件定义 resolve({ template: ‘

I am async!
‘ }) }, 1000) })
异步组件与webpack代码分割结合
Vue.component(‘async-webpack-example’, function (resolve) { // 这个特殊的 require 语法将会告诉 webpack // 自动将你的构建代码切割成多个包,这些包 // 会通过 Ajax 请求加载 require([‘./my-async-component’], resolve) })
ESM+ES6+写法
Vue.component( ‘async-webpack-example’, // 这个动态导入会返回一个 Promise 对象。 () => import(‘./my-async-component’) )
局部注册组件写法
new Vue({ // … components: { ‘my-component’: () => import(‘./my-async-component’) } })
处理加载状态的工厂函数
const AsyncComponent = () => ({ // 需要加载的组件 (应该是一个 Promise 对象) component: import(‘./MyComponent.vue’), // 异步组件加载时使用的组件 loading: LoadingComponent, // 加载失败时使用的组件 error: ErrorComponent, // 展示加载时组件的延时时间。默认值是 200 (毫秒) delay: 200, // 如果提供了超时时间且组件加载也超时了, // 则使用加载失败时使用的组件。默认值是:Infinity timeout: 3000 })

  • 了解下异步组件和同步组件区别
  • 实现封装,传入需要加载的组件

    访问元素组件

    在绝大多数情况下,我们最好不要触达另一个组件实例内部或手动操作 DOM 元素。不过也确实在一些情况下做这些事情是合适的
    访问根组件

  • 在每个 new Vue 实例的子组件中,其根实例可以通过 $root property 进行访问(子组件访问)// 获取根组件的数据 this.$root.foo // 写入根组件的数据 this.$root.foo = 2 // 访问根组件的计算属性 this.$root.bar // 调用根组件的方法 this.$root.baz()

  • 访问父组件

    注意:这个模式扩展到中大型应用来说就不然了。因此在绝大多数情况下,我们强烈推荐使用 Vuex 来管理应用的状态

  • 使用 $parent,如果层次过深,容易失控,推荐依赖注入var map = this.$parent.map || this.$parent.$parent.map访问子组件


  • 尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,你可以通过 ref 这个 attribute 为子组件赋予一个 ID 引用<base-input ref=”usernameInput”></base-input>this.$refs.usernameInput // 访问这个子组件实例
  • 在父组件中可以获取子组件实例方法,调用使用methods: { // 用来从父级组件聚焦输入框 focus: function () { this.$refs.input.focus() } }this.$refs.usernameInput.focus() // 在父组件中调用
  • 依赖注入

    注意:当 ref 和 v-for 一起使用的时候,你得到的 ref 将会是一个包含了对应数据源的这些子组件的数组。

  • 使用 $parent property 无法很好的扩展到更深层级的嵌套组件上。这也是依赖注入的用武之地,它用到了两个新的实例选项:provide 和 inject

  • 适用 provide 提供给后代组件 数据/方法
    问题 // c要用a的getMap方法 解决方案: provide 和 inject

父组件
provide: function () { return { getMap: this.getMap } }
任何后代组件里添加实例属性 getMap
inject: [‘getMap’]

  • 此用法可以让我们在任意后代组件中访问 getMap,而不需要暴露整个 父组件 实例
  • 实际上,你可以把依赖注入看作一部分“大范围有效的 prop” (隔代的props)

依赖注入缺点

  • 它将你应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难
  • 所提供的 property 是非响应式的
  • 如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex 这样真正的状态管理方案