img图片加载失败
场景:有些时候后台返回的图片不一定能加载成功,加载失败默认显示一张图片
<template>
<div>
<img :src="imgUrl" @error="handleError" alt="">
</div>
</template>
<script>
export default {
data () {
return {
imgUrl: ''
}
},
methods: {
handleError (e) {
e.target.src = require('@/assets/logo.png')
}
}
}
</script>
组件级路由钩子
beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被确认前调用
console.log(to)
console.log(from)
next()
},
beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由调用
next()
}
递归组件
场景:如果开发一个 tree 组件,里面层级是根据后台数据决定的,这个时候就需要用到动态组件
- 递归组件: 组件在它的模板内可以递归的调用自己,只要给组件设置name组件就可以了。
- 设置那么House在组件模板内就可以递归使用了,不过需要注意的是,
- 必须给一个条件来限制数量,否则会抛出错误: max stack size exceeded
- 组件递归用来开发一些具体有未知层级关系的独立组件。比如:联级选择器和树形控件
父组件:
<template>
<div>
<Tree :treeArr="treeArr"></Tree>
</div>
</template>
<script>
import Tree from './tree.vue'
export default {
components: {
Tree
},
data () {
return {
imgUrl: '',
treeArr: [
{
id: 1,
expand: true,
name: '二级节点1',
children: [{
id: 12,
expand: true,
name: '三级节点1'
}]
},
{
id: 2,
expand: true,
name: '二级节点2',
children: [{
id: 21,
expand: true,
name: '三级节点2'
}]
}
]
}
}
}
</script>
子组件:
<template>
<div>
<div v-for="(item, index) in treeArr">
<div :key="item.id">
{{item.name}}
<!-- 递归调用自身,后台判断是否存在该值 -->
<Tree :treeArr="item.children" v-if="item.expand"></Tree>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Tree', // 必须定义name,组件内部递归使用
props: {
treeArr: {
type: Array,
default: () => []
}
}
}
</script>
路由参数解耦
-
一般在组件内使用路由参数,大多数人会这样做:
export default { methods: { getParamsId() { return this.$route.params.id } } }
-
正确的做法是通过 props 解耦
const router = new VueRouter({ routes: [{ path: '/user/:id', component: User, props: true }] })
将路由的 props 属性设置为 true 后,组件内可通过 props 接收到 params 参数
export default {
props: ['id'],
methods: {
getParamsId() {
return this.id
}
}
}
-
还可以通过函数模式来返回 props
const router = new VueRouter({ routes: [{ path: '/user/:id', component: User, props: (route) => ({ id: route.query.id }) }] })
Router key
由于 Vue 会复用相同组件,例如 /page?id=1 => /page?id=2 这类跳转的情况,组件将不会执行 created, mounted 等钩子函数,此时常用解决方案如下。
watch监听
watch: {
$route (to, from) {
console.log(to, '....') // 可以监听到路由的变化,例如从详情1跳转到详情2
}
},
给 router-view 绑定一个 unique key
// $route.fullPath: 完成解析后的 URL,包含查询参数和 hash 的完整路径
<router-view :key="$route.fullPath"></router-view>
注:如果没有类似的场景不建议使用,毕竟每次渲染还是要付出一丢丢性能代价的。
通过Vue.use()使用install创建自定义组件
-
首先新建loading文件夹,并在文件夹内新建loading.vue和index.js文件
<template> <div> Loading.... </div> </template>
-
编辑index.js,核心为install属性,
import LoadingComponent from './Loading' const Loading = { install: (Vue) => { Vue.component('Loading', LoadingComponent) } } export default Loading
-
main.js中引入相应的组件并用vue.use()使用组件
import Loading from '@/components/index' Vue.use(Loading)
统一处理方式
index.js
import LoadingComponent from '@/components/Loading'
const customCom = (Vue) => {
const Loading = {
install: () => {
Vue.component('Loading', LoadingComponent)
}
}
Vue.use(Loading)
}
export default customCom
main.js
import customCom from './components/index.js'
customCom(Vue)