【Vue2.0源码学习】全局API篇-Vue中全局API分析

这篇具有很好参考价值的文章主要介绍了【Vue2.0源码学习】全局API篇-Vue中全局API分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0. 前言

与实例方法不同,实例方法是将方法挂载到Vue的原型上,而全局API是直接在Vue上挂载方法。在Vue中,全局API一共有12个,分别是Vue.extendVue.nextTickVue.setVue.deleteVue.directiveVue.filterVue.componentVue.useVue.mixinVue.observableVue.version。这12个API中有的是我们在日常业务开发中经常会用到的,有的是对Vue内部或外部插件提供的,我们在日常业务开发中几乎用不到。接下来我们就对这12个API逐个进行分析,看看其内部原理都是怎样的。

1. Vue.extend

1.1 用法回顾

其用法如下:

Vue.extend( options )
  • 参数

    • {Object} options
  • 作用

    使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。

    data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数

    <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')
    

    结果如下:

    <p>Walter White aka Heisenberg</p>
    

1.2 原理分析

通过用法回顾我们知道,Vue.extend的作用是创建一个继承自Vue类的子类,可接收的参数是一个包含组件选项的对象。

既然是Vue类的子类,那么除了它本身独有的一些属性方法,还有一些是从Vue类中继承而来,所以创建子类的过程其实就是一边给子类上添加上独有的属性,一边将父类的公共属性复制到子类上。接下来,我们就来看看源码是如何实现这个过程的。

该API的定义位于源码的src/core/global-api/extend.js中,如下:

Vue.extend = function (extendOptions: Object): Function {
    extendOptions = extendOptions || {}
    const Super = this
    const SuperId = Super.cid
    const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
    if (cachedCtors[SuperId]) {
        return cachedCtors[SuperId]
    }

    const name = extendOptions.name || Super.options.name
    if (process.env.NODE_ENV !== 'production' && name) {
        validateComponentName(name)
    }

    const Sub = function VueComponent (options) {
        this._init(options)
    }
    Sub.prototype = Object.create(Super.prototype)
    Sub.prototype.constructor = Sub
    Sub.cid = cid++
    Sub.options = mergeOptions(
        Super.options,
        extendOptions
    )
    Sub['super'] = Super

    if (Sub.options.props) {
        initProps(Sub)
    }
    if (Sub.options.computed) {
        initComputed(Sub)
    }

    // allow further extension/mixin/plugin usage
    Sub.extend = Super.extend
    Sub.mixin = Super.mixin
    Sub.use = Super.use

    // create asset registers, so extended classes
    // can have their private assets too.
    ASSET_TYPES.forEach(function (type) {
        Sub[type] = Super[type]
    })
    // enable recursive self-lookup
    if (name) {
        Sub.options.components[name] = Sub
    }

    Sub.superOptions = Super.options
    Sub.extendOptions = extendOptions
    Sub.sealedOptions = extend({}, Sub.options)

    // cache constructor
    cachedCtors[SuperId] = Sub
    return Sub
}

可以看到,虽然代码量稍微有点多,但是逻辑并不复杂,下面我们就来逐行分析一下。

首先,该函数内部定义了几个变量,如下:

extendOptions = extendOptions || {}
const Super = this
const SuperId = Super.cid
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
  • extendOptions:用户传入的一个包含组件选项的对象参数;
  • Super:指向父类,即基础 Vue类;
  • SuperId:父类的cid属性,无论是基础 Vue类还是从基础 Vue类继承而来的类,都有一个cid属性,作为该类的唯一标识;
  • cachedCtors:缓存池,用于缓存创建出来的类;

接着,在缓存池中先尝试获取是否之前已经创建过的该子类,如果之前创建过,则直接返回之前创建的。之所以有这一步,是因为Vue为了性能考虑,反复调用Vue.extend其实应该返回同一个结果,只要返回结果是固定的,就可以将结果缓存,再次调用时,只需从缓存中取出结果即可。在API方法定义的最后,当创建完子类后,会使用父类的cid作为key,创建好的子类作为value,存入缓存池cachedCtors中。如下:

if (cachedCtors[SuperId]) {
    return cachedCtors[SuperId]
}

接着,获取到传入的选项参数中的name字段,并且在开发环境下校验name字段是否合法,如下:

const name = extendOptions.name || Super.options.name
if (process.env.NODE_ENV !== 'production' && name) {
    validateComponentName(name)
}

接着,创建一个类Sub,这个类就是将要继承基础Vue类的子类,如下:

const Sub = function VueComponent (options) {
    this._init(options)
}

到这里,我们已经把类创建好了,接下来的工作就是让该类去继承基础Vue类,让其具备一些基础Vue类的能力。

首先,将父类的原型继承到子类中,并且为子类添加唯一标识cid,如下:

Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
Sub.cid = cid++

接着,将父类的options与子类的options进行合并,将合并结果赋给子类的options属性,如下:

Sub.options = mergeOptions(
    Super.options,
    extendOptions
)

接着,将父类保存到子类的super属性中,以确保在子类中能够拿到父类,如下:

Sub['super'] = Super

接着,如果选项中存在props属性,则初始化它,如下:

if (Sub.options.props) {
    initProps(Sub)
}

function initProps (Comp) {
  const props = Comp.options.props
  for (const key in props) {
    proxy(Comp.prototype, `_props`, key)
  }
}

初始化props属性其实就是把参数中传入的props选项代理到原型的_props中。

接着,如果选项中存在computed属性,则初始化它,如下:

if (Sub.options.computed) {
    initComputed(Sub)
}

function initComputed (Comp) {
  const computed = Comp.options.computed
  for (const key in computed) {
    defineComputed(Comp.prototype, key, computed[key])
  }
}

初始化props属性就是遍历参数中传入的computed选项,将每一项都调用defineComputed函数定义到子类原型上。此处的defineComputed函数与我们之前在生命周期初始化阶段initState中所介绍的defineComputed函数是一样的。

接着,将父类中的一些属性复制到子类中,如下:

Sub.extend = Super.extend
Sub.mixin = Super.mixin
Sub.use = Super.use

export const ASSET_TYPES = [
  'component',
  'directive',
  'filter'
]
// create asset registers, so extended classes
// can have their private assets too.
ASSET_TYPES.forEach(function (type) {
    Sub[type] = Super[type]
})
// enable recursive self-lookup
if (name) {
    Sub.options.components[name] = Sub
}

接着,给子类新增三个独有的属性,如下:

Sub.superOptions = Super.options
Sub.extendOptions = extendOptions
Sub.sealedOptions = extend({}, Sub.options)

最后,使用父类的cid作为key,创建好的子类Sub作为value,存入缓存池cachedCtors中。如下:

// cache constructor
cachedCtors[SuperId] = Sub

最终将创建好的子类Sub返回。

以上,就是Vue.extend的所有逻辑。其实总体来讲,整个过程就是先创建一个类Sub,接着通过原型继承的方式将该类继承基础Vue类,然后给Sub类添加一些属性以及将父类的某些属性复制到Sub类上,最后将Sub类返回。

2. Vue.nextTick

2.1 用法回顾

其用法如下:

Vue.nextTick( [callback, context] )
  • 参数

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

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

    // 修改数据
    vm.msg = 'Hello'
    // DOM 还没有更新
    Vue.nextTick(function () {
      // DOM 更新了
    })
    
    // 作为一个 Promise 使用 (2.1.0 起新增,详见接下来的提示)
    Vue.nextTick()
      .then(function () {
        // DOM 更新了
      })
    

    2.1.0 起新增:如果没有提供回调且在支持 Promise 的环境中,则返回一个 Promise。请注意 Vue 不自带 Promise 的 polyfill,所以如果你的目标浏览器不原生支持 Promise (IE:你们都看我干嘛),你得自己提供 polyfill。

2.2 原理分析

该API的原理同实例方法 $nextTick原理一样,此处不再重复。唯一不同的是实例方法 $nextTick 中回调的 this 绑定在调用它的实例上。

3. Vue.set

3.1 用法回顾

其用法如下:

Vue.set( target, propertyName/index, value )
  • 参数

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

  • 作用

    向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi')

3.2 原理分析

该API的原理同实例方法 $set原理一样,此处不再重复。

4. Vue.delete

4.1 用法回顾

其用法如下:

Vue.delete( target, propertyName/index )
  • 参数

    • {Object | Array} target
    • {string | number} propertyName/index

    仅在 2.2.0+ 版本中支持 Array + index 用法。

  • 作用

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

    在 2.2.0+ 中同样支持在数组上工作。

4.2 原理分析

该API的原理同实例方法 $delete原理一样,此处不再重复。

5. Vue.directive

5.1 用法回顾

其用法如下:

Vue.directive( id, [definition] )
  • 参数

    • {string} id
    • {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')
    

5.2 原理分析

从用法回顾中可以知道,该API是用来注册或获取全局指令的,接收两个参数:指令id和指令的定义。这里需要注意一点的是:注册指令是将定义好的指令存放在某个位置,获取指令是根据指令id从存放指令的位置来读取指令。至于如何让指令生效的问题我们会在指令篇单独展开介绍。

下面我们就来看一下该API的内部实现原理,其代码如下:

Vue.options = Object.create(null)
Vue.options['directives'] = Object.create(null)

Vue.directive= function (id,definition) {
    if (!definition) {
        return this.options['directives'][id]
    } else {
        if (type === 'directive' && typeof definition === 'function') {
            definition = { bind: definition, update: definition }
        }
        this.options['directives'][id] = definition
        return definition
    }
}

可以看到,我们在Vue类上创建了options属性,其属性值为一个空对象,并且在options属性中添加了directives属性,其值也是一个空对象,这个directives属性就是用来存放指令的位置。如下:

Vue.options = Object.create(null)
Vue.options['directives'] = Object.create(null)

前文我们说了,该API可以用来注册或获取全局指令,这两种功能的切换取决于是否传入了definition参数。如果没有传入definition参数,则表示为获取指令,那么就从存放指令的地方根据指令id来读取指令并返回,如下:

if (!definition) {
    return this.options['directives'][id]
}

如果传入了definition参数,则表示为注册指令,那么继续判断definition参数是否是一个函数,如果是函数,则默认监听bindupdate两个事件,即将definition函数分别赋给bindupdate两个属性。如下:

if (type === 'directive' && typeof definition === 'function') {
    definition = { bind: definition, update: definition }
}

如果definition参数不是一个函数,那么即认为它是用户自定义的指令对象,直接将其保存在this.options['directives']中,如下:

this.options['directives'][id] = definition

以上,就是Vue.directives的所有逻辑。

6. Vue.filter

6.1 用法回顾

其用法如下:

Vue.filter( id, [definition] )
  • 参数

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

    注册或获取全局过滤器。

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

6.2 原理分析

从用法回顾中可以知道,该API是用来注册或获取全局过滤器的,接收两个参数:过滤器id和过滤器的定义。同全局指令一样,注册过滤器是将定义好的过滤器存放在某个位置,获取过滤器是根据过滤器id从存放过滤器的位置来读取过滤器。至于如何让过滤器生效的问题我们会在过滤器篇单独展开介绍。

下面我们就来看一下该API的内部实现原理,其代码如下:

Vue.options = Object.create(null)
Vue.options['filters'] = Object.create(null)

Vue.filter= function (id,definition) {
    if (!definition) {
        return this.options['filters'][id]
    } else {
        this.options['filters'][id] = definition
        return definition
    }
}

可以看到,同全局指令一样,Vue.options['filters']是用来存放全局过滤器的地方。还是根据是否传入了definition参数来决定本次操作是注册过滤器还是获取过滤器。如果没有传入definition参数,则表示本次操作为获取过滤器,那么就从存放过滤器的地方根据过滤器id来读取过滤器并返回;如果传入了definition参数,则表示本次操作为注册过滤器,那就直接将其保存在this.options['filters']中。

7. Vue.component

7.1 用法回顾

其用法如下:

Vue.component( id, [definition] )
  • 参数

    • {string} id
    • {Function | Object} [definition]
  • 作用

    注册或获取全局组件。注册还会自动使用给定的id设置组件的名称

    // 注册组件,传入一个扩展过的构造器
    Vue.component('my-component', Vue.extend({ /* ... */ }))
    
    // 注册组件,传入一个选项对象 (自动调用 Vue.extend)
    Vue.component('my-component', { /* ... */ })
    
    // 获取注册的组件 (始终返回构造器)
    var MyComponent = Vue.component('my-component')
    

7.2 原理分析

从用法回顾中可以知道,该API是用来注册或获取全局组件的,接收两个参数:组件id和组件的定义。 同全局指令一样,注册全局组件是将定义好的组件存放在某个位置,获取组件是根据组件id从存放组件的位置来读取组件。

下面我们就来看一下该API的内部实现原理,其代码如下:

Vue.options = Object.create(null)
Vue.options['components'] = Object.create(null)

Vue.filter= function (id,definition) {
    if (!definition) {
        return this.options['components'][id]
    } else {
        if (process.env.NODE_ENV !== 'production' && type === 'component') {
            validateComponentName(id)
        }
        if (type === 'component' && isPlainObject(definition)) {
            definition.name = definition.name || id
            definition = this.options._base.extend(definition)
        }
        this.options['components'][id] = definition
        return definition
    }
}

可以看到,同全局指令一样,Vue.options['components']是用来存放全局组件的地方。还是根据是否传入了definition参数来决定本次操作是注册组件还是获取组件。如果没有传入definition参数,则表示本次操作为获取组件,那么就从存放组件的地方根据组件id来读取组件并返回;如果传入了definition参数,则表示本次操作为注册组件,如果是注册组件,那么在非生产环境下首先会校验组件的name值是否合法,如下:

if (process.env.NODE_ENV !== 'production' && type === 'component') {
    validateComponentName(id)
}

接着,判断传入的definition参数是否是一个对象,如果是对象,则使用Vue.extend方法将其变为Vue的子类,同时如果definition对象中不存在name属性时,则使用组件id作为组件的name属性。如下:

if (type === 'component' && isPlainObject(definition)) {
    definition.name = definition.name || id
    definition = this.options._base.extend(definition)
}

最后,将注册好的组件保存在this.options['components']中。

8 directive、filter、component小结

通过对Vue.directiveVue.filterVue.component这三个API的分析,细心的你肯定会发现这三个API的代码实现非常的相似,是的,这是我们为了便于理解故意拆开的,其实在源码中这三个API的实现是写在一起的,位于源码的src/core/global-api/index,jssrc/core/global-api/assets,js中,如下:

export const ASSET_TYPES = [
  'component',
  'directive',
  'filter'
]

Vue.options = Object.create(null)
ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
})

ASSET_TYPES.forEach(type => {
    Vue[type] = function (id,definition) {
        if (!definition) {
            return this.options[type + 's'][id]
        } else {
            if (process.env.NODE_ENV !== 'production' && type === 'component') {
                validateComponentName(id)
            }
            if (type === 'component' && isPlainObject(definition)) {
                definition.name = definition.name || id
                definition = this.options._base.extend(definition)
            }
            if (type === 'directive' && typeof definition === 'function') {
                definition = { bind: definition, update: definition }
            }
            this.options[type + 's'][id] = definition
            return definition
        }
    }
})

9. Vue.use

9.1 用法回顾

其用法如下:

Vue.use( plugin )
  • 参数

    • {Object | Function} plugin
  • 作用

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

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

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

9.2 原理分析

从用法回顾中可以知道,该API是用来安装Vue.js插件的。并且我们知道了,该API内部会调用插件提供的install 方法,同时将Vue 作为参数传入。另外,由于插件只会被安装一次,所以该API内部还应该防止 install 方法被同一个插件多次调用。下面我们就来看一下该API的内部实现原理。

该API的定义位于源码的src/core/global-api/use.js中,代码如下:

Vue.use = function (plugin) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
        return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
        plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
        plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
}

可以看到,在该函数内部,首先定义了一个变量installedPlugins,该变量初始值是一个空数组,用来存储已安装过的插件。首先判断传入的插件是否存在于installedPlugins数组中(即已被安装过),如果存在的话,则直接返回,防止重复安装。如下:

const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
    return this
}

接下来获取到传入的其余参数,并且使用toArray方法将其转换成数组,同时将Vue插入到该数组的第一个位置,这是因为在后续调用install方法时,Vue必须作为第一个参数传入。如下:

const args = toArray(arguments, 1)
args.unshift(this)

在用法回顾中说了,传入的插件可以是一个提供了 install 方法的对象。也可以是一个函数,那么这个函数会被作为 install 方法。所以在接下来会根据这两种不同的情况分别处理。

首先,判断传入的插件如果是一个提供了 install 方法的对象,那么就执行该对象中提供的 install 方法并传入参数完成插件安装。如下:

if (typeof plugin.install === 'function') {
    plugin.install.apply(plugin, args)
}

如果传入的插件是一个函数,那么就把这个函数当作install方法执行,同时传入参数完成插件安装。如下:

else if (typeof plugin === 'function') {
    plugin.apply(null, args)
}

插件安装完成之后,将该插件添加进已安装插件列表中,防止重复安装。如下:

installedPlugins.push(plugin)

以上,就是Vue.use的所有逻辑。

10. Vue.mixin

10.1 用法回顾

其用法如下:

Vue.mixin( mixin )
  • 参数

    • {Object} mixin
  • 作用

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

10.2 原理分析

从用法回顾中可以知道,该API是用来向全局注册一个混入,即可以修改Vue.options属性,并且会影响之后的所有Vue实例,这个API虽然在日常的业务开发中几乎用不到,但是在编写Vue插件时用处非常大。下面我们就来看一下该API的内部实现原理。

该API的定义位于源码的src/core/global-api/mixin.js中,代码如下:

Vue.mixin = function (mixin: Object) {
    this.options = mergeOptions(this.options, mixin)
    return this
}

可以看到,该API的实现非常简单。因为上文中我们说了,该API就是通过修改Vue.options属性进而影响之后的所有Vue实例。所以我们只需将传入的mixin对象与this.options合并即可,然后将合并后的新对象作为this.options传给之后的所有Vue实例,从而达到改变其原有特性的效果。

11. Vue.compile

11.1 用法回顾

其用法如下:

Vue.compile( template )
  • 参数

    • {string} template
  • 作用

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

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

11.2 原理分析

从用法回顾中可以知道,该API是用来编译模板字符串的,我们在日常业务开发中几乎用不到,它内部是调用了compileToFunctions方法,如下:

Vue.compile = compileToFunctions;

关于compileToFunctions方法在模板编译篇已经做了非常详细的介绍,此处不再重复。

12. Vue.observable

12.1 用法回顾

其用法如下:

Vue.observable( object )
  • 参数

    • {Object} object
  • 用法

    让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象。

    返回的对象可以直接用于渲染函数计算属性内,并且会在发生改变时触发相应的更新。也可以作为最小化的跨组件状态存储器,用于简单的场景:

    const state = Vue.observable({ count: 0 })
    
    const Demo = {
      render(h) {
        return h('button', {
          on: { click: () => { state.count++ }}
        }, `count is: ${state.count}`)
      }
    }
    

12.2 原理分析

从用法回顾中可以知道,该API是用来将一个普通对象转化成响应式对象。在日常业务开发中也几乎用不到,它内部是调用了observe方法,关于该方法在数据变化侦测篇已经做了非常详细的介绍,此处不再重复。

13. Vue.version

13.1 用法回顾

其用法如下:

Vue.version
  • 细节:提供字符串形式的 Vue 安装版本号。这对社区的插件和组件来说非常有用,你可以根据不同的版本号采取不同的策略。

  • 用法

    var version = Number(Vue.version.split('.')[0])
    
    if (version === 2) {
      // Vue v2.x.x
    } else if (version === 1) {
      // Vue v1.x.x
    } else {
      // Unsupported versions of Vue
    }
    

13.2 原理分析

从用法回顾中可以知道,该API是用来标识当前构建的Vue.js的版本号,对于日常业务开发几乎用不到,但是对于插件编写非常有用,可以根据Vue版本的不同从而做一些不同的事情。

该API是在构建时读取了package.json中的version字段,然后将其赋值给Vue.version文章来源地址https://www.toymoban.com/news/detail-482339.html

到了这里,关于【Vue2.0源码学习】全局API篇-Vue中全局API分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Vue2.0源码学习】指令篇-Vue自定义指令

    在 Vue 中,除了 Vue 本身为我们提供的一些内置指令之外, Vue 还支持用户自定义指令。并且用户有两种定义指令的方式:一种是使用全局API—— Vue.directive 来定义全局指令,这种方式定义的指令会被存放在 Vue.options[\\\'directives\\\'] 中;另一种是在组件内的 directive 选项中定义专为

    2024年02月09日
    浏览(44)
  • 开始学习vue2(Vue方法)

    一、过滤器 过滤器 ( Filters )是 vue 为开发者提供的功能,常用于 文本的格式  化 。过滤器可以用在两个地方: 插值表达式 和 v- bind   属性绑定 。 过滤器应该被添加在 JavaScript 表达式的 尾部 ,由“ 管道符   ”进行 调用,示例代码如下 : 1、定义过滤器 在创建 vue 实例

    2024年01月24日
    浏览(35)
  • 【Vue2.0源码学习】生命周期篇-初始化阶段(initInjections)

    本篇文章介绍生命周期初始化阶段所调用的第四个初始化函数—— initInjections 。从函数名字上来看,该函数是用来初始化实例中的 inject 选项的。说到 inject 选项,那必然离不开 provide 选项,这两个选项都是成对出现的,它们的作用是:允许一个祖先组件向其所有子孙后代注

    2024年02月09日
    浏览(50)
  • 【Vue2.0源码学习】生命周期篇-初始化阶段(initState)

    本篇文章介绍生命周期初始化阶段所调用的第五个初始化函数—— initState 。 从函数名字上来看,这个函数是用来初始化实例状态的,那么什么是实例的状态呢?在前面文章中我们略有提及,在我们日常开发中,在 Vue 组件中会写一些如 props 、 data 、 methods 、 computed 、 watc

    2024年02月09日
    浏览(53)
  • 前端vue2 全局水印效果

    最近写项目遇到一个需求,全局显示水印,不管在哪个路由都要显示。 想要实现的效果: 新建shuiyin.js文件 main.js中全局注册

    2024年02月15日
    浏览(50)
  • vscode vue2 + volar 全局代码提示

    这几天更新vscode vetur的后  项目一直转loading加载不出来了,索性就直接换volar了。 一、基础配置 但是volar的配置在vue3和vue2里是不太一样的   需要一些额外的配置。记录一下踩坑。 首先vscode安装扩展 Vue Language Features (Volar) 、 TypeScript Vue Plugin (Volar)  并且卸载或者禁用掉原

    2024年02月16日
    浏览(43)
  • Vue2封装自定义全局Loading组件

    前言 在开发的过程中,点击提交按钮,或者是一些其它场景总会遇到Loading加载框,PC的一些UI库也没有这样的加载框,无法满足业务需求,因此可以自己自定义一个,实现过程如下。 效果图 如何封装? 第1步:创建要封装成全局组件的文件 第2步:注册组件 Loading这类的通用

    2024年02月15日
    浏览(38)
  • Vue学习计划-Vue2--VueCLi(二)vuecli脚手架创建的项目内部主要文件分析

    1. 补充: 什么叫单文件组件? 一个文件中只有一个组件 vue-cli 创建的项目中, .vue 的文件都是单文件组件,例如 App.vue 2. 进入分析 1. package.json : 项目依赖配置文件: 如图,我们说主要的属性: name : 项目的名称 version : 项目版本 scripts : 脚本入口 serve : 启动项目命令 build :

    2024年02月04日
    浏览(77)
  • uniapp引入全局js,vue2/vue3不同方式引入

    Hi I’m Shendi uniapp引入全局js,vue2/vue3不同方式引入 最近写小程序,个人开发,选用了 uni-app 进行开发 选用的 vue3 版本 因为我用的 vue3 版本,在这里踩了没学过vue3的坑,用vue2引入全局js的方式使用,导致undefined… Vue2 版引入全局js的方法如下 将js放到项目内,一般放到自建的

    2024年02月03日
    浏览(63)
  • Github 用户查询案例【基于Vue2全局事件总线通信】

            本次案例是一个基于 Vue2 的全局事件总线通信的仿 Github 用户搜索模块,使用的接口是 Github 官方提供的搜索接口: https://api.github.com/search/users?q=xxx(发送请求时需要将输入的用户名称绑定替换掉xxx),如果对全局事件总线不太熟练的小伙伴可以看这篇文章: http:/

    2024年02月03日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包