简书

在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. Python——类与对象,异常处理

    类 class C1: def setdata(self,value): self.data = value def display(self): print(self.data) class C2( ...

  2. face++ php

    总流程是先上传文件,保存到后台,获取返回来的face_token保存下来,然后拿face_token添加到faceSet里面去,搜索的时候结果会返回faceSet里面的face_token 1.dem ...

  3. ESP8266莫名重启或者死机问题

    多半是内存使用不当 1. 如果你要用很大长度的数组,那么可以换用更小的数据类型.比如,int值要占用两个字节,你可以用byte(只占用一个字节)代替:    2. esp8266有时会莫明重启,大部分 ...

  4. 高可用Redis(十一):使用redis-trib.rb工具搭建集群

    环境说明: 两台虚拟机,IP地址分别为:192.168.81.100和192.168.81.101 虚拟机系统为:CentOS 7.5 Redis为yum安装,版本为3.2 系统环境:关闭firewa ...

  5. 概率dp的边界处理 POJ 2096

    题目地址:https://vjudge.net/problem/POJ-2096 说的是有n个bug,和s个系统.现在一个人一天能发现一个bug,它可能是任何一个系统中的,也可能会发现已经发现过的bu ...

  6. 六 java和Tomcat

    Java企业级应用TOMCAT实战 http://blog.oldboyedu.com/java-tomcat/ 老男孩笔记 常规应用架构模型 Tomcat对静态请求效率低,可以做动静分离,动态的给T ...

  7. java----SVN

    下载SVN server 安装服务器,注意需要配置端口和本地仓库 https://www.visualsvn.com/server/download/ 下载SVN client https://tor ...

  8. zabbix4.0添加磁盘io监控

    agent服务器端的操作 1.设置zabbix-agent端的配置文件 找到agent端配置文件的位置,本例agent端的配置文件路径在/usr/local/etc/zabbix下 首先:在主配置文件 ...

  9. CF1093

    题解: D: 比较显然这个图得是二分图才行 然后每个二分图上的方案是$(2^a+2^b) (a,b是两种颜色的个数)$ E: 我tm就不该先写bitset的 正解和bitset都很好想 因为是个排列, ...

  10. tensorflow优化器-【老鱼学tensorflow】

    tensorflow中的优化器主要是各种求解方程的方法,我们知道求解非线性方程有各种方法,比如二分法.牛顿法.割线法等,类似的,tensorflow中的优化器也只是在求解方程时的各种方法. 比较常用的 ...