Vue 学习笔记 — 组件初始化
在vue中有3个概念很容易搞混,data,computed,props,特别是我们这些原后端开发人员。
new Vue({ el: "#x", data: { id: 1 }, props: ["id"], computed: { id: function () { return 3; } } });

测试一下,结果是props
和data
无法共存,data
优先级高于computed
;
我经常是吧组件封装成一个extend来使用的,比如这样:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="js/vue2.2.6.js"></script> <script src="js/vCheckBox.js"></script> </head> <body> <input type="checkbox" id="test1" /> <script> var test1 = new vCheckBox({ el: "#test1", data: { text: "测试多选框" } }); </script> </body> </html>
效果:

一开始用的还挺嗨的,直到有一次一个extend用了大量的conputed

然后这个组件对应的文档是这样的:

结果杯具就发生了:
var pager = new vPager({ el: "#pager", data: { pageSize: 10 } });
刚才文章开头说了,data
的优先级是高于computed
的,所以导致pageSize的计算属性被覆盖了,结果可想而知。
所以最后使用的时候改成了这样:
var pager = new vPager({ el: "#pager", created: function () { this.pageSize = 10; } });
但是总感觉很不舒服
所以我决定写一个mixin来优化这个初始化的操作;
var pager = new vPager({ el: "#pager", init: { pageSize: 10 } });
我希望达到这样的效果,无论是data或者computed都可以被赋值
vue.mixin({ created: function () { var init = this.$options.init; if (typeof init === "object") { for (var key in init) { if (init.hasOwnProperty(key) && this.hasOwnProperty(key)) { this[key] = init[key]; } } } } });
这是最初的样子,挺简单的,经过一段时间的使用,又增加了一些功能,最后的变成了这样子:
(function (vue) { if (vue == null) return; vue.config.optionMergeStrategies.init = function (parent, child) { return child; } vue.mixin({ beforeCreate: function () { var opt = this.$options; if (opt.init === undefined) return; if (opt.created == null) { opt.created = []; } var me = this; opt.created.push(init); var hasOnInit = "onInit" in opt.methods; if (!hasOnInit) { opt.methods.onInit = initCallback; } if ("reInit" in opt.methods === false) { opt.methods.reInit = init; } //--- function --- function initCallback(data) { if (hasOnInit && typeof me.onInit === "function") { me.onInit.apply(me, arguments); } setData(data); me.$emit("init", { vm: me, data: data }); } function setData(data) { if (typeof data === "object") { for (var key in data) { if (data.hasOwnProperty(key) && key in me) { me[key] = data[key]; } } } } function init() { var initData = me.$options.init; var callback = initCallback; if (typeof initData === "function") { if (initData.length > 0) { initData = initData.call(me, callback); callback = null; } else { initData = initData.call(me); } } setData(initData); callback && callback(initData); } } }); })(window.Vue);
这是个全局的mixin,为每个存在init选项的Vue实例添加init功能
init功能:
- 如果init选项为
object
,则使用init选项的值初始化Vue实例的字段,并触发init
事件; - 如果init选项为无参的
function
,执行function后使用返回值初始化Vue实例字段,并触发init
事件; - 如果init选项为有参的
function
,则会传入一个回调函数,执行回调函数会触发init
事件,可以在init函数中直接返回初始值也可以在回调函数中传入初始值; - 为Vue添加一个函数
reInit()
,用于使用原始init选项重新初始化对象并触发init
事件(对象存在reInit成员该功能无效); - 为Vue添加一个函数
onInit(data)
,用于使用data参数初始化对象并触发init
事件;
关闭init功能
要关闭init功能也可以在初始化时将init:undefined
,为此需要专门写一个合并选项策略
Vue.config.optionMergeStrategies.init = function (parent, child) { return child; }
策略比较粗暴,直接让子选项覆盖父选项;
除了最初的初始化属性的功能以外还支持init为function的情况:
init 为无参的`function
var pager = new vPager({ el: "#pager", init: function() { var p = location.search.slice(1).split(','); return { pageNumber: p[0] || 1, pageSize: p[1] || 20 } } });
init 为有参的`function,直接返回初始化数据,延迟触发回调
var pager = new vPager({ el: "#pager", init: function (callback) { $.ajax({ ... , context: this }).done(function (data) { this.pageNumber = data.pageNumber; this.pageSize = data.pageSize; callback(); }); return { pageNumber: 1, pageSize: 20 } } });
init 为有参的`function,延迟传入初始化数据并触发回调
var pager = new vPager({ el: "#pager", init: function (callback) { $.ajax({ ... , context: this }).done(function (data) { callback({ data.pageNumber, data.pageSize }); }); } });
init 事件
触发 init 事件
vm.$emit("init", { vm: vm, data: initData })
订阅 init 事件
vm.$on("init", function(event){ event.vm ... event.initData ... })
我写的文章,除了纯代码,其他的都是想表达一种思想,一种解决方案.希望各位看官不要局限于文章中的现成的代码,要多关注整个文章的主题思路,谢谢!
我发布的代码,没有任何版权,遵守WTFPL协议(如有引用,请遵守被引用代码的协议)
qq群:5946699 希望各位喜爱C#的朋友可以在这里交流学习,分享编程的心得和快乐
我发布的代码,没有任何版权,遵守WTFPL协议(如有引用,请遵守被引用代码的协议)
qq群:5946699 希望各位喜爱C#的朋友可以在这里交流学习,分享编程的心得和快乐
分类:
javascript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库