vue常用技巧
配置开发环境
"scripts": {
"serve": "vue-cli-service serve --mode development",
"serve:test": "vue-cli-service serve --mode test",
"serve:pre": "vue-cli-service serve --mode preproduction",
"build": "vue-cli-service build --mode production",
},
vue-cli-service serve
命令会启动一个开发服务器, --mode
指定环境模式 默认值有:development
, test
和 production
在根目录创建个.env.xx
的配置文件
NODE_ENV ='development'
VUE_APP_URL=http://192.168.203.173:9120 //问答api地址
VUE_APP_WEB_URL=http://192.168.203.173:8082 //测评小程序后台 api地址
VUE_APP_CP_URL=http://192.168.203.173:8380 //保费试算
登录地址
VUE_APP_LOGIN=http://192.168.203.173:8082/user/authLogin
返回地址
VUE_APP_CALLBACK=http://192.168.203.43:8085/main
项目中通过process.env.xxx
来使用比如:process.env.VUE_APP_URL
require.context()
如果页面需要导入多个组件,原始写法
import one from '@/components/one '
import two from '@/components/two'
import three from '@/components/three'
...
components:{one,two,three, ...}
这样写了很多重复代码。利用 require.context
可以写成
const path = require('path')
const filre = require.context('@/components',true /\.vue$/)
const moudles = {}
filre.keys().map( key => {
const name = path.basename(key,'.vue')
moudles[name] = filre(key).default||filre(key)
})
components: moudles
这样不管页面引入多少组件,都可以使用这个方法
require.context
这是个webpack
的方法,vue
工程一般基于webpack
require.context(directory,useSubdirectories,regExp)
directory
要检索的目录
useSubdirectories
是否检索子目录
regExp
匹配文件的正则表达式,一般是文件名
watch
- 立即执行
可以直接利用 watch
的 immediate
和 handler
栗子
watch:{
value:{
handler: function(){
},
immediate: true
}
},
- 深度监听
watch
的 deep
属性,深度监听,也就是可以监听复杂的数据
data () {
return {
value:{
name:'xx',
has:{
car:'xx'
},
}
}
},
watch:{
value:{
handler: function(){
},
deep: true
}
},
常见的组件通讯
- props
props
值可以是数组或对象
//数组:不推荐使用
props:[]
//对象
props:{
inputVal:{
type: String,//传入值限定类型
required: true,//是否必填
default: 'a',//默认值 对象或数组默认值必须从一个工厂函数获取如 default:()=>[]
validator:(value)=>{
// 这个值必须匹配下列字符串中的一个
return ['a','b','c'].includes(value)
}
}
}
- $emit
非常常见,触发子组件触发父组件给自己绑定的事件,其实就是子传父的方法
// 父组件
<home @title="title">
// 子组件
this.$emit('title',[{title:'这是title'}])
- vuex
一个状态管理器
适合数据共享多的项目里面,因为如果只是简单的通讯,使用起来会比较重
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:模块,如果状态过多,可以拆分成模块
- attrs 和 listeners
attrs
:如果父传子有很多值,那么在子组件要定义很多props,attrs
就是获取在子组件未定义的props,栗子
// 父组件
<chlidren title="这是标题" width="80" height="80" />
// 子组件
mounted() {
console.log(this.$attrs) //{title: "这是标题", width: "80", height: "80"}
},
//如果子组件定义了props,则剔除定义的属性
// 父组件
<chlidren title="这是标题" width="80" height="80" />
// 子组件
props: {
title: {
type: String,
default: ''
}
}
mounted() {
console.log(this.$attrs) //{ width: "80", height: "80"}
},
listeners
当子组件需要调用父组件的方法时,父组件可以通过 v-on='listeners'
传入组件内部
// 父组件
<chlidren @getList="getList" />
// 子组件
mounted() {
this.$listeners.getList //调用父组件里面的getList方法
},
-
parent
和children
//父组件
mounted(){
console.log(this.$children)
//可以拿到 一级子组件的属性和方法
//所以就可以直接改变 data,或者调用 methods 方法
}
//子组件
mounted(){
console.log(this.$parent) //可以拿到 parent 的属性和方法
}
$refs
// 父组件
<chlidren ref="chlidren"/>
mounted(){
console.log(this.$refs.chlidren) //可以拿到子组件的实例,就可以直接操作 data 和 methods
}
mixins
有些组件有些重复的 js
逻辑,如校验手机验证码,解析时间等
//mixin/alert.js
export default {
data() {
return {
dialogVisible: false,
}
},
methods: {
close(){
this.dialogVisible = false
},
open(){
this.dialogVisible = true
}
}
}
import mixinAlert from '@/mixin/alert.js'
mixins: [mixinAlert],
Vue.nextTick
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
<button @click="testClick()" ref="button">{{testMsg}}</button>
methods:{
testClick:function(){
this.testMsg="修改后的值";
console.log(this.$refs.button.innerText); //this.$refs.button,输出:原始值
}
}
methods:{
testClick:function(){
let that=this;
this.testMsg="修改后的值";
this.$nextTick(()=>{
console.log(this.$refs.button.innerText); //输出:修改后的值
});
}
}
directive
官方给我们提供了很多指令,但是我们如果想将文字变成指定的颜色定义成指令使用,这个时候就需要用到Vue.directive
// 全局定义
Vue.directive("change-color",function(el,binding,vnode){
el.style["color"]= binding.value;
})
// 使用
<template>
<div v-change-color="color">{{message}}</div>
</template>
<script>
export default{
data(){
return{
color:'green'
}
}
}
</script>
// el : 指令所绑定的元素,可以用来直接操作DOM
// binding: 一个对象,包含指令的很多信息
// vnode: VUE编译生成的虚拟节点
Vue.filter
过滤器,比如时间戳转时间格式
// 用法
{{xxxx| time}}
// 全局注册
Vue.filter('time', (value) =>{
// 处理逻辑
})
//局部处理
filters: {
time: (value)=> {
// 处理逻辑
}
}
v-pre
不编译,原样输出
<span v-pre>{{msg}}</span> //{{msg}}
// 即使data里定义了msg这里仍然是显示的{{msg}}
v-cloak
解决页面加载闪烁问题
v-once
只渲染一次
有些 template 中的静态 dom 没有改变,这时就只需要渲染一次,可以降低性能开销
事件修饰符
.stop //阻止冒泡
.prevent //阻止默认行为
.self //仅绑定元素自身触发
.once //只触发一次
.passive // 滚动事件的默认行为(即滚动行为)将会立即触发,不能和.prevent 一起使用
路由
- 缓存
keep-alive
<transition name="fade" mode="out-in">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
</transition>
<transition name="fade" mode="out-in" >
<router-view v-if="!$route.meta.keepAlive"/>
</transition>
keep-alive
的生命周期
初次进入时:created
> mounted
> activated
;退出后触发deactivated
再次进入:会触发 activated
;事件挂载的方法等,只执行一次的放在mounted
中;组件每次进去执行的方法放在 activated
中
- 路由钩子
router.beforeEach
router.beforeEach((to, from, next) => {
//一般登录拦截用这个,也叫导航钩子守卫
routers.beforeEach((to, from, next) => {
const { isLogin } = store.state
if (to.name === 'login' || isLogin) {
next()
} else {
routers.push({ name: 'login' })
}
})
https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
Vue.$router
this.$router.push() //跳转到不同的url,但这个方法回向history栈添加一个记录,点击后退会返回到上一个页面
this.$router.replace()//不会有记录
this.$router.go(n)//n可为正数可为负数。正数返回上一个页面,类似 window.history.go(n)
-
router-view
的key
由于 Vue
会复用相同组件, 即 /page/1 => /page/2 或者 /page?id=1 => /page?id=2 这类链接跳转时, 将不在执行created
,mounted
之类的钩子
<router-view :key="$route.fullpath"></router-view>
//这样组件的 created 和 mounted 就都会执行