七个意想不到的vue pattern
周末在家刷如懿传,顺带在youtube看了一个7-secret-patterns-about-vue的视频,讲得还蛮有意思的,确实有些地方意想不到。更多内容参见作者的github仓库。productivity Boostssmart watcherscomponent Registrationmodule Registrationradical Tweakscleaner v...
周末在家刷如懿传,顺带在youtube看了一个7-secret-patterns-about-vue的视频,讲得还蛮有意思的,确实有些地方意想不到。更多内容参见作者的github仓库。
productivity Boosts
smart watchers
watch : {
msg: {
handler: 'fetchUserList', // fetchUserList is one of this.methods
immediate: true // call it on created
}
}
component Registration
用webpack的require.context来引入到处都会用到的components,注意缺点是打出来的包体积会变大,不如用到哪个引入哪个小。
// main.js
const requireComponent = require.context('.', false, /base-[\w-]+\.vue$/)
requireComponent.keys().forEach(fileName => {
const componentConfig = requireComponent(fileName)
const copmponentName = upperFirst(
camelCase(fileName.replace(/^\.\//,'').replace(/\.\w+$/,''))
)
Vue.component(componentName, componentConfig.default || componentConfig)
})
这里先去找default再去找本身,是因为import/export的机制与commonjs的引入机制不同。es6里的import会自动import它的default,commonjs则不同。另外我用的是vue-cli3,在main.js中引入.vue文件,内容是在default中,不管有没有<script>标签。
module Registration
跟component Registration 原理一样,但不用考虑增加了包体积的问题,相比更为实用。注意在forEach中需要加上这句,把本身摘出去。
// index.js
if(fileName === './index.js') return
// 如果要加上namespaced, 用解构写法
modules[moduleName] = {
namespaced: true,
...requireModule(fileName)
}
radical Tweaks
cleaner views
在router-view上挂一个key,每次都重新生成。就不用watch route 的变化了。
// html
<router-view :key="$route.params.id">
// .vue
created() {
this.getPost(this.$route.params.id)
}
transparent Wrappers
适用于表单控件,把父组件的$listeners传给了子组件。v-on上和v-bind上都可以传入对象,分别绑$attrs和$listeners。
<!--BaseInput.vue-->
<template>
<label>
{{ label }}
<input v-bind="$attrs" :value="value" v-on="listeners" />
</label>
</template>
<!--App.vue -->
<BaseInput placeholder="who am i" @focus="doSomething" />
listeners() {
return {
...this.$listeners,
input: event => this.$emit('input', event.target.value)
}
}
unlocked Possibilities
single-root component
适用于要列表渲染但没有一个根元素的时候。直接render jsx。
// LI.vue
<script>
export default {
functional: true,
render(h, {props}) {
return props.route.map(route =>
<li key={route.name}>
<router-link to={route}>
{route.title}
</router-link>
</li>
)
}
}
</script>
rendering non-html
用于和第三方库共同使用的时候,实际的渲染是第三方库做的。主要包括三点:
- created的时候 从$parent里拿到父组件,获取其data来操作。
- beforeDestroy的时候,同样获取$parent的属性,移除第三方库的方法。
- 手写render,return null。
这个代码比较多,具体可以参见作者的sandbox
更多推荐
所有评论(0)