vue2常用api

448 阅读4分钟

全局

productionTip

  • 类型boolean

  • 默认值true

  • 用法

    设置为 false 以阻止 vue 在启动时生成生产提示

    // 浏览器控制台生产的生产提示
    You are running Vue in development mode.
    Make sure to turn on production mode when deploying for production.
    See more tips at https://vuejs.org/guide/deployment.html
    

Vue.nextTick

  • 参数

    • {Function} [callback]
    • {Object} [context]
  • 用法

    在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

    <template>
      <div :class="$style.root">
        <div ref="div">{{count}}</div>
        <button @click="toOne">置1</button>
        <button @click="toZero">置0</button>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          count:-1
        };
      },
      methods:{
        toOne(){
          this.count=1
          console.log(this.$refs.div.innerHTML);
          // 第一种写法
          this.$nextTick(()=>{
            console.log(this.$refs.div.innerHTML);
          })
        },
        async toZero(){
          this.count=0
          console.log(this.$refs.div.innerHTML);
          // 第二种写法
          await this.$nextTick()
          console.log(this.$refs.div.innerHTML);
        }
      }
    };
    </script>
    

Vue.set( target, propertyName/index, valu…

  • 参数

    • {Object | Array} target
    • {string | number} propertyName/index
    • {any} value
  • 返回值:设置的值。

  • 用法

    向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新,它必须用于向响应式对象上添加新 property。

  • 用途:解决Vue 不能检测数组和对象的变化

    • 对于对象

      Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。

      this.$set(object, propertyName, value)
      
    • 对于数组

      Vue 不能检测以下数组的变动:

      1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue

        this.$set(this.arr, indexOfItem, newValue)
        
      2. 当你修改数组的长度时,例如:vm.items.length = newLength

        this.arr.splice(newLength)
        

Vue.filter()

  • 参数

    • {string} id
    • {Function} [definition]
  • 用法

    注册或获取全局过滤器

    // 注册
    Vue.filter('my-filter', function (value) {
      // 返回处理后的值
      return newValue
    })
    
    // getter,返回已注册的过滤器
    var myFilter = Vue.filter('my-filter')
    

    使用过滤器

    <!-- 在双花括号中 -->
    {{ message | capitalize }}
    
    <!-- 在 `v-bind` 中 -->
    <div v-bind:id="rawId | formatId"></div>
    

Vue.directive()

  • 参数

    • {string} name
    • {Function | Object} [definition]
  • 用法

    注册或获取全局指令。

    // 注册
    Vue.directive('my-directive', {
      bind: function () {},
      inserted: function () {},
      update: function () {},
      componentUpdated: function () {},
      unbind: function () {}
    })
    
    // 注册 (指令函数)
    Vue.directive('my-directive', function () {
      // 这里将会被 `bind` 和 `update` 调用
    })
    
    // getter,返回已注册的指令
    var myDirective = Vue.directive('my-directive')
    
  • 自定义指令的钩子函数 (均为可选):

    • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

    • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

    • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新

    • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

    • unbind:只调用一次,指令与元素解绑时调用。

  • 指令钩子函数会被传入以下参数:

    • el:指令所绑定的元素,可以用来直接操作 DOM

    • binding:一个对象,包含以下 property:

      • name:指令名,不包括 v- 前缀。
      • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
      • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用无论值是否改变都可用。
      • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
      • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
      • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
    • vnode:Vue 编译生成的虚拟节点

    • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

Vue.use()

  • 参数

    • {Object | Function} plugin
  • 用法

    安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。

    该方法需要在调用 new Vue() 之前被调用。

    当 install 方法被同一个插件多次调用,插件将只会被安装一次。

Vue.mixin( mixin )

  • 参数

    • {Object} mixin
  • 用法

    全局注册一个混入,影响注册之后所有创建的每个 Vue 实例。插件作者可以使用混入,向组件注入自定义的行为。不推荐在应用代码中使用

组件选项/数据

props

  • 大小写

    驼峰的prop名,在标签中使用对应的连接符型式

    props: ['postTitle'] -> <blog-post post-title="hello!"></blog-post>
    
  • 类型校验

    props: {
      // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
      propA: Number,
      // 多个可能的类型
      propB: [String, Number],
      // 必填的字符串
      propC: {
        type: String,
        required: true
      },
      // 带有默认值的数字
      propD: {
        type: Number,
        default: 100
      },
      // 带有默认值的对象
      propE: {
        type: Object,
        // 对象或数组默认值必须从一个工厂函数获取
        default: function () {
          return { message: 'hello' }
        }
      },
      // 自定义验证函数
      propF: {
        validator: function (value) {
          // 这个值必须匹配下列字符串中的一个
          return ['success', 'warning', 'danger'].indexOf(value) !== -1
        }
      }
    }
    

computed

  • 类型{ [key: string]: Function | { get: Function, set: Function } }

  • 详细

    • 计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例

    • 计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖 (比如非响应式 property) 在该实例范畴之外,则计算属性是不会被更新的

    • 计算属性只能处理同步,不能处理异步

computed: {
    // 默认情况下只能获取,不能修改
    // fullName() {
    //   return this.firstName + ' ' + this.lastName
    // },

    fullName: {
      // 获取时调用
      get() {
        return this.firstName + ' ' + this.lastName
      },
      // 设置时调用 value可以拿到最新值
      set(value) {
        this.firstName = value.split(' ')[0]
        this.lastName = value.split(' ')[1]
        console.log('我调用了', value)
      }
    }
  }

全选反选案例(★)

<template>
  <div>
    <span>全选:</span>
    <input type="checkbox" v-model="checkAll" />
    <button>反选</button>
    <ul>
      <!-- 这里的每一个checkbox都被一个li包裹,所以他们是独立的每一个checkbox,适用于v-model绑定的是checked选中状态 -->
      <li v-for="item in arr" :key="item.name">
        <input type="checkbox" v-model="item.c" />
        <span>{{ item.name }}</span>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arr: [
        {
          name: '猪八戒',
          c: false,
        },
        {
          name: '孙悟空',
          c: false,
        },
        {
          name: '唐僧',
          c: false,
        },
        {
          name: '白龙马',
          c: false,
        },
      ],
    }
  },

  computed: {
    // 老写法: 计算属性只能获取
    // checkAll() {
    //   return this.arr.every((item) => {
    //     return item.c === true
    //   })
    // },

    // 新写法: 计算属性既能获取. 又能设置
    checkAll: {
      get() {
        return this.arr.every((item) => {
          return item.c === true
        })
      },
      set(value) {
        this.arr.forEach((item) => {
          // 赋值
          item.c = value
        })
      },
    },
  },
}
</script>

<style></style>

watch

  • 类型{ [key: string]: string | Function | Object | Array }
  • 详细
    • 一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象
    • Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property
    • watch除了能完成computed能完成的所有操作,还能处理异步操作
// 基本使用
watch: {
  // 只要属性发生了改变,这个函数就会执行
  // 参数1: value    变化后的值
 // 参数2: oldValue 变化前的值
  简单数据名 (value, oldValue) {

  }
}
/* 
watch: {
  msg (value, oldValue) {
    console.log('你变了', value, oldValue)
  }
}
*/

// 1. 默认情况下,watch只能监听到简单类型的数据变化,如果监听的是复杂类型,只会监听地址是否发生改变,不会监听对象内部属性的变化。
// 2. 需要使用监听的完整写法 是一个对象
watch: {
  复杂数据名: {
    // handler 数据发生变化,需要执行的处理程序
    // deep: true  如果true,代表深度监听,不仅会监听地址的变化,还会监听对象内部属性的变化
    // immediate: 立即 立刻  是否立即监听 默认是false  如果是true,代表页面一加载,会先执行一次处理程序
    // value: 数据最新值
    handler (value) {
      console.log(value)
    },
    deep: true,
    immediate: true
  }
}

/* 
watch: {
  friend: {
    handler (value) {
      console.log('你变了', value)
    },
    deep: true,
    immediate: true
  }
}
*/

组件选项/钩子

created

  • 类型Function

  • 详细

    在实例创建完成后被立即同步调用。在这一步中,实例已完成对选项的处理,意味着以下内容已被配置完毕:数据侦听、计算属性、方法、事件/侦听器的回调函数。然而,挂载阶段还没开始,且 $el property 目前尚不可用。

mounted

  • 类型Function

  • 详细

    实例被挂载后调用,这时 el 被新创建的 vm.$el 替换了。如果根实例挂载到了一个文档内的元素上,当 mounted 被调用时 vm.$el 也在文档内。

    注意 mounted 不会保证所有的子组件也都被挂载完成。如果你希望等到整个视图都渲染完毕再执行某些操作,可以在 mounted 内部使用 vm.$nextTick

    mounted: function () {
      this.$nextTick(function () {
        // 仅在整个视图都被渲染之后才会运行的代码
      })
    }
    

    该钩子在服务器端渲染期间不被调用。

destroyed

  • 类型Function

  • 详细

    实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。

    该钩子在服务器端渲染期间不被调用。

activated

  • 类型Function

  • 详细

    被 keep-alive 缓存的组件激活时调用。

    该钩子在服务器端渲染期间不被调用。

deactivated

  • 类型Function

  • 详细

    被 keep-alive 缓存的组件失活时调用。

    该钩子在服务器端渲染期间不被调用。

组件选项/资源

directives

  • 类型Object

  • 详细

    包含 Vue 实例可用指令(局部指令,不常用)

    directives: {
      focus: {
        // 指令的定义
        inserted: function (el) {
          el.focus()
        }
      }
    }
    

filters

  • 类型Object

  • 详细

    包含 Vue 实例可用过滤器(局部过滤器)

    filters: {
      capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      }
    }
    

components

  • 类型Object

  • 详细

    • 命名(推荐使用短横线命名法)

      // 短横线命名法
      Vue.component('hm-header', HmHeader)
      // 大驼峰命名法(推荐)
      Vue.component('HmHeader', HmHeader)
      
      // 区别:
      // 使用 短横线命名法 时 只能使用`<hm-header> </hm-header>`
      // 使用 大驼峰命名法 时 `<HmHeader> </HmHeader>` 和 `<hm-header> </hm-header>`  都可以
      
    • 使用

      // 简写型式
      components: {
          ComponentA
      },
      // 完整型式
      components: {
          'component-a': ComponentA
      },
      

组件选项/组合

parent

  • 类型Vue instance
  • 详细
    • 子实例可以用 this.$parent 访问父实例
    • 这种方式是临时的,不建议常用

mixins

  • 类型Array<Object>

  • 详细

    • 接收一个混入对象的数组。这些混入对象可以像正常的实例对象一样包含实例选项,这些选项将会被合并到最终的选项中,使用的是和 Vue.extend() 一样的选项合并逻辑

    • Mixin 钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用

    • 使用

      // 定义一个mixin对象
      const myMixin = {
        created: function () {
          this.hello()
        },
        methods: {
          hello: function () {
            console.log('hello from mixin!')
          }
        }
      }
      // 导出这个mixin
      export default myMixin
      
      // 导入mixin
      import myMixin from './mixins/myMixin'
      
      export default {
        // 使用mixin
        mixins: [myMixin]
      }
      
    • 合并时冲突的解决方式

      • 数据对象(data)在内部会进行递归合并,并在发生冲突时以组件数据优先
      • 同名钩子函数将合并为一个数组,因此都将被调用,混入对象的钩子将在组件自身钩子之前调用
      • 值为对象的组件选项(methods、components 和 directives),将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对

provide / inject

  • 类型

    • provideObject | () => Object
    • injectArray<string> | { [key: string]: string | Symbol | Object }
  • 详细

    这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。

    provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 SymbolReflect.ownKeys 的环境下可工作。

    inject 选项应该是:

    • 一个字符串数组,或
    • 一个对象,对象的 key 是本地的绑定名,value 是:
      • 在可用的注入内容中搜索用的 key (字符串或 Symbol),或
      • 一个对象,该对象的:
        • from property 是在可用的注入内容中搜索用的 key (字符串或 Symbol)
        • default property 是降级情况下使用的 value
  • 注意:

    provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

  • 使用:

    // 祖先
    <template>
      <div :class="$style.root">
        <Son></Son>
      </div>
    </template>
    
    <script>
    import Son from './Son.vue'
    export default {
      components:{
        Son
      },
      data() {
        return {
          count:[0,1]
        };
      },
      provide () {
        return {
          count: this.count
        }
      }
    };
    </script>
    
    <style lang="scss" module>
    .root {
      width: 300px;
      height: 300px;
    }
    </style>
    
    // 后代
    <template>
      <div class="son">
        <ul v-for="item in foo" :key="item">
          <li>{{item}}</li>
        </ul>
      </div>
    </template>
    
    <script>
    export default {
      inject: {
        foo: {
          from: 'count',
          default: () => [1, 2, 3]
        }
      }
    }
    </script>
    
    <style>
    
    </style>
    

组件选项/其它

name

  • 类型string

  • 限制:只有作为组件选项时起作用

  • 详细

    只改变组件在 vue-devtools中显示的名称,不改变组件本身的组件名

实例

vm.$parent

  • 类型Vue instance

  • 只读

  • 详细

    父实例,如果当前实例有的话

vm.$root

  • 类型Vue instance

  • 只读

  • 详细

    当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己

vm.$slots

  • 类型{ [name: string]: ?Array<VNode> }

  • 只读

  • 响应性:否

  • 详细

    • 用来访问被静态插槽(默认插槽和具名插槽)分发的内容。

    • 每个具名插槽有其相应的 property (例如:v-slot:foo 中的内容将会在 vm.$slots.foo 中被找到)

    • default property 包括了所有没有被包含在具名插槽中的节点,或 v-slot:default 的内容

  • 注意:

    静态插槽的实现是在组件初始化刚开始的时候就去拿渲染后的内容,它定义在 initRender 方法中,并且这个方法的初次调用先于 created,所以一开始可以在 created 里得到有值的内容

vm.$scopedSlots

  • 类型{ [name: string]: props => Array<VNode> | undefined }

  • 只读

  • 详细

    用来访问作用域插槽。对于包括 默认 slot 在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数。

  • 注意

    • 虽然 $scopedSlots 的初始化也是在 initRender 方法里,但那时很明显只是给了它一个空对象,它的赋值是在 _render 方法中,所以你在mounted中是可以拿到的

    • 从 2.6.0 开始,这个 property 有两个变化:

      1. 作用域插槽函数现在保证返回一个 VNode 数组,除非在返回值无效的情况下返回 undefined
      2. 所有的 $slots 现在都会作为函数暴露在 $scopedSlots 中。如果你在使用渲染函数,不论当前插槽是否带有作用域,我们都推荐始终通过 $scopedSlots 访问它们。这不仅仅使得在未来添加作用域变得简单,也可以让你最终轻松迁移到所有插槽都是函数的 Vue 3。
// 父组件中
<Son>
  <template v-slot:header>
    <h1>这是具名插槽</h1>
  </template>

  <template v-slot:default>
    <p>默认插槽的内容</p>
    <p>也是默认插槽的内容</p>
  </template>

  <template v-slot:footer={num}>
    <p>这是作用域插槽接收slot上传递的参数</p>
    <p>{{num}}</p>
  </template>
</Son>

// 子组件中
<div class="son">
  <header>
    <slot name="header">具名插槽需要name,这里是插槽的默认值</slot>
  </header>
  <main>
    <slot>这是默认插槽,这里是插槽的默认值</slot>
  </main>
  <footer>
    <slot name="footer" :num="num">作用域插槽需要name,这里是插槽的默认值</slot>
  </footer>
</div>
// $slots控制台打印
{}
default: (...)
header: (...)
get default: ƒ ()
get header: ƒ ()
[[Prototype]]: Object

// $scopedSlots控制台打印
{$stable: true, $key: undefined, header: ƒ, default: ƒ, footer: ƒ, …}
default: ƒ ()
footer: ƒ ()
header: ƒ ()
$hasNormal: false
$key: undefined
$stable: true
[[Prototype]]: Object

vm.$refs

  • 类型Object

  • 只读

  • 详细

    一个对象,持有注册过ref的所有 DOM 元素和组件实例,一般在子组件上注册ref,父组件通过this.$ref获取子组件实例上的属性或方法

    <template>
      <div :class="$style.root">
        <Son ref="son"></Son>
      </div>
    </template>
    
    <script>
    import Son from './Son.vue';
    export default {
      components: {
        Son
      },
      mounted(){
        console.log(this.$refs.son);
      }
    }
    </script>
    

vm.$attrs

  • 类型{ [key: string]: string }
  • 只读
  • 详细
    • 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (classstyle 除外)
    • 当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (classstyle 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用

vm.$listeners

  • 类型{ [key: string]: Function | Array<Function> }
  • 只读
  • 详细
    • 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器
    • 它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用