vue.js 开发技巧
1
1.场景:如页面需要导入多个组件,原始写法:
import titleCom from '@/components/home/titleCom'
import bannerCom from '@/components/home/bannerCom'
import cellCom from '@/components/home/cellCom'
components:{titleCom,bannerCom,cellCom}
2.这样就写了大量重复的代码,利用 require.context 可以写成
const path = require('path')
const files = require.context('@/components/home', false, /\.vue$/)
const modules = {}
files.keys().forEach(key => {
const name = path.basename(key, '.vue')
modules[name] = files(key).default || files(key)
})
components:modules
这样不管页面引入多少组件,都可以使用这个方法
3.API 方法
实际上是 webpack 的方法,vue 工程一般基于 webpack,所以可以使用
require.context(directory,useSubdirectories,regExp)
接收三个参数:
directory:说明需要检索的目录
useSubdirectories:是否检索子目录
regExp: 匹配文件的正则表达式,一般是文件名
2、watch
2.1 常用用法
1.场景:表格初始进来需要调查询接口 getList(),然后input 改变会重新查询
created(){
this.getList()
},
watch: {
inpVal(){
this.getList()
}
}
2.2 立即执行
2.可以直接利用 watch 的immediate和handler属性简写
watch:{
inpValObj:{
handler(newVal,oldVal){
console.log(newVal)
console.log(oldVal)
},
deep:true
}
}
此时发现oldVal和 newVal 值一样; 因为它们索引同一个对象/数组,Vue 不会保留修改之前值的副本; 所以深度监听虽然可以监听到对象的变化,但是无法监听到具体对象里面那个属性的变化
3、多种组件通讯
3.1 props
这个应该非常属性,就是父传子的属性; props 值可以是一个数组或对象;
// 数组:不建议使用
props:[]
// 对象
props:{
inpVal:{
type:Number, //传入值限定类型
// type 值可为String,Number,Boolean,Array,Object,Date,Function,Symbol
// type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认
required: true, //是否必传
default:200, //默认值,对象或数组默认值必须从一个工厂函数获取如 default:()=>[]
validator:(value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
3.2 $emit
这个也应该非常常见,触发子组件触发父组件给自己绑定的事件,其实就是子传父的方法
// 父组件
<home @title="title">
// 子组件
this.$emit('title',[{title:'这是title'}])
3.3 vuex
1.这个也是很常用的,vuex 是一个状态管理器 2.是一个独立的插件,适合数据共享多的项目里面,因为如果只是简单的通讯,使用起来会比较重 3.API
state:定义存贮数据的仓库 ,可通过this.$store.state 或mapState访问
getter:获取 store 值,可认为是 store 的计算属性,可通过this.$store.getter 或
mapGetters访问
mutation:同步改变 store 值,为什么会设计成同步,因为mutation是直接改变 store 值,
vue 对操作进行了记录,如果是异步无法追踪改变.可通过mapMutations调用
action:异步调用函数执行mutation,进而改变 store 值,可通过 this.$dispatch或mapActions
访问
modules:模块,如果状态过多,可以拆分成模块,最后在入口通过...解构引入
3.4 dttrs 和 listeners
2.4.0 新增 这两个是不常用属性,但是高级用法很常见; 1.attrs获取子传父中未在 props 定义的值
// 父组件
<home title="这是标题" width="80" height="80" imgUrl="imgUrl"/>
// 子组件
mounted() {
console.log(this.$attrs) //{title: "这是标题", width: "80", height: "80", imgUrl: "imgUrl"}
},
相对应的如果子组件定义了 props,打印的值就是剔除定义的属性
props: {
width: {
type: String,
default: ''
}
},
mounted() {
console.log(this.$attrs) //{title: "这是标题", height: "80", imgUrl: "imgUrl"}
},
2.listeners" 传入内部组件——在创建更高层次的组件时非常有用
// 父组件<home @change="change"/>// 子组件mounted() { console.log(this.$listeners) //即可拿到 change 事件}
如果是孙组件要访问父组件的属性和调用方法,直接一级一级传下去就可以
3.inheritAttrs
// 父组件
<home title="这是标题" width="80" height="80" imgUrl="imgUrl"/>
// 子组件
mounted() {
console.log(this.$attrs) //{title: "这是标题", width: "80", height: "80", imgUrl: "imgUrl"}
},
inheritAttrs默认值为true,true的意思是将父组件中除了props外的属性添加到子组件的根节点上(说明,即使设置为true,子组件仍然可以通过$attr获取到props意外的属性)
将inheritAttrs:false后,属性就不会显示在根节点上了
3.5 路由传参
1.方案一
// 路由定义
{
path: '/describe/:id',
name: 'Describe',
component: Describe
}
// 页面传参
this.$router.push({
path: `/describe/${id}`,
})
// 页面获取
this.$route.params.id
2.方案二
// 路由定义
{
path: '/describe',
name: 'Describe',
component: Describe
}
// 页面传参
this.$router.push({
name: 'Describe',
params: {
id: id
}
})
// 页面获取
this.$route.params.id
3.方案三
// 路由定义
{
path: '/describe',
name: 'Describe',
component: Describe
}
// 页面传参
this.$router.push({
path: '/describe',
query: {
id: id
`}
)
// 页面获取
this.$route.query.id
4.三种方案对比 方案二参数不会拼接在路由后面,页面刷新参数会丢失 方案一和三参数拼接在后面,丑,而且暴露了信息
3.6 Vue.observable
新增 用法:让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象; 返回的对象可以直接用于渲染函数和计算属性内,并且会在发生改变时触发相应的更新; 也可以作为最小化的跨组件状态存储器,用于简单的场景。通讯原理实质上是利用Vue.observable实现一个简易的 vuex
// 文件路径 - /store/store.js
import Vue from 'vue'
export const store = Vue.observable({ count: 0 })
export const mutations = {
setCount (count) {
store.count = count
}
}
//使用
<template>
<div>
<label for="bookNum">数 量</label>
<button @click="setCount(count+1)">+</button>
<span>{{count}}</span>
<button @click="setCount(count-1)">-</button>
</div>
</template>
<script>
import { store, mutations } from '../store/store' // Vue2.6新增API Observable
export default {
name: 'Add',
computed: {
count () {
return store.count
}
},
methods: {
setCount: mutations.setCount
}
}
</script>