使用 Vue 实例——全局 API

文章目录

一、总览

二、Vue.extend(options)

三、Vue.nextTick(options)

四、Vue.set(target, key, value) 

五、Vue.delete(target, key)

六、Vue.directive(id, [definition])

七、Vue.filter(id, [definition])

八、Vue.component(id, [definition])

九、Vue.use(plugin)

十、Vue.mixin(mixin)

十一、Vue.compile(template)

十二、Vue.version


一、总览

Vue.extend(options)                 // 通过继承一个option对象来创建一个Vue实例
Vue.nextTick([callback, context])   // 在下次DOM更新循环结束之后执行延迟回调
Vue.set(target, key, value)         // 设置对象的属性,如果是响应式对象,将会触发视图更新
Vue.delete(target, key)             // 删除对象的属性,如果是响应式对象,将会触发视图更新
Vue.directive(id, [definition])     // 注册或获取全局指令
Vue.filter(id, [definition])        // 注册或获取全局过滤器
Vue.component(id, [definition])     // 注册或获取全局组件
Vue.use(plugin)                     // 安装Vue插件
Vue.mixin(mixin)                    // 全局注册一个mixin对象
Vue.compile(template)               // 在render函数中编译模板字符串
Vue.version                         // 提供当前使用Vue的版本号

二、Vue.extend(options)

Vue.extend 属于 Vue 的全局 API,在实际业务开发中我们很少使用,因为相比常用的 Vue.component 写法使用 extend 步骤要更加繁琐一些。但是在一些独立组件开发场景中,Vue.extend + $mount 这对组合是我们需要去关注的。

<!-- <p>Walter White aka Heisenberg</p> -->
<div id="mount-point"></div>

// 创建构造器
var Profile = Vue.extend({
  template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
  data: function () {
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    }
  }
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')

三、Vue.nextTick(options)

Vue.nextTick 用于延迟执行一段代码,它接受2个参数(回调函数和执行回调函数的上下文环境),如果没有提供回调函数,那么将返回 promise 对象

下面了解下 nextTick 的主要应用的场景及原因

  • 在Vue生命周期的 created() 钩子函数进行的 DOM 操作一定要放在 Vue.nextTick() 的回调函数中

created() 钩子函数执行的时候 DOM 其实并未进行任何渲染,而此时进行 DOM 操作无异于徒劳,所以此处一定要将 DOM操作的 JS 代码放进 Vue.nextTick() 的回调函数中。与之对应的就是 mounted() 钩子函数,因为该钩子函数执行时所有的 DOM挂载和渲染都已完成,此时在该钩子函数中进行任何 DOM 操作都不会有问题 。

  • 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick() 的回调函数中
<div class="app">
  <div ref="msgDiv">{{msg}}</div>
  <div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
  <div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
  <div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
  <button @click="changeMsg">
    Change the Message
  </button>
</div>

new Vue({
  el: '.app',
  data: {
    msg: 'Hello Vue.',
    msg1: '',
    msg2: '',
    msg3: ''
  },
  methods: {
    changeMsg() {
      this.msg = "Hello world."
      this.msg1 = this.$refs.msgDiv.innerHTML
      this.$nextTick(() => {
        this.msg2 = this.$refs.msgDiv.innerHTML
      })
      this.msg3 = this.$refs.msgDiv.innerHTML
    }
  }
})

四、Vue.set(target, key, value) 

  • target:要更改的数据源(可以是对象或者数组)
  • key:要修改的变量
  • value重新赋的值

如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。当你把一个普通的 JS 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter

受现代 JS 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

Vue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上。


五、Vue.delete(target, key)

  • target:要更改的数据源(可以是对象或者数组)
  • key:要删除的变量

删除对象的属性,如果对象是响应式的,确保删除能触发更新视图,这个方法主要用于避开 Vue 不能检测到属性被删除的限制


六、Vue.directive(id, [definition])

Vue 允许注册自定义指令,用于对底层 DOM 进行操作

Vue.directive("focus", {
  bind() {
    // 指令第一次绑定到元素时调用,只会调用一次,可以用来执行一些初始化操作。
  },
  inserted(el) {
    // 被绑定元素插入父节点时调用。
  },
  update() {
    // 所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。
  },
  componentUpdated() {
    // 所在组件VNode及其子VNode全部更新时调用。
  },
  unbind() {
    // 指令与元素解绑时调用,只会被调用一次。
  }
})

上面的钩子函数拥有如下参数:

  • el:指令绑定的 HTML 元素,可以用来直接操作 DOM
  • vnode:Vue编译生成的虚拟节点。
  • oldVnode:之前的虚拟节点,仅在 update、componentUpdated 钩子中可用。
  • binding:一个对象,包含以下属性:
    • name:指令名称,不包括 v- 前缀。
    • value:指令的绑定值,例如 v-my-directive="1 + 1" value 的值是2。
    • oldValue:指令绑定的之前一个值,仅在 update、componentUpdated 钩子中可用。
    • expression:绑定值的字符串形式,例如 v-my-directive="1 + 1" 当中 expression 的值为"1 + 1"。
    • arg:传给指令的参数,例如 v-my-directive:foo中arg 的值是 "foo"
    • modifiers:包含修饰符的对象,例如 v-my-directive.foo.bar modifiers 的值是 {foo: true, bar: true}

七、Vue.filter(id, [definition])

Vue 可以通过定义过滤器,进行一些常见的文本格式化,可以用于 mustache 插值和 v-bind 表达式当中,使用时通过管道符 | 添加在表达式尾部

filters.js

const numUnitConversion = value => {
  return value >= 10000 ? (value / 10000).toFixed(1) : value
}

const stubValue = value => {
  if (!value) {
    return '-'
  } else {
    return value
  }
}

export {
  stubValue,
  numUnitConversion
}

main.js

import * as filters from './common/filters'

// 全局过滤器设置
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

直接用过滤管道符 | 连接需要过滤的数据和定义配置的过滤函数即可

<div class="info_tit info_last">
  <span>磁盘总量</span>
    <span><i class="color_6">{{ rectangleData.diskNum | stubValue }}</i> TB</span>
</div>

八、Vue.component(id, [definition])

  全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生

Vue.component('组件名',组件变量名);

  例如:

<div id="app">        
    <div>#app</div>        
    <my-header></my-header>        
    <my-main></my-main>        
    <my-footer></my-footer>    
</div>    
<div id="root">        
    <div>#root</div>        
    <my-header></my-header>        
    <my-main></my-main>        
    <my-footer></my-footer>    
</div>

<script type="text/javascript" src="./vue.js"</script><script>    
    // 定义组件    
    const Header = {        
        template: '<header>全局头部组件</header>'    
    };    
    const Main = {
        template: '<main>局部主体组件</main>'    
    };   
    const Footer = {       
        template: '<footer>全局尾部组件</footer>'    
    };
    
    // 全局注册组件——头部&&尾部
    Vue.component('my-header',Header); 
    Vue.component('my-footer',Footer);  
    
    // 第一个实例    
    new Vue({        
        el: '#app',        
        // 局部注册组件——内容        
        components: {            
            'my-main': Main        
        }    
     });  
    // 第二个实例    
    new Vue({        
        el: '#root',    
    })
</script>

  页面运行结果

#app
全局头部组件
局部主体组件
全局尾部组件
#root
全局头部组件
全局尾部组件

  控制台运行结果

[Vue warn]: Unknown custom element: <my-main> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

(found in <Root>)

  会报错,说没有注册组件


九、Vue.use(plugin)

Vue 通过插件来添加一些全局功能,Vue插件都会覆写其 install() 方法,该方法第1个参数是 Vue 构造器, 第2个参数是可选的 option 对象

MyPlugin.install = function (Vue, options) {
  // 添加全局方法或属性
  Vue.myGlobalMethod = function () {}
  // 添加全局资源
  Vue.directive("my-directive", {
    bind (el, binding, vnode, oldVnode) {}
  })
  // 注入组件
  Vue.mixin({
    created: function () {}
  })
  // 添加实例方法
  Vue.prototype.$myMethod = function (methodOptions) {}
}

通过全局方法 Vue.use() 使用指定插件,使用的时候也可以传入一个 option 对象

Vue.use(MyPlugin, {someOption: true})

vue-router 等插件检测到 Vue 是全局对象时会自动调用 Vue.use(),如果在 CommonJS 模块环境中,则需要显式调用 Vue.use()


十、Vue.mixin(mixin)

使用全局 mixins 将会影响到所有之后创建的 Vue 实例

// 为自定义选项myOption注入一个处理器
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})
new Vue({
  myOption: "AI-fisher"
})

// AI-fisher

十一、Vue.compile(template)

render 函数中编译模板字符串。只在独立构建时有效

var res = Vue.compile('<div><span>{{ msg }}</span></div>')
 
new Vue({
  data: {
    msg: 'hello'
  },
  render: res.render,
  staticRenderFns: res.staticRenderFns
})

十二、Vue.version

获取当前使用的 Vue 版本号,在我们去寻找安装的一些依赖包的时候,需要知道支持的 Vue 版本是什么,所以这个时候就会用到这个方法,其原理就是读取 package.json 中的 version 字段

上一篇:使用$nextTick、$set的原理(双向绑定)


下一篇:Node2-3环境&调试----process(进程)