We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
思考来源: vue-cli对于异步请求数据的时候,通过methods, created, data这三步,觉得实在是太过于复杂,能不能有一个计算属性,可以直接得到值,从而在模板中使用。
methods
created
data
在github上面搜索得到大牛已经实现了 asyncComputed, 别人捷足先登了。楼主决定先看一遍它的源码,之后会对他的源码进行拓展。
插件通常会为Vue添加全局功能,插件的范围没有限制。
1.1.1定义插件:Vue.js的插件使用的install() 。这个方法的第一个参数是Vue构造器,第二个参数是一个可选的对象:
install()
// myplugin.js const plugins = { install(Vue, myOptions) { // 通过this.$options.asyncComputed可以获取Vue实例中绑定的方法 Vue.config.optionMergeStrategies.asyncComputed = Vue.config.optionMergeStrategies.computed Vue.prototype.$myMethods = function() { console.log(`这是原型上面的方法,可以听过this.$myMethods调用`); } } }
1.1.2使用插件 : Vue通过全局Vue.use(obj||fn) 来安装vue的插件
Vue.use(obj||fn)
import myplugin from './myplugin.js' Vue.use(myplugin)
**1.1.3Vue.use结合install直接使用: **
Vue.use({ install(Vue,myOptions) { Vue.prototype.$myMethods = function() { console.log(`这是原型上面的方法,可以听过this.$myMethods调用`); } Vue.mixin({ created(){ console.log(this.$option) } }) } })
我们通过computed拓展得到asyncComputed,这里通过computed拓展主要是方便记忆和基于computed的缓存机制方便存放数据和状态。
// asyncComputed.js const AsyncComputed = { install(Vue,pluginOptions) { pluginOptions = pluginOptions || {} //这里是额外的选择 // 下面通过自定义混合得到了asyncComputed, 可以在Vue实例中使用asyncComputed属性 Vue.config.optionMergeStrategies.asyncComputed = Vue.config.optionMergeStrategies.computed } }
使用 : app.vue
export default { ... asyncComputed: { type() { return axios.get('http://rap.taobao.org/mockjsdata/24170/category/topList').then(res => res.data.lists) } }, }
**配置: ** 我们可以通过Vue.mixin 来混合配置
2.2-1 asyncComputed.js
//asyncComputed.js // 得到所有的asyncComputed中的函数 function getterFor (fn) { // 如果是函数的话,直接返回 if (typeof fn === 'function') return fn // 如果不是函数的话,得到对象的get的值 => 其实也是一个函数 let getter = fn.get // 判定fn这个对象是否又watch属性 if (fn.hasOwnProperty('watch')) { getter = function getter () { fn.watch.call(this) return fn.get.call(this) } } // 最后总是返回一个函数 return getter } // 得到默认的配置 function defaultFor (fn, pluginOptions) { // 已经被制定了this是Vue实例 let defaultValue = null // 看是否有默认值 if ('default' in fn) { defaultValue = fn.default } else if ('default' in pluginOptions) { defaultValue = pluginOptions.default } // 如果默认值是一个函数的话,执行函数并返回 if (typeof defaultValue === 'function') { return defaultValue.call(this) } else { return defaultValue } }
2.2-2 asyncComputed.js中的 Vue.mixin({})中的beforeCreate()
//asyncComputed.js const prefix = '_async_computed$' const AsyncComputed = { install(Vue,pluginOptions) { pluginOptions = pluginOptions || {} //这里是额外的选择 // 下面通过自定义混合得到了asyncComputed, 可以在Vue实例中使用asyncComputed属性 Vue.config.optionMergeStrategies.asyncComputed = Vue.config.optionMergeStrategies.computed } Vue.mixin({ beforeCreate () { // 获取每一个vue组件数据 const optionData = this.$options.data // 如果没有配置计算属性,就赋值为一个空对象 if (!this.$options.computed) { this.$options.computed = {} } // 循环asyncComputed 对象 for (const key in this.$options.asyncComputed || {}) { // this.$options.asyncComputed[key] 得到对应的函数 this.$options.computed[prefix + key] = getterFor(this.$options.asyncComputed[key]) } this.$options.data = function vueAsyncComputedInjectedDataFn () { const data = ( // 如果是一个函数的话直接执行,不是的直接返回数据 (typeof optionData === 'function') ? optionData.call(this) : optionData ) || {} for (const key in this.$options.asyncComputed || {}) { // 给data初始化值,把asyncComputed的名字赋值给this.$options.data data[key] = null } return data } }, }) }
这里beforeCreate() 钩子函数初始化数据null,并没有得到数据。
optionData: 得到每一个对应实例中的data(函数或者对象)
optionData
this.$options.computed[prefix + key] 给实例的computed 添加函数 ;
this.$options.computed[prefix + key]
computed
this.$options.data 给Vue实例化组件添加data方法(一个函数,在created()的时候执行)
this.$options.data
created()
2.2-3 asyncComputed.js中的 Vue.mixin({})中的Created()
created () { // 处理默认值 for (const key in this.$options.asyncComputed || {}) { // 把对应的函数,额外的选择都传递给函数defaultFor this[key] = defaultFor.call(this, this.$options.asyncComputed[key], pluginOptions) } for (const key in this.$options.asyncComputed || {}) { // 给每一个asyncComputed匹配一个id let promiseId = 0 // console.log(this.$watch) this.$watch(prefix + key, newPromise => { const thisPromise = ++promiseId // 如果newPromise或者newPromise.then也不存在,就返回一个promise if (!newPromise || !newPromise.then) { newPromise = Promise.resolve(newPromise) } // 如果已经存在一个promise newPromise.then(value => { if (thisPromise !== promiseId) return this[key] = value }).catch(err => { // 错误处理 if (thisPromise !== promiseId) return if (pluginOptions.errorHandler === false) return const handler = (pluginOptions.errorHandler === undefined) ? console.error.bind(console, 'Error evaluating async computed property:') : pluginOptions.errorHandler if (pluginOptions.useRawError) { handler(err) } else { handler(err.stack) } }) }, { immediate: true }) } }
检查是否存在默认值,如果有的话,给实例添加属性,值是对应的值
for (const key in this.$options.asyncComputed || {}) { // 把对应的函数,额外的选择都传递给函数defaultFor this[key] = defaultFor.call(this, this.$options.asyncComputed[key], pluginOptions) }
监听(this.$watch) this.$options.$computed中的所有属性, 如果已经是一个promise,就直接给覆盖beforeCreate()中初始化的this[key]的值。如果不是一个promise函数,则直接执行并返回一个promise函数
this.$watch
this.$options.$computed
this[key]
this.$watch(prefix + key, newPromise => { const thisPromise = ++promiseId // 如果newPromise或者newPromise.then也不存在,就返回一个promise if (!newPromise || !newPromise.then) { newPromise = Promise.resolve(newPromise) } // 如果已经存在一个promise newPromise.then(value => { if (thisPromise !== promiseId) return this[key] = value }) }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
asyncComputed源码解析
在github上面搜索得到大牛已经实现了 asyncComputed, 别人捷足先登了。楼主决定先看一遍它的源码,之后会对他的源码进行拓展。
1. Vue的install()方法和Vue.use()
1.1开发插件
1.1.1定义插件:Vue.js的插件使用的
install()
。这个方法的第一个参数是Vue构造器,第二个参数是一个可选的对象:1.1.2使用插件 : Vue通过全局
Vue.use(obj||fn)
来安装vue的插件**1.1.3Vue.use结合install直接使用: **
2. 解析asyncComputed
2.1 通过自定义混合得到asyncComputed
2.2 asyncComputed的使用和配置
使用 : app.vue
**配置: ** 我们可以通过Vue.mixin 来混合配置
2.2-1 asyncComputed.js
2.2-2 asyncComputed.js中的 Vue.mixin({})中的beforeCreate()
这里beforeCreate() 钩子函数初始化数据null,并没有得到数据。
optionData
: 得到每一个对应实例中的data(函数或者对象)this.$options.computed[prefix + key]
给实例的computed
添加函数 ;this.$options.data
给Vue实例化组件添加data方法(一个函数,在created()
的时候执行)2.2-3 asyncComputed.js中的 Vue.mixin({})中的Created()
检查是否存在默认值,如果有的话,给实例添加属性,值是对应的值
监听(
this.$watch
)this.$options.$computed
中的所有属性, 如果已经是一个promise,就直接给覆盖beforeCreate()中初始化的this[key]
的值。如果不是一个promise函数,则直接执行并返回一个promise函数全部代码链接
The text was updated successfully, but these errors were encountered: