vue实例方法、全局API、内置组件

实例方法是挂载在Vue的原型上
而全局API是直接在Vue上挂载方法。

实例方法

事件相关

在eventsMixin函数中挂载到Vue原型上的

vm.$on和emit

发布订阅模式

vm.$on( event, callback )
vm.$on('test', function (msg) {
  console.log(msg)
})
vm.$emit('test', 'hi')
//该方法接收的第一个参数是要触发的事件名,之后的附加参数都会传给被触发事件的回调函数。

所有绑定在这个实例上的事件都会存储在实例的_events属性中。输出该属性看一看:

原生事件绑定是通过addEventListener绑定给真实元素的,组件事件绑定是通过Vue自定义的$on实现的。而on是在new Vue()初始化时候挂载到vue原型上的

vm.$off

如果没有提供参数,则移除所有的事件监听器;
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。

vm.$off( [event, callback] )

vm.$once

监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。

Vue.prototype.$once = function (event, fn) {
    const vm: Component = this
    function on () {
        vm.$off(event, on);//取消监听之后执行回调
        fn.apply(vm, arguments)
    }
    on.fn = fn
    vm.$on(event, on)
    return vm
}

生命周期相关

初始化:内部属性watcher…和外部属性
初始化methods中方法时候会检验是否合法
在beforeMount对数据进行更改,不会触发updated。
数据处理一般放在created和mounted
接口请求一般放在mounted中,但需要注意的是服务端渲染时不支持mounted,需要放到created中。

mounted阶段真实dom渲染完成,可以操作dom,

SSR:服务器获取数据之后绑定视图,直接生成html返回前端。SEO性能好

在这里插入图片描述

vue.$options.created其实是一个数组,保存多个钩子函数

$mount

手动挂载 一个未挂载的实例
如果 Vue 实例在实例化时没有收到 el 选项,则它停滞处于“未挂载”状态,没有关联的 DOM 元素。

vm.$mount( [elementOrSelector] )//返回实例自身,因而可以链式调用其它实例方法。

如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API把它插入文档中。

不同构建版本的vue.js的差异主要在于对mount方法的实现

$forceUpdate

迫使vue实例重新渲染

vm.$forceUpdate()
Vue.prototype.$forceUpdate = function () {
    const vm: Component = this
    if (vm._watcher) {
        vm._watcher.update()
    }
}

$nextTick()

vm.$nextTick( [callback] )

方法存在的意义

Vue中对DOM的更新策略:
Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个事件队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到事件队列中一次。这样去除重复数据,避免不必要的计算和 DOM 操作。(所以nextTick很必要)

nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,callback应该放置 对修改后DOM进行操作的 js代码

注意还有全局Vue.nextTick
区别在于:$nextTick 中回调的 this 绑定在调用它的实例上

$destroy

当调用了实例的$destroy方法之后,当前实例就进入了销毁阶段
完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。
触发 beforeDestroy 和 destroyed 的钩子。

vm.$destroy()

全局API

Vue.extend

创建一个继承自Vue类的子类,可接收的参数是一个包含组件选项的对象。
注意:data 选项在 Vue.extend() 中它必须是函数
为什么呢
一个组件被复用多次意味着创建多个实例。本质上,这些实例用的都是同一个构造函数。
如果data是对象的话,对象属于引用类型,被所有的实例共用。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数

Vue.extend( options )

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

注册获取全局指令、过滤器、组件

涉及全局,Vue.options属性很重要
options的五类属性
数据: data, props, propsData, computed, Watch;

DOM: el, template, render, renderError;

声明周期钩子: beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deactivated、beforeDestroy、destroyed、errorCaptured;

资源: directives、filters、components;

组合: parent、mixins、extends、provide、inject;

Vue.directive

用来注册或获取全局指令的
注册指令是将定义好的指令存放在某个位置,获取指令是根据指令id从存放指令的位置来读取指令。

Vue.directive( id, [definition] )

源码实现:
在Vue类上创建了options属性,其属性值为一个空对象,并且在options属性中添加了directives属性,其值也是一个空对象,这个directives属性就是用来存放指令的位置。

自定义指令

Vue对于自定义指令定义对象提供了几个钩子函数,这几个钩子函数分别对应着指令的几种状态,一个指令从第一次被绑定到元素上到最终与被绑定的元素解绑,它会经过以下几种状态:
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。

源码内部是监听虚拟DOM渲染更新的create、update、destory阶段都得处理指令逻辑

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

Vue.filter

注册或获取全局过滤器。


Vue.filter( id, [definition] )

// 注册
Vue.filter('my-filter', function (value) {
  // 返回处理后的值
})

// getter,返回已注册的过滤器
var myFilter = Vue.filter('my-filter')

源码实现:
同全局指令一样,Vue.options[‘filters’]是用来存放全局过滤器的地方。

过滤器(纯函数,无this)

内部工作原理,就是将用户写在模板中的过滤器通过模板编译,编译成_f函数的调用字符串,之后在执行渲染函数的时候会执行_f函数,从而使过滤器生效。
构建

//可以在一个组件的选项中定义本地的过滤器:
filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

//也可以在创建vue实例之后全局
Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

过滤器有两种使用方式,分别是在双花括号插值中和在 v-bind 表达式。

解析过滤器:将过滤器字符串转化成_f(“capitalize”)(message)
v-bind 表达式中的过滤器它属于存在于标签属性中,在HTML解析器parseHTML函数中负责处理标签属性的函数是processAttrs,所以会在processAttrs函数中调用过滤器解析器parseFilters函数对写在该处的过滤器进行解析。
在双花括号中的过滤器它属于存在于标签文本中,在HTML解析器parseHTML函数中,当遇到文本信息时会调用parseHTML函数的chars钩子函数,在chars钩子函数内部又会调用文本解析器parseText函数对文本进行解析,所以会在文本解析器parseText函数中调用过滤器解析器parseFilters函数对写在该处的过滤器进行解析。

使用

//可以串联使用
{{ message | filterA | filterB }}

//过滤器是 JavaScript 函数,因此可以接收参数:
{{ message | filterA('arg1', arg2) }}

<div v-bind:id="rawId | formatId"></div>

Vue.component

注意全局和局部注册两种方式

//全局
Vue.component( id, [definition] )

Vue.component('tab-title',{
   props:['title'],
   template:'<li v-on:click="$emit(\'change\')">{{title}}</li>'
 })

//补充局部

var app=new Vue({
      el: '#app',
     components: {
       'tab-title': {
        props:['info'],//接受父元素传递的参数
        template:'<li v-on:click="$emit(\'addactive\')">{{info}}</li>'//点击时传递通过$emit子元素传递给父元素调用 addactive方法(不能使用驼峰写法)
        }
     },
     methods:{
     },
     data:{
     }
    });

源码实现:
同全局指令一样,Vue.options[‘components’]是用来存放全局组件的地方。

Vue.use安装插件

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

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

import dlg from 'vue-dialog-rexsheng';
Vue.use(dlg);

Vue.mixin

Vue.mixin( mixin )

该API是用来向全局注册一个混入,即可以修改Vue.options属性,并且会影响之后的所有Vue实例,这个API虽然在日常的业务开发中几乎用不到,但是在编写Vue插件时用处非常大。

Vue.observable

Vue.observable( object )

让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象。
返回的对象可以直接用于渲染函数和计算属性内,并且会在发生改变时触发相应的更新。也可以作为最小化的跨组件状态存储器
源码内部是调用了observe方法

Vue.compile

Vue.compile( template )

在 render 函数中编译模板字符串。只在独立构建时有效
源码内部是调用了compileToFunctions方法

Vue.version

用法如下:提供字符串形式的 Vue 安装版本号

Vue.version

建立自己的全局变量

只读的全局变量
定义在其他模块然后导入,OnlyRead作为全局对象来调用

读写的全局变量
在main.js中的data定义,然后添加到原型对象prototype上,每个对象都可以this.引用/修改

import Vue from 'vue';
let OnlyRead = new Vue({
    methods: {
        deleteCookie: function (cname) {
            let d = new Date();
            let expires = "expires=" + d.toGMTString();
            document.cookie = cname + "=; " + expires;
        }
})

export default OnlyRead;

import OnlyRead from "./components/common/comm";
//look at there
OnlyRead.deleteCookie('ms_username')

import Vue from 'vue';

let ReadWrite = new Vue({
    methods: {
        deleteCookie: function (cname) {
            let d = new Date();
            let expires = "expires=" + d.toGMTString();
            document.cookie = cname + "=; " + expires;
        }
})

export default ReadWrite;
Vue.prototype.$ReadWrite = MyComm;
//项目中任何地方都可如此引用 
this.$ReadWrite.deleteCookie('ms_username')

内置组件

keep-alive

组件的定义位于源码的 src/core/components/keep-alive.js 文件

keep-alive的中还运用了LRU(Least Recently Used)算法。

是Vue中内置的一个抽象组件,它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。把组件保存在内存中,而不是直接的销毁,这样做可以保留组件的状态或避免多次重新渲染,以提高页面性能。

<keep-alive>不常变动的组件或者需要缓存的组件用</keep-alive>

还有两个生命周期activated/deactivated,用来得知当前组件是否处于活跃状态。

源码分析:
组件一旦被 < keep-alive> 缓存,那么再次渲染的时候就不会执行 created、mounted 等钩子函数,但是我们很多业务场景都是希望在我们被缓存的组件再次被渲染的时候做一些事情,好在Vue 提供了 activated和deactivated 两个钩子函数,它的执行时机是 < keep-alive> 包裹的组件激活时调用和停用时调用

应用:当用户再次切回组件时保留切走之前的组件状态。
组件可接收三个属性:
include/exclude- 字符串或正则表达式,允许组件有条件的进行缓存,前者匹配缓存,后者反之。
max - 数字。最多可以缓存多少组件实例。

<html>
<head>
  <title>VueJS</title>
</head>
<div id="app">
  <button @click="switchComp('child1')">组件1</button>
  <button @click="switchComp('child2')">组件2</button>
 <keep-alive>
  <component :is="chooseComponent"></component>
</keep-alive>
</div>
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    var child1 = {
      template: '<div>组件1:<input type="text"/></div>',
    }
    var child2 = {
      template: '<div>组件2:<input type="text"/></div>'
    }
    var vm = new Vue({
      el: '#app',
      components: {
        child1,
        child2,
      },
      data() {
        return {
          chooseComponent: 'child1',
        }
      },
      methods: {
        switchComp(component) {
          this.chooseComponent = component;
        }
      }
    })
  </script>
</body>
</html>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面以一个简单的网页内容为例,介绍如何使用Vue.js实现: 1. 数据绑定:使用Vue.js的数据绑定可以将数据和DOM元素进行绑定,实现动态更新。例如,可以在Vue实例中定义data属性,并在HTML模板中使用{{}}语法进行绑定。 2. 内置指令:Vue.js内置了一些指令,可以实现一些常见的操作,例如v-if、v-show、v-for等。这些指令可以用于控制DOM元素的显示或隐藏,以及循环遍历数据等。 3. 事件:可以使用Vue.js的事件绑定来监听DOM元素的事件,例如点击事件、鼠标移动事件等。可以使用v-on指令进行事件绑定。 4. 方法:可以在Vue实例中定义一些方法,用于处理业务逻辑。例如,在事件处理函数中调用方法来更新数据或进行其他操作。 5. 全局APIVue.js提供了一些全局API,例如Vue.component、Vue.directive等。可以使用这些API来自定义组件或指令,扩展Vue.js的功能。 6. 过渡动画:Vue.js提供了过渡动画的支持,可以使用transition组件来实现过渡效果。可以在组件的enter、leave、before-enter等生命周期函数中定义过渡效果。 7. CLI:Vue.js提供了CLI工具,可以快速创建Vue.js项目、打包项目、进行测试等。 8. 路由:可以使用Vue.js的路由功能来实现单页面应用。可以使用Vue Router库来实现路由功能,定义路由表、跳转路由等。 综上所述,使用Vue.js实现网页内容可以大大简化开发流程,提高开发效率。可以使用Vue.js提供的各种功能和API来实现各种需求,同时也可以扩展Vue.js的功能,满足不同的开发需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值