简书

在vue中有3个概念很容易搞混,data,computed,props,特别是我们这些原后端开发人员。

new Vue({
el: "#x",
data: { id: 1 },
props: ["id"],
computed: {
id: function () { return 3; }
}
});

测试一下,结果是propsdata无法共存,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 ...
})

Vue 学习笔记 — 组件初始化的更多相关文章

  1. Vue学习笔记-组件通信-子传父(自定义事件)

    props用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中.我们应该如何处理呢?这个时候,我们需要使用自定义事件来完成.什么时候需要自定义事件呢?当子组件需要向父组件传递 ...

  2. vue学习笔记——组件的优化

    Vue 应用性能优化指南 1 给组件定义name,然后在同级目录新建index文件: import Count from './count.vue' export Count; 2 优化大数据的列表 ...

  3. Vue学习笔记-组件通信-父传子(props中的驼峰标识)

    在组件中,使用选项props来声明需要从父级接收到的数据.props的值有两种方式:方式一:字符串数组,数组中的字符串就是传递时的名称.方式二:对象,对象可以设置传递时的类型,也可以设置默认值等. & ...

  4. vue学习笔记(八)组件校验&通信

    前言 在上一章博客的内容中vue学习笔记(七)组件我们初步的认识了组件,并学会了如何定义局部组件和全局组件,上一篇内容仅仅只是对组件一个简单的入门,并没有深入的了解组件当中的其它机制,本篇博客将会带大 ...

  5. vue学习笔记(九)vue-cli中的组件通信

    前言 在上一篇博客vue学习笔记(八)组件校验&通信中,我们学会了vue中组件的校验和父组件向子组件传递信息以及子组件通知父组件(父子组件通信),上一篇博客也提到那是对组件内容的刚刚开始,而本 ...

  6. Vue学习笔记-Vue.js-2.X 学习(三)===>组件化高级

    (四) 组件化高级 1.插槽(slot)的基本使用 A:基本使用: <slot></slot> B:默认置:<slot><h1>中间可以放默认值< ...

  7. Vue学习笔记-Vue.js-2.X 学习(二)===>组件化开发

    ===重点重点开始 ========================== (三) 组件化开发 1.创建组件构造器: Vue.extends() 2.注册组件: Vue.component() 3.使用 ...

  8. Vue学习笔记-vue-element-admin 前端学习

    一  使用环境 开发系统: windows 后端IDE: PyCharm 前端IDE: VSCode 数据库: msyql,navicat 编程语言: python3.7  (Windows x86- ...

  9. Vue学习笔记-2

    前言 本文非vue教程,仅为学习vue过程中的个人理解与笔记,有说的不正确的地方欢迎指正讨论 1.computed计算属性函数中不能使用vm变量 在计算属性的函数中,不能使用Vue构造函数返回的vm变 ...

随机推荐

  1. SQL语句完整的执行顺序(02)

    这是对SQL语句完整的执行顺序(01)的补充: 数据库是mysql,使用的数据库表名称是my_student. 表的完整数据信息是: 完整语法是: Select [select选项] 字段列表[字段别 ...

  2. 【svn】本地文件夹同步到SVN

    本地代码上传至SVN 起因: 我在开发项目代码时往往在本地开发很久,在基本功能完成时才上传svn,添加版本控制. 做法: 右键 TortoiseSVN - Repo browser 在希望项目存储的根 ...

  3. loadrunner使用过程遇到的问题(一)

    1.如果log日志出现乱码,如何设置?(对于乱码设置只是对单一脚本有效,并不是全部脚本有效,所以多个脚本出现乱码,需要逐个设置) loadrunner12版本设置方法,在preference里面,设置 ...

  4. 消息队列(MQ)

    1. 分类: 获取消息方式:A. push(推)方式:优点——可以尽可能快地将消息发送给消费者,缺点——如果消费者处理能力跟不上,消费者的缓冲区可能会溢出:     B. pull(拉)方式:优点—— ...

  5. 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。

    /** 转换成XML格式字符串 **/ public static String doXMLStr(Map<String, String> map) { StringBuffer xml_ ...

  6. js变量污染引起的诡异bug

    js方法是这样的: //保存提货券JSON数据到隐藏字段 saveVoucherListInfoToHiddenFiled: function () { //保存绑定商品信息 var voucherL ...

  7. [转]Example Design - Using the AXI DMA in polled mode to transfer data to memory

    Description Attached to this Answer Record is an Example Design for using the AXI DMA in polled mode ...

  8. No enclosing instance of type Test is accessible. Must qualify the allocation with an enclosing instance of type Test (e.g. x.new A() where x is an instance of Test).

    Java编写代码过程中遇到了一个问题,main方法中创建内部类的实例时,编译阶段出现错误,查看错误描述: No enclosing instance of type Test is accessibl ...

  9. 《ServerSuperIO Designer IDE使用教程》-4.增加台达PLC驱动及使用教程,从0到1的改变。发布:v4.2.3版本

    v4.2.3 更新内容:1.优化数据存储部分,提高效率.2.修复数据库服务停止造成程序异常退出的现象.3.修复本机没有串口造成无法增加设备驱动的情况.4.增加编辑设备和监测点配置信息功能.5.增加台达 ...

  10. 2、Linux常用功能

    防火墙的基本用法 - 启动: systemctl start firewalld - 关闭: systemctl stop firewalld - 查看状态: systemctl status fir ...