Vue 学习笔记 — 组件初始化

vue

简书

在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" />

<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 学习笔记 — 组件初始化 的全部内容, 来源链接: utcz.com/z/378249.html

回到顶部