场景:有些时候后台返回的图片不一定能加载成功,加载失败默认显示一张图片
<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 组件,里面层级是根据后台数据决定的,这个时候就需要用到动态组件
父组件:
<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
})
}]
})
由于 Vue 会复用相同组件,例如 /page?id=1 => /page?id=2 这类跳转的情况,组件将不会执行 created, mounted 等钩子函数,此时常用解决方案如下。
watch: {
$route (to, from) {
console.log(to, '....') // 可以监听到路由的变化,例如从详情1跳转到详情2
}
},
// $route.fullPath: 完成解析后的 URL,包含查询参数和 hash 的完整路径
<router-view :key="$route.fullPath"></router-view>
注:如果没有类似的场景不建议使用,毕竟每次渲染还是要付出一丢丢性能代价的。
首先新建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)