logoSpectreAlan's blogs
vue2.x使用技巧
标签:
Vue
类别:web前端
创建时间: 2019-12-12 15:47:20
字数总计: 3.16 k
建议阅读时长: 4 分钟
阅读量: 255

路由参数解耦

通常情况下我们在组件内获取路由参数的办法是:

1export default { 2 computed: { 3 paramsId () { 4 return this.$route.params.id 5 } 6 } 7}

在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。 正确的做法是通过 props 解耦

1const router = new VueRouter({ 2 routes: [{ 3 path: /user/:id , 4 component: User, 5 props: true 6 }] 7})

将路由的 props 属性设置为 true 后,组件内可通过 props 接收到 params 参数

1export default { 2 props: [ id ] 3}

另外还可以通过函数模式来返回 props

1const router = new VueRouter({ 2 routes: [{ 3 path: /user/:id , 4 component: User, 5 props: (route) => ({ 6 id: route.query.id 7 }) 8 }] 9})

函数式组件

函数式组件是无状态,它无法实例化,没有任何的生命周期和方法。创建函数式组件也很简单,只需要在模板添加 functional 声明即可。一般适合只依赖于外部数据的变化而变化的组件,因其轻量,渲染性能也会有所提高。 组件需要的一切都是通过 context 参数传递。它是一个上下文对象,具体属性查看文档。这里 props 是一个包含所有绑定属性的对象。 函数式组件

1<template functional> 2 <div class="list"> 3 <div class="item" v-for="item in props.list" :key="item.id" @click="props.itemClick(item)"> 4 <p>{{item.title}}</p> 5 <p>{{item.content}}</p> 6 </div> 7 </div> 8</template>

父组件使用

1<template> 2 <div> 3 <List :list="list" :itemClick="item => (currentItem = item)" /> 4 </div> 5</template> 6import List from @/components/List.vue 7export default { 8 components: { 9 List 10 }, 11 data() { 12 return { 13 list: [{ 14 title: title , 15 content: content 16 }], 17 currentItem: null 18 } 19 } 20}

样式穿透

在开发中修改第三方组件样式是很常见,但由于 scoped 属性的样式隔离,可能需要去除 scoped 或是另起一个 style 。这些做法都会带来副作用(组件样式污染、不够优雅),样式穿透在css预处理器中使用才生效。 我们可以使用 >>> 或 /deep/ 解决这一问题:

1<style scoped> 2外层 >>> .el-checkbox { 3 display: block; 4 font-size: 26px; 5 6 .el-checkbox__label { 7 font-size: 16px; 8 } 9} 10</style> 11<style scoped> 12/deep/ .el-checkbox { 13 display: block; 14 font-size: 26px; 15 16 .el-checkbox__label { 17 font-size: 16px; 18 } 19} 20</style>

监听组件生命周期

通常我们监听组件生命周期会使用 $emit ,父组件接收事件来进行通知 子组件

1export default { 2 mounted() { 3 this.$emit( listenMounted ) 4 } 5} 6// 父组件 7<template> 8 <div> 9 <List @listenMounted="listenMounted" /> 10 </div> 11</template>

其实还有一种简洁的方法,使用 @hook 即可监听组件生命周期,组件内无需做任何改变。同样的, created 、 updated 等也可以使用此方法。

1<template> 2 <List @hook:mounted="listenMounted" /> 3</template>

优雅的处理定时器

在页面挂载时定义计时器,需要在页面销毁时清除定时器。这看起来没什么问题。但仔细一看 this.timer 唯一的作用只是为了能够在 beforeDestroy 内取到计时器序号,除此之外没有任何用处。

1export default { 2 mounted() { 3 this.timer = setInterval(() => { 4 console.log(Date.now()) 5 }, 1000) 6 }, 7 beforeDestroy() { 8 clearInterval(this.timer) 9 } 10}

如果可以的话最好只有生命周期钩子可以访问到它。这并不算严重的问题,但是它可以被视为杂物。 我们可以通过 $on 或 $once 监听页面生命周期销毁来解决这个问题:

1export default { 2 mounted() { 3 this.creatInterval( hello ) 4 this.creatInterval( world ) 5 }, 6 creatInterval(msg) { 7 let timer = setInterval(() => { 8 console.log(msg) 9 }, 1000) 10 this.$once( hook:beforeDestroy , function() { 11 clearInterval(timer) 12 }) 13 } 14}

使用这个方法后,即使我们同时创建多个计时器,也不影响效果。因为它们会在页面销毁后程序化的自主清除。

吐槽一下
copyright