Vue.js知识

196 阅读2分钟

开发技巧

封装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 库的使用

lodash官网

安装

npm i -S lodash

使用

var _ = require('lodash');

常用方法

  • 防抖
_.debounce(func, [wait=0], [options={}])
  • 节流
_.throttle(func, [wait=0], [options={}])