用Vue自己造个组件轮子,以及实践背后带来的思考
前言
首先,向大家说声抱歉。由于之前的井底之蛙,误认为Vue.js还远没有覆盖到二三线城市的互联网小厂里。现在我错了,从我司的前端技术选型之路便可见端倪。以太原为例,已经有不少公司陆续开始采用Vue.js作为他们公司前端的技术栈,前后端分离正搞得热火朝天,还有更多的公司正在来时的路上。所以说,还在校的童鞋和仍在培训的萌新们,Vue已经成为现在前端的标配技能之一,为防止掉队,跟着闰土大叔学起来吧。
接下来,正文从这开始~
先来了解下当前的行业背景:
随着SPA、前后端分离的技术架构在业界越来越流行,前端的业务复杂度也越来越高,导致前端开发者需要管理的内容,承担的职责越来越多,这一切,使得业界对前端开发方案的思考多了很多,以react、vue等框架为代表推动的组件化开发模式越来越被开发者认可,这种模式极大的降低了我们开发与维护的成本。
最近一段时间,我也在研究Vue,在网上看了那么多基于Vue的组件,何不自己也来造个小轮子,有了这个想法后,撸子袖子就是干。本文提供代码仅仅是提供而已,重要的是思路。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用Vue造个组件轮子吧-闰土大叔</title>
</head>
<body>
<div id="app">
<input-number v-model="value" :max="20" :min="0"></input-number>
</div>
<script src="js/vue.js"></script>
<script>
function isValueNumber(value){
return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).test(value + '');
}
Vue.component('input-number', {
template:`
<div class="input-number">
<input type="text"
:value="currentValue"
@change="handleChange"
ref="input"
@keydown="show($event)"/>
<button @click="handleDown" :disabled="currentValue <= min">-</button>
<button @click="handleUp" :disabled="currentValue >= max">+</button>
</div>
`,
props:{
max:{
type:Number,
default:Infinity
},
min:{
type:Number,
default:-Infinity
},
value:{
type:Number,
default:0
},
step:{
type:Number,
default:5
}
},
data: function(){
return {
currentValue: this.value
}
},
watch:{
currentValue:function(val){
this.$emit('input',val);
},
value:function(val){
this.updateValue(val);
}
},
methods:{
handleDown: function(){
if(this.currentValue <= this.min) return;
this.currentValue -= this.step;
},
handleUp: function(){
if(this.currentValue >= this.max) return;
this.currentValue += this.step;
},
updateValue:function(val){
if(val > this.max) val = this.max;
if(val < this.min) val = this.min;
this.currentValue = val;
},
handleChange:function(event){
var val = event.target.value.trim();
var max = this.max;
var min = this.min;
if(isValueNumber(val)){
val = Number(val);
this.currentValue = val;
if(val > max){
this.currentValue = max;
}else if(val < min){
this.currentValue = min;
}
}else{
event.target.value = this.currentValue;
}
},
show:function(ev){
console.log(ev.keyCode)
if(ev.keyCode == 38){
this.handleUp();
}else if(ev.keyCode == 40){
this.handleDown();
}
}
},
mounted:function(){
this.updateValue(this.value);
this.$refs['input'].focus();
}
})
var app = new Vue({
el:'#app',
data:{
value:5
}
})
</script>
</body>
</html>
如果你掌握了Vue的组件知识,相关的指令、事件,花点时间你也可以造出这么个入门级的小轮子。如果这篇文章只是单纯的贴出组件轮子代码那也太easy了。接下来,抛出造轮子实践背后带来的一些思考。
第一问:
vue 已经挂载的组件怎么初始化里面的data?
能问出这个问题的童鞋,说明你已经迷上了Vue。按照源码里讲的,vue将数据绑定到组件的原理分为三个步骤: 当实例化一个Vue构造函数,会执行 Vue 的 init 方法,在 init 方法中主要执行三部分内容,一是初始化环境变量,二是处理 Vue 组件数据,三是解析挂载组件。以上三部分内容构成了 Vue 的整个执行过程。
第二问:
vue 注册组件为什么要必须发生在根实例初始化前?

可能你已经熟读Vue官方API文档,但是这个问题你考虑过么。如果在Vue根实例初始化之后才注册组件会发生什么?如果你有兴趣,我可以等你实践30秒再说我的想法。

30秒时间到了,在等你的时候,我又实践了一遍。是的,报错了。大意是,未知的自定义元素:<input-number> - 你是否正确注册了组件?对于递归组件,请确保提供name选项。
我曾翻阅过官网API文档,也曾阅览过相关的书籍,但里面都是简单的提了一句:

这个问题无解么,不是的。其实你仔细想想报错信息,你应该会泯然一笑,说的通俗点,这就像坐高铁,买了票才能上。因为实例化的时候会尝试找这个组件,你不提前注册就找不到了。如果硬要深究,只能去看源码了。
第三问:
这个数字输入框组件网上很常见,在此基础上你有做什么扩展么?
是的,与网上的数字输入框组件不同的,我做了两个扩展。
第一个扩展:input框自动获取焦点,在输入框聚焦时,监听键盘上下按键的操作,相当于加1或者减1。
实现的思路,在input输入框上定义一个ref为input引用,然后在模板渲染完毕之后,在mounted钩子里,通过$refs查找到对应的ID:input,然后focus。获取完焦点之后,接下来就是如何监听键盘上下按键的操作。首先,我们通过keydown事件绑定一个show()方法,里面传一个$event参数,然后在子组件的methods选项内创建一个show方法。我们都知道,键盘上的上键对应的keyCode码是38,下键对应的是40。 有了这个之后,我们做一个条件判断(上加下减),如果event的keyCode码为38,就调用handleUp()方法,如果是40,就调用handleDown()方法。至此,监听键盘上下键的按下进而操作input数值的扩展完成。
第二个扩展:给组件增加一个控制步伐的prop——step,比如设置为10,点击加号按钮,一次增加10。
继续说说我的思路,这个就相对来说比较简单了,首先在props选项内定义一个step对象,类型设置为Number,默认值设置为5。然后将methods里面的handleDown和handleUp里面将 this.currentValue +/-= (具体的数值)替换为 this.step。相当于进一步封装了它的可用性。至此,所有扩展完成。
后记
自己曾经求职面试前端,因不会Vue框架而被淘汰,而且不止一次,也曾因此赋闲半年在家。所以,事不过三,我要抓紧时间学会它,以及它的全家桶。有原则有危机感的人,往往都是之前吃过大亏的人。他们知道犯错误的代价,所以不敢触碰这个红线。愿我走过的路踩过的坑,你们不会再踩一遍,才会哭着鼻子记住这个教训。以铜为镜,可以正衣冠;以人为镜,可以明得失。在之后的日子里,我还会继续更新vue相关的文章,愿我们都做一个爱思考的孩子。前端路上,we are not alone。
用Vue自己造个组件轮子,以及实践背后带来的思考的更多相关文章
- vue.js组件化开发实践
前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...
- vue组件化开发实践
前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了一下的内容.首先会对使用Vue进行开发的一些前期需要的技术储备进行简单 ...
- Vue.js——60分钟组件快速入门(上篇)
组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢?组件可以扩展HTML ...
- Vue.js——60分钟组件快速入门(下篇)
概述 上一篇我们重点介绍了组件的创建.注册和使用,熟练这几个步骤将有助于深入组件的开发.另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:"嘿,老哥,我开 ...
- 转: Vue.js——60分钟组件快速入门(上篇)
转自: http://www.cnblogs.com/keepfool/p/5625583.html Vue.js——60分钟组件快速入门(上篇) 组件简介 组件系统是Vue.js其中一个重要的概 ...
- Vue.js学习 Item11 – 组件与组件间的通信
什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有 ...
- vue实现简单表格组件
本来想这一周做一个关于vuex的总结的,但是由于朋友反应说还不知道如何用vue去写一个组件,所以在此写写一篇文章来说明下如何去写vue页面或者组件.vue的核心思想就是组件,什么是组件呢?按照我的理解 ...
- 浅谈Vue不同场景下组件间的数据交流
浅谈Vue不同场景下组件间的数据“交流” Vue的官方文档可以说是很详细了.在我看来,它和react等其他框架文档一样,讲述的方式的更多的是“方法论”,而不是“场景论”,这也就导致了:我们在阅读完 ...
- vue.js学习之组件(下篇)
本文的Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星! https://github.com/zwl-jasmine95/Vue_test 以下所有知 ...
随机推荐
- elasticsearch 学习笔记
基本概念 集群和节点的概念1.集群是由节点组成的2.每个集群都有唯一的名字默认是elasticsearch3.cluster.name: niubiwali //集群的名字很重要因为每个节点只是集群的 ...
- 》》mui--图片轮播
mui框架内置了图片轮播插件,通过该插件封装的JS API,用户可以设定是否自动轮播及轮播周期,如下为代码示例: //获得slider插件对象 var gallery = mui('.mui-slid ...
- CSS clear 清除浮动,兼容各浏览器
.clear:after{content:".";display:block;height:0;clear:both;visibility:hidden;} .clear{zoom ...
- zookeeper web ui-->node-zk-browser安装
眼下公司正在使用zookeeper做配置管理和其它工作,在网上找几个zookeeper管理工具,都不尽人意,要么功能不够强大,要么不能友好的浏览zk树形结构.我的想法是zk管理工具,应该有一个树形结构 ...
- ImageLoader配置(凝视)
/** * 配置ImageLoader */ private void configImageLoader() { File discCacheDir = StorageUtils.getOwnCac ...
- codevs1051
题目地址:http://codevs.cn/problem/1051/ 分析: --题目难度:提高一等 1.数据结构(Data Structure):①Hash(用map或人工)②Stack(栈) 2 ...
- web.config中配置数据库(多数据)连接的两种方式
这是我的第一篇文章,既然是第一篇了,那就从最基础的只是说起--web.config中配置数据库连接. 网上有很多这方面的资料,但发现并没有一篇从头到位很清楚明了说完的,今天就把我的整理写在这里吧. 在 ...
- Swift 3.0在集合类数据结构上的一些新变化
一.Array数组的更改 array数组中修改的API示例如下: //创建大量相同元素的数组//创建有10个String类型元素的数组,并且每个元素都为字符串"Hello"//sw ...
- Hive数据倾斜解决方法总结
数据倾斜是进行大数据计算时最经常遇到的问题之一.当我们在执行HiveQL或者运行MapReduce作业时候,如果遇到一直卡在map100%,reduce99%一般就是遇到了数据倾斜的问题.数据倾斜其实 ...
- qml demo分析(externaldraganddrop-拖拽)
一.效果展示 客户端程序拖拽是一个很常见的需求,对于QWidget程序来说,需要重写如图1这么几个方法,通过重写这几个方法的逻辑,我们就可以控制鼠标拖拽的逻辑,糟糕的是QDrag执行exec后是一个阻 ...