七個意想不到的vue pattern

週末在家刷如懿傳,順帶在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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章