一、 js适配经验:
在写代码的时候,很有可能写到这种代码:
或者是使用promise
等es6的方法,但是我们的需求是在Android4.4上面完美运行。这样就会出现includes is not undefied
等错误提示。我们可以通过webpack的插件来解决,具体的使用方法:
1 2 3 4 5 6 7 8 9
| import "babel-polyfill" import es6Promise from 'es6-promise' es6Promise.polyfill() require('es6-promise').polyfill()
entry: { app: ['babel-polyfill', './src/main.js'] },
|
二、 全局定义
当我们写了很多库的时候,我们引入页面可能会变成这样:
1 2 3 4 5 6 7
| import utils from "library"
import utils from "library" ...
import utils from "library"
|
可以这样处理
1 2 3 4 5 6
| import Vue from 'vue' import http from "http/http" Vue.prototype.$okhttp = http
this.$okhttp
|
这样会节省很多没有必要的代码量
三、 自定义目录
在写代码的时候,很多时候都存在这种情况 :
1 2
| import component1 from "../../../../component" import component2 from "../../../../../component"
|
这样写的缺陷是一旦某个目录发生变化就会导致引入错误。可以通过webpack路径解决
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| module.exports = { context: path.resolve(__dirname, '../'), entry: { app: ['babel-polyfill', './src/main.js'] }, output: {}, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), 'components': resolve('src/components'), 'pages': resolve('src/pages') } }, module: { }, node: { }, plugins: [], }
|
在resolve->alias里面可以配置绝对相对路径,在使用的时候
1 2
| import component1 from "pages/component" import component2 from "pages/component"
|
四、 路由懒加载
官方文档里面定义路由的时候都有两步:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import Vue from 'vue' import Router from 'vue-router' import xxx from 'xxx' Vue.use(Router)
const router = new Router({ routes: [ { path: '/', component: xxx, } ] })
|
在做大型项目的时候 很可能定义很多很多个路由,那样页面就会写的特别多。此时懒加载就会解决这个问题
1 2 3 4 5 6 7 8 9 10 11 12
| import Vue from 'vue' import Router from 'vue-router' Vue.use(Router)
const router = new Router({ routes: [ { path: '/', component: () => import("xxx") } ] })
|
五、 样式污染和样式覆盖的问题
在我们新建vue的时候,经常会看到scoped
如果我们去掉scoped
的时候会发现,在本vue项目内定义的css属性会影响到其他vue页面的css属性。这个就很坑了。所以,我们在使用的时候一定要用scoped
但是在实际的开发中,也会遇到这么个问题。比如elementUI](http://element-cn.eleme.io/#/zh-CN/component/changelog),虽然里面的资源库很强大,但是里面的视图不能完全符合策划的需求,此时就需要进行微调。
1 2 3 4 5 6 7
| <style lang="stylus" scoped> .custom-dialog .el-dialog__header padding 0 .el-dialog__body padding 0 </style>
|
如果此时我们加上scoped
标签的话,我们发现并没有效果,发现去掉scoped
才会起作用。
六、 mock、mock
很多情况下,后台还没有搭建完成之前。可能前端没办法进行数据的接入。这种情况可能是一个大问题,这样会严重拖慢项目开发,此时就需要mock
首先在webpack.dev.conf.js里面配置express,
1 2 3 4 5
| const express = require('express') const app = express() const appData = require('../static/data/user.json') const apiRouter = express.Router() app.use('/api',apiRouter)
|
然后将接口通过devServer
发布出去:
1 2 3 4 5 6 7
| before(app) { app.get('/api/user',(req, res) => { res.json({ data: appData }) }) }
|
使用的时候就直接打开http://localhost:8080/api/user,就可以了。
六、 代理解决跨域
有些时候,在进行本地开发的时候,可能会遇到跨域的问题。为了解决这个问题呢?主要有两种方法:
1、 服务器设置
服务端设置很简单,就是将本地开发的东西加上“Access-Control-Allow-Origin”, “*”
,或者是直接将本地开发的ip直接设置成白名单,这样就可以了.
2、 本地代理
首先引入
1
| npm install http-proxy-middleware --save
|
然后在index.js
的标签下proxyTable
使用
1 2 3 4 5 6 7
| '/lesson': { target: 'http://xxx/v2/webapi/lesson', changeOrigin: true, pathRewrite: { '^/lesson': '/' } }
|
使用的时候,就直接使用
1 2 3 4 5 6 7 8 9 10 11 12
| axios({ method: 'get', url:'/lesson' , params: qs.stringify(data) }).then(function (res) { if (res) { } }); }).catch(function (error) { console.error(error); })
|
七、 页面统一判断
在开发中经常会遇到权限判断的问题,我们又不可能在每一个页面的生命周期中去判断一下,可以这样处理:
1 2 3
| router.beforeEach((to, from, next) => { myAccess.checkhaveAccess(to.path) === true ? next() : next('/forbid') })
|
八、 事件的传递:
一般来说事件的传递有很多种,比如父子之间传递数据就可以直接用props
,和emit
来做关联。
父组件给子组件传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <parent> <child :datas="content"></child> </parent>
data(){ return { content:'sichaoyun' }; }
// 子组件
props:["datas"]; // 或者是 props: { datas: String }
|
子组件给父组件传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div @click="open"></div> </template>
methods: { open() { this.$emit('showbox','the msg'); //触发showbox方法,'the msg'为向父组件传递的数据 } } // 父组件 <child @showbox="toshow" :msg="msg"></child>
methods: { toshow(msg) { this.msg = msg; } }
|
兄弟组件之间的传递一般有几种方式:
1、 注册全局事件
2、 vuex
3、 localstorage
使用全局事件则代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let vm = new Vue();
<div @click="ge"></div> methods: { ge() { vm.$emit('click',data); } }
<div></div> created() { vm.$on('click', (arg) => { }); }
|
九、 列表渲染
v-for循环绑定model:
这个是我在一个微信公众号上面看到的写法,很新颖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| data() { return{ obj: { ob: "OB", koro1: "Koro1" }, model: { ob: "默认ob", koro1: "默认koro1" } } }, <div v-for="(value,key) in obj"> <input type="text" v-model="model[key]"> </div> // input就跟数据绑定在一起了,那两个默认数据也会在input中显示
|
v-if尽量不要与v-for在同一节点使用:
v-for 的优先级比 v-if 更高,如果它们处于同一节点的话,那么每一个循环都会运行一遍v-if。
如果想根据循环中的每一项的数据来判断是否渲染,可以这么做:
1 2 3
| <li v-for="index in datas" v-if="Object.is(index,0)"> {{ index }} </li>
|
如果你想要根据某些条件跳过循环,而又跟将要渲染的每一项数据没有关系的话,可以将v-if放在v-for的父节点:
1 2 3 4 5 6 7 8 9 10 11 12 13
| // 根据elseData是否为true 来判断是否渲染,跟每个元素没有关系 <ul v-if="condition"> <li v-for="index in datas"> {{ index }} </li> </ul> // 数组是否有数据 跟每个元素没有关系 <ul v-if="datas.length"> <li v-for="index in datas"> {{ index }} </li> </ul> <p v-else>没有更多数据</p>
|
十、 深度watch与watch立即触发回调
watch有两个可选参数
选项:deep
在选项参数中指定 deep: true,可以监听对象中属性的变化。
选项:immediate
在选项参数中指定 immediate: true, 将立即以表达式的当前值触发回调,也就是默认触发一次。
十一、 路由的项目启动页和404页面
1 2 3 4 5 6 7 8 9 10 11 12
| export default new Router({ routes: [ { path: '/', redirect:'/login' }, { path: '*', component: () => import('./notfind') }, ] })
|
比如你的域名为:www.baidu.com
项目启动页指的是: 当你进入www.baidu.com
,会自动跳转到login登录页。
404页面指的是: 当进入一个没有 声明/没有匹配 的路由页面时就会跳转到404页面。
比如进入www.baidu.com/testRouter
,就会自动跳转到notFind页面。
当你没有声明一个404页面,进入www.baidu.com/testRouter
,显示的页面是一片空白。
评论加载中