共计 4673 个字符,预计需要花费 12 分钟才能阅读完成。
起源:公众号《前端全栈开发者》
当初,Vue.js 已成为前端开发的热门框架。有很多工程师利用 Vue.js 的便利性和弱小性能。然而,咱们实现的某些解决方案可能未遵循最佳做法。好吧,让咱们看一下那些必备的 Vue 技术。
1. 函数组件
函数组件 是无状态的,没有生命周期或办法,因而无奈实例化
创立一个函数组件非常容易,你须要做的就是在 SFC 中增加一个 functional: true
属性,或者在模板中增加 functional
。因为它像函数一样笨重,没有实例援用,所以渲染性能进步了不少。
函数组件依赖于上下文,并随着其中给定的数据而渐变。
<template functional>
<div class="book">
{{props.book.name}} {{props.book.price}}
</div>
</template>
<script>
Vue.component('book', {
functional: true,
props: {
book: {type: () => ({}),
required: true
}
},
render: function (createElement, context) {
return createElement(
'div',
{
attrs: {class: 'book'}
},
[context.props.book]
)
}
})
</script>
2. 深层选择器
有时,你须要批改第三方组件的 CSS,这些都是 scoped
款式,移除 scope
或关上一个新的款式是不可能的。
当初,深层选择器 >>>
/deep/
::v-deep
能够帮忙你。
<style scoped>
>>> .scoped-third-party-class {color: gray;}
</style>
<style scoped>
/deep/ .scoped-third-party-class {color: gray;}
</style>
<style scoped>
::v-deep .scoped-third-party-class {color: gray;}
</style>
3. 高级“watcher”
立刻执行
当被监控的 prop 产生渐变时,watch handler 就会触发。但有时,它是在组件被创立后才呈现的。
是的,有一个简略的解决方案:在 created
的钩子中调用处理程序,但这看起来并不优雅,同时也减少了复杂性。
或者,你能够向观察者增加 immediate
属性:
watch: {
value: {
handler: 'printValue',
immediate: true
}
},
methods : {printValue () {console.log(this.value)
}
}
深度监听
有时,watch 属性是一个对象,然而其属性渐变无奈触发 wacher 处理程序。在这种状况下,为观察者增加 deep:true
能够使其属性的渐变可检测到。
请留神,当对象具备多个层时,深层可能会导致一些重大的性能问题。最好思考应用更扁平的数据结构。
data () {
return {
value: {
one: {
two: {three: 3}
}
}
}
},
watch: {
value: {
handler: 'printValue',
deep: true
}
},
methods : {printValue () {console.log(this.value)
}
}
多个 handlers
实际上,watch 能够设置为数组,反对的类型为 String、Function、Object。触发后,注册的 watch 处理程序将被一一调用。
watch: {
value: [
'printValue',
function (val, oldVal) {console.log(val)
},
{
handler: 'printValue',
deep: true
}
]
},
methods : {printValue () {console.log(this.value)
}
}
订阅多个变量渐变
watcher
不能监听多个变量,但咱们能够将指标组合在一起作为一个新的 computed
,并监督这个新的 “ 变量 ”。
computed: {multipleValues () {
return {
value1: this.value1,
value2: this.value2,
}
}
},
watch: {multipleValues (val, oldVal) {console.log(val)
}
}
4. 事件参数:$event
$event
是事件对象的一个非凡变量。它在某些场景下为简单的性能提供了更多的可选参数。
原生事件
在原生事件中,该值与默认事件(DOM 事件或窗口事件)雷同。
<template>
<input type="text" @input="handleInput('hello', $event)" />
</template>
<script>
export default {
methods: {handleInput (val, e) {console.log(e.target.value) // hello
}
}
}
</script>
自定义事件
在自定义事件中,该值是从其子组件中捕捉的值。
<!-- Child -->
<template>
<input type="text" @input="$emit('custom-event','hello')" />
</template>
<!-- Parent -->
<template>
<Child @custom-event="handleCustomevent" />
</template>
<script>
export default {
methods: {handleCustomevent (value) {console.log(value) // hello
}
}
}
</script>
5. 路由器参数解耦
我置信这是大多数人解决组件中路由器参数的形式:
export default {
methods: {getRouteParamsId() {return this.$route.params.id}
}
}
在组件外部应用 $route
会对某个 URL 产生强耦合,这限度了组件的灵活性。
正确的解决方案是向路由器增加 props。
const router = new VueRouter({
routes: [{
path: '/:id',
component: Component,
props: true
}]
})
这样,组件能够间接从 props 获取 params
。
export default {props: ['id'],
methods: {getParamsId() {return this.id}
}
}
此外,你还能够传入函数以返回自定义 props
。
const router = new VueRouter({
routes: [{
path: '/:id',
component: Component,
props: router => ({id: route.query.id})
}]
})
6. 自定义组件的双向绑定
容许自定义组件在应用
v-model
时自定义使 props 和 event。默认状况下,组件上的 v -model 应用 value 作为属性,Input 作为事件,但一些输出类型,如复选框和单选按钮可能心愿应用 value 属性来实现不同的目标。在这种状况下,应用 model 选项能够防止抵触。
v-model
是家喻户晓的双向绑定。input
是默认的更新事件。能够通过 $emit
更新该值。惟一的限度是该组件须要 <input>
标记能力与 value
属性绑定。
<my-checkbox v-model="val"></my-checkbox>
<template>
<input type="checkbox" :value="value" @input="handleInputChange(value)" />
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default: false
}
},
methods: {handleInputChange (val) {console.log(val)
}
}
}
</script>
双向绑定还有另一种解决方案,即 sync
修饰符。与 v-model
不同的是,它不须要你的组件有一个 <input>
标签并将值绑定到它下面。它仅触发 update:<your_prop>
通过事件系统对属性进行渐变。
<custom-component :value.sync="value" />
7. 组件生命周期 Hook
通常,你能够像这样监听子组件的生命周期(例如 mounted
)
<!-- Child -->
<script>
export default {mounted () {this.$emit('onMounted')
}
}
</script>
<!-- Parent -->
<template>
<Child @onMounted="handleOnMounted" />
</template>
还有另一种简略的解决方案,你能够改用 @hook:mount
在 Vue 外部零碎中应用。
<!-- Parent -->
<template>
<Child @hook:mounted="handleOnMounted" />
</template>
8. 事件监听 APIs
比方,在页面挂载时减少一个定时器,但销毁时须要革除定时器。这看起来不错。
坦率地说,只有在 beforeDestroy
中应用 this.timer
来获取计时器 ID 才有意义。并非厚道,而是变量越少,性能越好。
export default {data () {
return {timer: null}
},
mounted () {this.timer = setInterval(() => {console.log(Date.now())
}, 1000)
},
beforeDestroy () {clearInterval(this.timer)
}
}
使其只能在生命周期钩子内拜访。应用 $once
来放弃不必要的货色。
export default {mounted () {
let timer = null
timer = setInterval(() => {console.log(Date.now())
}, 1000)
this.$once('hook:beforeDestroy', () => {clearInterval(timer)
})
}
}
9. 以编程形式挂载组件
在某些状况下,以编程形式加载组件要优雅得多。例如,能够通过全局上下文 $popup()
或 $modal.open()
关上弹出窗口或模态窗口。
import Vue from 'vue'
import Popup from './popup'
const PopupCtor = Vue.extend(Popup)
const PopupIns = new PopupCtr()
PopupIns.$mount()
document.body.append(PopupIns.$el)
Vue.prototype.$popup = Vue.$popup = function () {PopupIns.open()
}
Element UI 实现了构造良好的模式组件,该组件容许应用自定义 API 来管制实例的生命周期。该实践与我下面演示的简直雷同。
这是无关 Vue 2.x 的 9 种技术,心愿在本文中你能够对应用框架有更好的理解。如果你认为本文很棒,请在其余社交网络上分享。
举荐浏览
- 2020 年的 12 个 Vue.js 开发技巧和诀窍
- 在 Vue.js 编写更好的 v -for 循环的 6 种技巧
- React.js 和 Vue.js 的语法并列比拟
- Vue 技巧 | 在 Vue3 中使元素在滚动视图时淡入
- Vue 3 教程(实用于 Vue 2 用户)