美文网首页
开发技巧

开发技巧

作者: 咔啡卟懂釢茶的清香 | 来源:发表于2020-06-28 10:52 被阅读0次

路由参数解耦

一般在组件内使用路由参数,大多数人会这样做:

export default {

    methods: {

        getParamsId() {

            return this.$route.params.id

        }

    }

}

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

正确的做法是通过 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

        })

    }]

})

文档 https://router.vuejs.org/zh/guide/essentials/passing-props.html


函数式组件

函数式组件是无状态,它无法实例化,没有任何的生命周期和方法。创建函数式组件也很简单,只需要在模板添加 functional 声明即可。一般适合只依赖于外部数据的变化而变化的组件,因其轻量,渲染性能也会有所提高。

组件需要的一切都是通过 context 参数传递。它是一个上下文对象,具体属性查看文档。这里 props 是一个包含所有绑定属性的对象。

 子组件 List.vue

<template functional>

    <div class="list">

        <div class="item" v-for="item in props.list" :key="item.id" @click="props.itemClick(item)">

            <p>{{item.title}}</p>

            <p>{{item.content}}</p>

        </div>

    </div>

</template>

父组件

<template>

    <div>

        <List :list="list" :itemClick="item => (currentItem = item)" />

    </div>

</template>

import List from '@/components/List.vue'

export default {

    components: {

        List

    },

    data() {

        return {

            list: [{

                title: 'title',

                content: 'content'

            }],

            currentItem: ''

        }

    }

}

样式穿透

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

我们可以使用 >>> 或 /deep/ 解决这一问题:

<style scoped>

外层 >>> .el-checkbox {

  display: block;

  font-size: 26px;

  .el-checkbox__label {

    font-size: 16px;

  }

}

</style>

<style scoped>

/deep/ .el-checkbox {

  display: block;

  font-size: 26px;

  .el-checkbox__label {

    font-size: 16px;

  }

}

</style>

watch高阶使用

立即执行

watch 是在监听属性改变时才会触发,有些时候,我们希望在组件创建后 watch 能够立即执行

可能想到的的方法就是在 create 生命周期中调用一次,但这样的写法不优雅,或许我们可以使用这样的方法

export default {

    data() {

        return {

            name: 'Joe'

        }

    },

    watch: {

        name: {

            handler: 'sayName',

            immediate: true

        }

    },

    methods: {

        sayName() {

            console.log(this.name)

        }

    }

}

深度监听

在监听对象时,对象内部的属性被改变时无法触发 watch ,我们可以为其设置深度监听

export default {

    data: {

        studen: {

            name: 'Joe',

            skill: {

                run: {

                    speed: 'fast'

                }

            }

        }

    },

    watch: {

        studen: {

            handler: 'sayName',

            deep: true

        }

    },

    methods: {

        sayName() {

            console.log(this.studen)

        }

    }

}

触发监听执行多个方法

使用数组可以设置多项,形式包括字符串、函数、对象

export default {

    data: {

        name: 'Joe'

    },

    watch: {

        name: [

            'sayName1',

            function(newVal, oldVal) {

                this.sayName2()

            },

            {

                handler: 'sayName3',

                immaediate: true

            }

        ]

    },

    methods: {

        sayName1() {

            console.log('sayName1==>', this.name)

        },

        sayName2() {

            console.log('sayName2==>', this.name)

        },

        sayName3() {

            console.log('sayName3==>', this.name)

        }

    }

}

watch监听多个变量

watch本身无法监听多个变量。但我们可以将需要监听的多个变量通过计算属性返回对象,再监听这个对象来实现“监听多个变量”

export default {

    data() {

        return {

            msg1: 'apple',

            msg2: 'banana'

        }

    },

    compouted: {

        msgObj() {

            const { msg1, msg2 } = this

            return {

                msg1,

                msg2

            }

        }

    },

    watch: {

        msgObj: {

            handler(newVal, oldVal) {

                if (newVal.msg1 != oldVal.msg1) {

                    console.log('msg1 is change')

                }

                if (newVal.msg2 != oldVal.msg2) {

                    console.log('msg2 is change')

                }

            },

            deep: true

        }

    }

}

监听组件生命周期

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

子组件

export default {

    mounted() {

        this.$emit('listenMounted')

    }

}

父组件

<template>

    <div>

        <List @listenMounted="listenMounted" />

    </div>

</template>

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

<template>

    <List @hook:mounted="listenMounted" />

</template>

相关文章

网友评论

      本文标题:开发技巧

      本文链接:https://www.haomeiwen.com/subject/jjyifktx.html