前言:
18 年年底, 就一个字, 忙, 貌似一到年底哪个公司都在冲业绩, 包括我们自己开发自己公司的项目也一样得加把劲. 自从 18 年年初立了个 flag17 年年终总结 -- 走过 2017, 迎来 2018Flag 到现在又一年了. 想想当时立的 flag 还是很多没有完成到, 说的第一点就没有完成了 (ps: 这确实不能怪我, 真的忙), 健身也是落下了, 而 node.JS 的呢还在进程中, 说不定稍后会出了系列的文章 (ps: 当然不会像之前那几篇那样, 感觉写得有点云里雾里的). 当然, 今天的重点不是说这些, 而是我在 vue 项目上实践的一些小汇总和踩坑指南. 另, 结尾有福利喔~~~
正文:
这一年前前后后大概做了有四个 vue 相关的项目 (ps:vue-cli 脚手架搭建), 其中包括两个移动端和两个管理后台的 (ps: 有一个管理端还在进行中), 其中不免遇到了不少坑, 还有不少的总结.
vue-cli 开发相关
一, 一般的 vue-cli src 的项目骨架:
├── App.vue
├── main.JS
├── permission.JS
├── router
│ └── index.JS
├── API
│ └── index.JS
│ └── xx.JS
├── assets
│ ├── images
│ ├── flexible.JS
│ └── common
│ └── common.Less
│ └── mixin.Less
├── components
├── utils
├── store
│ ├── index.JS
│ └── xxStore.JS
└── views
├── index.vue
└── xx.vue
对 vue-cli 有了解的应该知道一般我们的源码就写在 src 文件夹下面. 其中 App.vue 就是根组件, 其他的组件我们就可以通过 App.vue 的
<router-view/> 渲染; main.JS 就是入口文件, 一般用于引入通用组件, UI 框架, router,axios,store 挂载等; permission.JS 则用于在路由渲染先后需要设置的权限之类的; components 则为通用组件的封装; utils 则为通用的方法的封装; API 则为通用 API 的封装调用等.
例如: main.JS
- import 'babel-polyfill'
- import Vue from 'vue'
- import Es6Promise from 'es6-promise'
- require('es6-promise').polyfill()
- Es6Promise.polyfill()
- import App from './App'
- import './assets/flexible'
- import axios from 'axios'
- import router from './router'
- import store from './store'
- import './permission'
- import {WechatPlugin,LoadingPlugin,ToastPlugin,AlertPlugin,ConfirmPlugin } from 'vux'
- import VueLazyload from 'vue-lazyload'
- // 挂载 axios
- Vue.prototype.axios=axios
- // 配置微信 jssdk, 通过 Vue.wechat 直接访问 wx
- Vue.config.productionTip = false
- Vue.use(WechatPlugin)
- Vue.use(LoadingPlugin)
- Vue.use(ToastPlugin)
- Vue.use(AlertPlugin)
- Vue.use(ConfirmPlugin)
- Vue.use(VueLazyload,{
- error:require('./assets/images/activity_default_loading.png'),
- loading:require('./assets/images/activity_default_loading.png')
- })
- /* eslint-disable no-new */
- new Vue({
- el: '#app',
- router,
- store,
- components: { App },
- template: '<App/>'
- })
二, axios API 接口的统一封装
现在的 vue-cli 开发, 一般都是使用 axios 进行接口请求, 其中一大好处就是可以进行请求和响应的拦截, 进而进行一些通用的配置, 所以能很好的做到了接口的封装.
例如: request.JS
- import axios from 'axios'
- import { AlertModule } from 'vux'
- // 创建 axios 实例
- const service = axios.create({
- //baseURL: process.env.ENV_CONFIG=='dev'?'/api':'', // API 的 base_url
- baseURL: process.env.ENV_CONFIG=='dev'?'/api':process.env.BASE_API,
- //timeout: 10000, // 请求超时时间
- headers:{
- }
- })
- // request 拦截器
- service.interceptors.request.use(
- config => {
- if( config.method === 'post' ){
- config.data.http_headers={
- }
- }
- return config
- },
- error => {
- // Do something with request error
- // for debug
- console.log(error)
- Promise.reject(error)
- }
- )
- // respone 拦截器
- service.interceptors.response.use(
- response => {
- if (response.data.result && response.data.result==='failed') {
- AlertModule.show({
- title:'提示',
- content:response.data.text,
- /*onHide () {
- router.push({
- name:'index'
- })
- }*/
- })
- return
- }
- else{
- return response.data
- }
- },
- error => {
- console.log('err' + error) // for debug
- /*AlertModule.show({
- title:'斑马提示',
- content:'链接超时, 请重新尝试',
- })*/
- return Promise.reject(error)
- }
- )
- export default service
之后, 我们就可以通过 API 目录暴露封装的接口调用
- import request from '@/utils/request'
- export function doXx(data) {
- return request({
- url:'/xx',
- method:'post',
- data
- })
- }
三, axios 请求不同数据格式的处理及表单提交处理
看 axios 文档我们可以了解到, axios 的其中一个特点就是将数据转换成 JSON 格式, 但是有些接口由于历史等原因后台不方便调整的话, 就需要前端做些处理了.
例如, 以 formdata 格式提交参数则可以通过 axios 内置的 qs 模块进行 data 的格式转换, 然后设置请求头即可
- export function XXRequest(data) {
- return request({
- transformRequest: [function(data) { // 在请求之前对 data 传参进行格式转换
- data = qs.stringify(data)
- return data
- }],
- url:'/xx.do',
- method:'post',
- data,
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
- }
- })
- }
又例如, 后台返回一个 form 表单, 需要前端提交 form 表单, 则需要, 通过路由的 resolve 对象, this.$router.resolve 解析接口回调参数并且打开空白页面并提交 form 表单
- // res 为回调参数
- let routerData = this.$router.resolve({name:'apply',query:{htmls:res}})
- Windows.open(routerData.href,'_ blank')
- const div = document.createElement('div')
- div.innerHTML = res
- document.body.appendChild(div)
- document.forms [0] .submit()
apply.vue 做法
- <template>
- <div v-HTML ="apply">
- {{apply}}
- </div>
- </template>
- <script>
- export default {
- name:'apply',
- data(){
- return {
- apply:''
- }
- },
- mounted(){
- let form = this.$route.query.htmls
- this.apply = form
- this.$nextTick(()=> {
- document.forms [0].submit()
- })
- }
- }
- </script>
四, 引入 CSS 预处理器 Less
NPM install Less Less-loader --save
修改 webpack.base.conf.JS rules
- {
- test: /\.Less$/,
- loader: "style-loader!css-loader!less-loader",
- }
五, es6 在低版本及 IE 下的不兼容
部分低版本的手机或者 IE 下是不兼容 es6 中的 promise 的, 如果用到了 promise 语法的话, 就需要进行 es6 编译 es5, 所以做法需要引入
es6-promise 并且在 main.JS 中引入
NPM install es6-promise --save
main.JS 中引入
- import Es6Promise from 'es6-promise'
- require('es6-promise').polyfill()
- Es6Promise.polyfill()
六, ico 调整
一般的 ico 都是设置在项目根目录下, 然后调整 build webpack.dev.conf.JS 和 webpack.prod.conf.JS 中的 new HtmlWebpackPlugin 设置参数
favicon:path.resolve(__dirname,'xx.ico') 即可.
七, 常用组件的引入
一般常用的 vue 组件的引入, 例如 vue-lazyload,vue-scroller 等一般可以上 https://www.npmjs.com/ 查看相关是使用方法即可.
vue-cli 单页面部署相关
一, build 路径问题
一般项目都会部署到端口的某个文件夹下面, 所以需要修改 config index.JS 的 assetsPublicPath 路径
- index: path.resolve(__dirname, '../ 文件夹名 / index.html'),
- assetsRoot: path.resolve(__dirname, '../ 文件夹名'),
- assetsSubDirectory: 'static',
- assetsPublicPath: './', // ./ 为相对文件夹路径, 否则 / 为根目录
二, 部署到 Nginx 上
由于打包完后的是静态文件, 所以我们可以直接部署到 Nginx 上面, 接口通过 Nginx 代理即可. 但是刷新会丢失 404, 所以需要做个重定向即可.
- location /{
- root dist;
- index index.HTML;
- try_files $uri $uri/ /dist/index.HTML;
- }
三, 部署到 Tomcat 上
部署到 Tomcat 上的话, 一样存在刷新丢失的情况, 我看有人提出配置 Web.xml 进行 404 重定向, 这个我司也是有实践了下
- <!DOCTYPE Web-App PUBLIC
- "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd">
- <Web-App>
- <display-name>xxx</display-name>
- <error-page>
- <error-code>404</error-code>
- <location>/index.HTML</location>
- </error-page>
- </Web-App>
但是, 这样部署的话其实是第一次刷新 ok 的, 但是再次刷新则还是 404 丢失.(ps: 在移动设备上会, 有知道的大佬可以留言喔~)
总结:
其中, 有了解过 vue-cli 开发的话, 其实用 vue 开发在业务逻辑上是没有太大的问题的, 因为很多大佬已经开发出各种组件供我们调用了, 我呢, 就在部署上面卡了很久, 因为最初的想法是部署到 Tomcat 上的, 所以一直尝试都没有成功, 最初的原因的就是使用了 es6 的 promise, 然后呢又了解到了需要配置重定向 xml. 最后以为大功告成, 还是存在二次刷新丢失的问题. 所以部署到了 Nginx 上, 然后设置重新定这样子解决.
另, 其中还有很多可能没有总结到位, 到时有补充的会补充在这里~
再另, 附福利
winter 大大, 前手机淘宝前端负责人在极客时间上发了《重学前端》的课程, 扫我的二维码报名的话可以找我分奖励喔, 另外通过我二维码报名的加我 wx:UEMtQWFyb24= (ps:base64 转码) 可得 vue 教程一套. 嘻嘻
来源: https://www.cnblogs.com/aaron-pan/p/10272907.html