在没有DOM操作的日子里,我是怎么熬过来的(终结篇)
前言
在我写终结篇的日子里,Vue版本稳定在2.9.1。当我摸清Vue的脉络之后,以一个爬坑无数的亲历者的身份,谈谈我在MVVM时代里遇到的那些事儿。
接下来,正文从这开始~
好多童鞋学习Vue都有灯下黑的误区,比如,观看各种Vue入门的视频教程,翻阅各种Vue学习笔记的技术博客,闲逛各种号称Vue技术交流的大群。。。殊不知你们都在骑驴找马绕远路。其实通向MVVM时代最笔直的一条大路,就是看官方文档,简单粗暴有疗效。如果看一遍还不明白,那就多看几遍。书读百遍其义自见,就是这个理儿。你跟着官方文档走一遍,然后用vue-cli脚手架搭一个环境,找个iview之类的UI组件库直接开撸,多练手自然而然就会了。
如果你在公司项目中遇到难以逾越的Question,请直接请你们公司的前端大佬吃顿火锅,三杯酒下肚,面对如此“美人娇,人如遥。面色微醺自娇俏”的大佬,然后顺势请教下工作上的事情,那么你的Question还是Question吗?噗嗤~
接下来我要分几个小节来梳理一下我的vue进阶之路:
关于Vue Devtools
老话说的好,“工欲善其事,必先利其器”。当我们在开发一个Vue项目时,强烈推荐在你的Chrome上安装Vue Devtools,这是一个调试审查Vue应用的上古神器。
从上图我们可以看到组件的prop属性、计算属性、vue getter属性等,以及Vuex中的触发的mutation、state 当前的值等我们可能关注的内容都直观地展示了出来。
为什么在 HTML 中监听事件
你可能注意到这种事件监听的方式违背了关注点分离这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:
扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何自己清理它们。
怎么理解组件插槽 slot
对于一个灵活的组件来说,可替换的组件非常重要。Vue中提供了一个叫slot的概念,使用slot标签作为内容插槽的占位符。
俗话说,Talk is cheap show your the code。赶紧贴上我的代码~
定义代码:
<template>
<div class="modal">
<div class="modal-header">
<slot name="header"></slot>
</div>
<div class="modal-content">
<slot name="content"></slot>
</div>
<div class="modal-footer">
<slot name="footer"></slot>
</div>
</div>
</template>
使用代码:
<modal>
<template slot="header"><!-- 声明替换 template 中的 header 槽 -->
<h2>This is header</h2>
</template>
<div slot="body"><!-- template 标签不是必须的,可以指定槽元素 -->
<p>Content body.</p>
</div>
<template slot="footer">
<div>Footer</div>
</template>
</modal>
抛弃vue-resource拥抱axios
前端开发不可避免的就是前后端交互。在Vue2.0出来之后,尤教主登台振臂高呼,宣告停止了对vue-resource的更新,推荐大家拥抱新出来的axios。说是api更迭,其实两者都是对ES6的promise对象的实现。说白了,就是变相地抛弃了vue-resource,更恰当的说法是,物竞天择,轻量小巧。为了响应教主的号召,我果断入了axios的坑。
问把大象装冰箱,总共分几步?
第一步,安装:
npm install axios --save-dev
第二步,引入:
import Vue from 'vue' import axios from 'axios' // 引入axios之后,修改原型链,解决axios不能use的问题 Vue.prototype.$axios = axios;
第三步,使用:
俗话说,不会交互的前端不是好全栈。我还是直接上代码吧~
<template>
<div>{{myData}}</div>
</template>
<script>
export default {
data() {
return {
myData: {}
}
},
created() {
this.$axios.get(url).then((response) => {
// success
this.myData = response.data.data;
}, (error) => {
// error
console.log(error)
});
}
}
</script>
说axios撩妹(请求数据)技术一流应该没人反对吧,你看我既可以get()请求,又可以post()请求,还可以用类ajax的形式发送请求,当请求成功后,会执行.then,否则执行.catch。
紧接着是webpack编译,跑个示例,F12打开Devtools里的Network,然后勾选XHR,发现请求状态码Status Code:200 OK (兴奋状),然后顺势点开Response看到响应到的json数据。OK,握手结束。
当然,如果你在公司里看到有个人对着电脑屏幕上的Network傻乐的时候,你应该能猜到,他刚刚完成了一次完美的请求,从他猥琐的笑容中,你能隐隐察觉到,此人正YY在进阶全栈的路上不可自拔,哈哈~。
尊敬的尤教主,你总是套路得人心呐~
Vue组件化实践带来的思考
这两年前端圈子里盛行组件化,给开发者带来的好处显而易见,用户界面完全可以用嵌套的组件树来描述,提高了代码的复用性,再也不用拷贝重复DOM结构,前端原来可以如此美好。
在Vue里面,每个封装好的组件可以看成一个个的ViewModel。如果在简单的 SPA 项目中,可以直接用 Vue.component 去定义一个全局组件。而现在公司级的项目,大多数都会引入工程化的管理,用包管理工具去管理,npm 或者 yarn。所以 Vue 在复杂的项目中用 Vue.component 去定义一个组件的方式就不适合了。这里就需要用到单文件组件,还可以使用 Webpack 或 Browserify 等构建工具。
组件的划分一般分为两部分:
页面区域: header、footer、sidebar…… 功能模块: select、pagination……
vue 虽然为组件style实现了scoped,但这也存在局限, 如果 A 组件包含了 B 组件,A 的 scoped css 就不应该试图定义 B 组件内部的元素样式,这是很糟糕的体验。如此,解决 css 命名污染,CSS Modules看起来倒是一个挺不错的解决方案。
之前项目中引用lodash,十分便于处理数据,而在这次新组件开发中并没引入,因此开发过程中遇到数据处理时总想到lodash方法。其实js原生已支持很多诸如forEach、map便捷的方法,及使用for in 遍历对象,lodash只是封装的语法糖,对于lodash中较常用好用的方法如_.find()等也用原生实现了个util。因此推荐使用原生操作,尽量避免三方库的引用,也能最大化加深基础知识。
还有一点我想分享的是,动态模版添加方法。先来看看需求:
服务端返回 '<p><img src=".." /></p>'html串,需要实现页面点击图片时弹出预览框。
我最初的想法是通过对html串拼接click方法,即可通过点击事件调用弹窗组件并获取其src预览。结果做不到对拼接的html再编译以使点击事件生效。
来看看我最后解决的思路:通过事件代理实现。对动态模版的父元素绑定方法@click="imageProxy($event)"
imageProxyy(evt){
if (evt.target.nodeName === 'IMG') {
evt.stopPropagation();
this.showPicView = true;
//evt.target.currentSrc 后续处理
}
}
后记
马上到年终了,好多人的小心脏又开始不安分了,类似加薪、跳槽、晋升等各种躁动的小因子,似蠕虫一般刺挠着你的脑浆。
借用吐槽大佬的话,如果你是工作经验小于2年的朋友,我希望能够说几句。
1、尽量呆在各个领域的Top公司,公司业务成长会带着你一起成长起飞,你能享受到这个溢价; 2、如果你已经在Top公司尽量不要太早出来,至少三年以上,要抵制住诱惑; 3、尽量在细分领域或专职岗位做到一定的深度和知名度。
最后,还是那句话,前三年靠技术吃饭,往后靠综合能力吃饭。
此系列文章,The End(终)。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 浅谈python脚本设置运行参数的方法
- laravel框架实现敏感词汇过滤功能示例
- python 接收处理外带的参数方法
- Django框架实现的简单分页功能示例
- php测试kafka项目示例
- Python读取YUV文件,并显示的方法
- php-7.3.6 编译安装过程
- PHP查找一列有序数组是否包含某值的方法
- python 从文件夹抽取图片另存的方法
- laravel框架使用极光推送消息操作示例
- 对pycharm 修改程序运行所需内存详解
- Python小工具之消耗系统指定大小内存的方法
- Thinkphp框架+Layui实现图片/文件上传功能分析
- PHP实现单例模式建立数据库连接的方法分析
- 解决Python2.7中IDLE启动没有反应的问题