vue 3.0 更好地複用和組合組件邏輯

項目背景:

本項目是基於vue2.x + vue-compostion-api基礎上,可能出在過分封裝,可是文章目的在於思考若是在vue 3.0更好地複用和組合組件邏輯.javascript

研究目的和意義

vue2.x的組件是基於選項的, 好比method必須寫在methods對象裏面,反觀vue3.0是基於函數的,不存在上述的制約.可是基於函數太過於自由,會致使咱們寫出麪條代碼,setup 函數會變的原來越大,最終組件愈來愈難維護.html

demo 介紹

界面一共有兩個輸入框,分別是frist-name,last-name和一個div 顯示nickname,每次鼠標失去焦點會更新nickname(fristName + lastName).vue

html 部分

`<div class="home">java

<form>
         <input id="first-name" placeholder="frist name" @blur="onFirstName" />
         <br/><br/>
         <input id="last-name" placeholder="last name"  @blur="onLasttName" />
          <br/>
         nickname: {{nickname}}
   </form>

</div>`react

javascript 部分

由於要從steup函數抽離重複的邏輯, state在onblur事件中脫離上下文,因此要建立build 函數給函數增長預設參數.api

function bind(fn: any, ...restArgs: any[]) {
    const args = new Array(restArgs.length);
    for (let i = 0; i < args.length; i++) {
      args[i] = restArgs[i];
    }
    return fn.bind(null, ...args);
}
import { defineComponent, reactive, toRefs } from '@vue/composition-api';
// code from hleper.ts
function bind(fn: any, ...restArgs: any[]) {
    const args = new Array(restArgs.length);
    for (let i = 0; i < args.length; i++) {
      args[i] = restArgs[i];
    }
    return fn.bind(null, ...args);
}

type State = {
      fristName: string;
      lastName: string;
      nickname: string;  // firstname + last name
}
interface OnBlurHandle {
    (state: State, value: string): void;
}
const composeNickName = (state: State) => {
        state.nickname =  `YJ ${state.fristName} ${state.lastName}`;
}
const validation = (value: string) => {
        // todo...
}
const onBlur = (state: State, fn: OnBlurHandle, event: Event) => {
      const value = (event.target as any).value;
      // other logic
      validation(value);
      composeNickName(state); 
      fn(state, value)
}
const onFirstName = (state: State, value: string) => {
    state.fristName = value;
}

const onLasttName = (state: State, value: string) => {
    state.lastName = value;
}
export default defineComponent({
  setup() {
      const state = reactive<State>({
         fristName: "",
         lastName: "",
         nickname: ''   // firstname + last name
      });

      return {
           onFirstName: bind(onBlur, state, onFirstName),
           onLasttName: bind(onBlur, state, onLasttName),
           ...toRefs(state)
      }
  }
})
相關文章
相關標籤/搜索