好久不见,本篇博客内容将延续上一篇博客内容《初试VUX》,我将总结在完成此项目中学习到的一些有趣的事情。
阅读记录:
6月份,我阅读了《图解HTTP》
7月份,我阅读了《JavaScript语言精粹》
8月份,我正在阅读《CSS SECRETS》——很高兴的是,至今年8月底,我学习FE一年了
9月份,我已经准备好迎接《ECMAScript 6 入门》以及《深入理解ES6》啦,已经阅读电子版的《ECMAScript 6 入门》,对ES6有些简单的认识,并慢慢实践中
7月初,分析公司业务需求后,我选择使用VUX完成项目,项目也很顺利的在7月底上线了。
那么以下内容都是通过我查阅我的Commits日志产出。
首先介绍下,本项目中使用到的技术栈:
axios
axios不需要过多介绍了吧,Vue更新至2.0版本后,作者就宣告不再对vue-resource更新,而是推荐的axios。
URLSearchParams API 解决CORS预检请求
问题出在,非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。
那么URLSearchParams API就是axios官方提供的解决方案。使用方法传送门>>
以及浏览器发起XHR的两种请求:简单请求和非简单请求。可以参阅《阮老师 - 跨域资源共享 CORS 详解》
实现文件上传
<input class="file" name="file" type="file" accept="image/*" @change="upload"/>
upload (event) {
let file = event.target.files[0]
let param = new FormData() // 创建form对象
param.append('upLoad', file, file.name) // 通过append向form对象添加数据
let config = {headers: {'Content-Type': 'multipart/form-data'}} // 添加请求头
axios.post(url, param, config)
.then(function (response) {
// ...
})
.catch(function (error) {
// ...
})
}
vue-router
导航钩子
因为业务逻辑需要,在载入某个路由后执行某些事。
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
Vue
props
props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值。
项目开发过程中,我将数据存在父组件中,由于某些业务场景,需要在子组件A中修改父组件数据,从而更新至子组件B中,最后统一移除props,使用vuex管理数据。
Vuex
每一个 Vuex 应用的核心就是 store(仓库)。”store” 基本上就是一个容器,它包含着你的应用中大部分的状态(state)。Vuex 和单纯的全局对象有以下两点不同:
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
Vuex 应用的核心完全契合项目开发。
组件化开发
组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is
特性扩展。
我认为使用组件是有必要的,其必要性在于:
- 代码复用
- 代码解耦
HTML5范围样式 scoped
CSS属性 fill
for …of
for …of 循环有以下几个特征:
- 这是最简洁、最直接的遍历数组元素的语法。
- 这个方法避开了 for …in 循环的所有缺陷。
- 与 forEach 不同的是,它可以正确响应 break、continue 和 return 语句。
- 其不仅可以遍历数组,还可以遍历类数组对象和其他可迭代对象。
那 for …of 到底可以干什么呢?
- 跟 forEach 相比,可以正确响应 break, continue, return。
- for …of 循环不仅支持数组,还支持大多数类数组对象,例如 DOM nodelist 对象。
- for …of 循环也支持字符串遍历,它将字符串视为一系列 Unicode 字符来进行遍历。
- for …of 也支持 Map 和 Set (两者均为 ES6 中新增的类型)对象遍历。
参考: 《知乎 - 深入了解 JavaScript 中的 for 循环》
过场动画
参考vux源码:
以下为提取内容:
main.js
import Vuex from 'vuex'
Vue.use(Vuex)
let store = new Vuex.Store({})
store.registerModule('vux', {
state: {
demoScrollTop: 0,
isLoading: false,
direction: 'forward',
},
mutations: {
updateDemoPosition (state, payload) {
state.demoScrollTop = payload.top
},
updateLoadingStatus (state, payload) {
state.isLoading = payload.isLoading
},
updateDirection (state, payload) {
state.direction = payload.direction
}
},
actions: {
updateDemoPosition ({commit}, top) {
commit({type: 'updateDemoPosition', top: top})
}
}
})
// simple history management
const history = window.sessionStorage
history.clear()
let historyCount = history.getItem('count') * 1 || 0
history.setItem('/', 0)
router.beforeEach(function (to, from, next) {
store.commit('updateLoadingStatus', {isLoading: true})
const toIndex = history.getItem(to.path)
const fromIndex = history.getItem(from.path)
if (toIndex) {
if (!fromIndex || parseInt(toIndex, 10) > parseInt(fromIndex, 10) || (toIndex === '0' && fromIndex === '0')) {
store.commit('updateDirection', {direction: 'forward'})
} else {
store.commit('updateDirection', {direction: 'reverse'})
}
} else {
++historyCount
history.setItem('count', historyCount)
to.path !== '/' && history.setItem(to.path, historyCount)
store.commit('updateDirection', {direction: 'forward'})
}
if (/\/http/.test(to.path)) {
let url = to.path.split('http')[1]
window.location.href = `http${url}`
} else {
next()
}
})
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app')
App.vue
<template>
<div id="app">
<transition :name="'vux-pop-' + (direction === 'forward' ? 'in' : 'out')">
<!-- @direction 判断动画样式为in或者out -->
<router-view class="app"></router-view>
</transition>
</div>
</template>
<script>
import { mapState } from 'vuex' // 用引入vuex的mapState
export default {
name: 'app',
computed: { // vuex管理页面
...mapState({
direction: state => state.vux.direction
})
}
}
</script>
<style lang='less'>
.vux-pop-out-enter-active,
.vux-pop-out-leave-active,
.vux-pop-in-enter-active,
.vux-pop-in-leave-active {
will-change: transform;
transition: all 250ms;
height: 100%;
top: 0;
position: absolute;
backface-visibility: hidden;
perspective: 1000;
}
.vux-pop-out-enter {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
.vux-pop-out-leave-active {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.vux-pop-in-enter {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.vux-pop-in-leave-active {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
.weui-btn:after {
border: none !important;
}
</style>
Webpack 轻度调整
vue-cli已经集成Webpack,执行npm run build
后,想实现直接运行index.html即可运行页面。修改以下参数即可实现:
build/utils.js
ExtractTextPlugin.extract({
publicPath: '../../' // 解决CSS样式导出路径问题
})
config/index.js
build: {
assetsPublicPath: './' // 解决JS、CSS路径问题
}
修改后src = ""
,或者url (...)
使用相对路径即可。
vue-infinite-scroll - 下拉加载
ESLint
这里要提到ESLint是因为,他可以帮助开发者减少开发中一些不必要的错误(除了逻辑),并且在合作开发时,起到大大的作用,所以请拥抱ESLint。
好了,先这样吧,我要抓紧学习去了~
- 本文链接: https://zongzi531.com/2017/08/07/hug-fe-in1year/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!