开发技巧
封装axios
import axios from 'axios'
const instance = axios.create({
timeout: 1000 * 5
})
自动引入模块文件 require.context()
例如
自动引入 store 中的模块文件
- 目录结构
├─store
│ │ index.js
│ │
│ └─modules
│ attribute.js
│ brand.js
│ category.js
│ goods.js
│ home.js
│ login.js
│ order.js
│ topic.js
└─views
- 关键代码
// store/index.js
// ...
// 自动引入模块
const modulesFiles = require.context('./modules', false, /\.js$/)
// 不需要这么做 `import app from './modules/app'`
// 它会自动从 './modules' 中引入 符合 /\.js$/ 正则表达式的文件
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// 把 './user.js' => 'user'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
// ...
export default new Vuex.Store({
modules, // modules: modules,
// ...
})
全局注册多个过滤器
src/filters/index.js目录下
// 定义 过滤器
export function filter1 (time) {
// todo ...
},
export function filter2 (time) {
// todo ...
},
export function filter3 (time) {
// todo ...
},
// ...
- main.js 中
// 引入
import * as filters from './filters' // 全局 filters
// 注册
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
- 在 xxx.vue 中使用
<!-- 单个 -->
<p>价格:{{ count|filter1 }}</p>
<!-- 多个 -->
<p>价格:{{ count|filter1|filter2|filter3|... }}</p>
hook 用法
监听组件声明周期:@hook:组件声明周期(created, mounted,...)
监听子组件 声明周期
// 父组件中
<Child @hook:mounted="todoFn"/>
...
methods: {
todoFn() {
console.log("触发子组件mounted");
},
},
替换文件名引入文件路径 如@代替src (别名引入智能提示)
- 在项目目录下新建
jsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
// 别名
"@/*": ["src/*"],
"@com/*": ["src/components/*"],
"@views/*": ["src/views/*"],
"@css/*": ["src/styles/*"],
"@img/*": ["src/assets/images/*"],
"@js/*": ["src/utils/*"],
}
},
"exclude": ["node_modules", "dist"] // 排除项
}
- 在
vue.config.js中
// ======================配置别名 start==========================
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
// 别名配置
chainWebpack: (config) => {
config.resolve.alias
.set('@', resolve('src'))
.set('@com', resolve('src/components'))
.set('@views', resolve('src/views'))
.set('@css', resolve('src/styles'))
.set('@img', resolve('src/assets/images'))
.set('@js', resolve('src/utils'))
// ...
},
// 或者
/* configureWebpack: {
resolve: {
alias: {
'@': resolve('src'),
'@com': resolve('src/components'),
// 其他同理...
}
}
}, */
// ======================配置别名 end==========================
productionSourceMap: false, // 取消打包后的镜像文件
devServer:{
// port:'端口'
open:true, // 项目启动成功时自动在默认浏览器中打开
hot:true,
},
// ...
}
- 安装 路径提示插件
Path Intellisense, 重新 用vscode 打开项目(如果上面两步成功了,可忽略此步骤) - 使用 示例
js-cookie 操作 cookies
- 安装
npm i js-cookie -S 或 yarn add js-cookie
- 可以自行封装
import Cookies from 'js-cookie'
const TokenKey = 'token'
// set cookies
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
// get cookies
export function getToken() {
return Cookies.get(TokenKey)
}
// remove cookies
export function removeToken() {
return Cookies.remove(TokenKey)
}
- 使用
// 引入
import { setToken, getToken, removeToken } from '@/utils/auth'
// 使用
setToken(res.data.token) // 其他看着封装的代码来传递参数
回车登录
mounted() {
// 绑定回车事件
document.addEventListener("keydown", this.keyDown, false);
},
destroyed() {
// 销毁事件
document.removeEventListener("keydown", this.keyDown, false);
},
methods: {
// 键盘事件
keyDown(e) {
e = window.event || e;
if (
this.$route.path == "/login" &&
(e.code == "Enter" || e.code == "enter")
) {
//验证在登录界面和按得键是回车键 enter
this.handleLogin("loginForm"); //登录函数
}
},
}
过滤器复用
- 不仅只能在template中使用,也可在组件实例中使用
- 局部、全局都可以访问得到
filters: {
formMoney(val) {
return Number(val).toFixed(2);
},
},
// 与filters同级的 属性、方法中访问,如下
computed:{
getNum(){
return this.$options.filters.formMoney(20)
}
}
.sync 修改父组件传递过来的自定义属性(简化子传父代码)
// 父组件
<Child :title.sync="title"></Child>
// 子组件
<p @click="$emit('update:title', 'hello')">{{ title }}</p>
props: {
title: {
type: String,
default: "",
},
},
render 函数使用
场景
<template>
<div>
<div v-if="level === 1"> <slot></slot> </div>
<p v-else-if="level === 2"> <slot></slot> </p>
<h1 v-else-if="level === 3"> <slot></slot> </h1>
<h2 v-else-if="level === 4"> <slot></slot> </h2>
<strong v-else-if="level === 5"> <slot></slot> </stong>
<textarea v-else-if="level === 6"> <slot></slot> </textarea>
</div>
</template>
优化
<template>
<div>
<child :level="level">Hello world!</child>
</div>
</template>
<script>
import Vue from 'vue'
Vue.component('child', {
render(h) {
const tag = ['div', 'p', 'strong', 'h1', 'h2', 'textarea'][this.level-1]
return h(tag, this.$slots.default)
},
props: {
level: { type: Number, required: true }
}
})
export default {
name: 'hehe',
data() { return { level: 3 } }
}
</script>
lodash 库的使用
安装
npm i -S lodash
使用
var _ = require('lodash');
常用方法
- 防抖
_.debounce(func, [wait=0], [options={}])
- 节流
_.throttle(func, [wait=0], [options={}])