欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue2封裝input組件方式(輸入的雙向綁定)

 更新時(shí)間:2023年04月23日 09:03:03   作者:查水表小泰迪  
這篇文章主要介紹了vue2封裝input組件方式(輸入的雙向綁定),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。

vue2封裝input組件

重點(diǎn)

首先我們要明白 vue中v-modle 的對(duì)于input 做了什么

	<input type="text" v-model="username">
    <input type="text" :value="username" @input="username = $event.target.value">

以上的兩行代碼,所呈現(xiàn)的效果是一樣的。也就是說(shuō): v-model=“username” 在input中做了兩件事情。

  • :value 綁定了值
  • @input=“username = $event.target.value” 監(jiān)聽(tīng)了值的改變

代碼示例:

父組件

<template>
  <div id="app">
    <lj-input placeholder="請(qǐng)輸入" v-model="username"></lj-input>
    <div>{{username}}</div>
  </div>
</template>

<script>
import ljInput from './components/inputCom/LjInput.vue'
export default {
  name: 'App',
  components: {
    ljInput
  },
  data(){
    return{
      username:'',
    }
  },
  methods: {
  }
}
</script>

子組件

<template>
  <div class="lj-input">
    <input :class="{'is-disabled':disabled}"  
    :placeholder="placeholder" 
    :type="type" 
    :disabled ='disabled'
    :value="value"
    @input="handleInput"
    >
  </div>
</template>

<script>
export default {
  name:'ljInput',
  props: {
    placeholder:{
      type:String,
      default:'' 
    },
    type:{
      type:String,
      default:''
    },
    disabled:{
      type:Boolean,
      default:false
    },
    value:{
      type:String,
      default:''
    }
  },
  methods:{
    handleInput(e){
   	 // 這句代碼是關(guān)鍵
      this.$emit('input',e.target.value) 
    }
  }
}
</script>

<style>
  .is-disabled{
      cursor: not-allowed;
  }
</style>

vue二次封裝input的幾種方式

下面就是自己封裝input 框?qū)崿F(xiàn)的效果

在看如何封裝之前,先來(lái)了解一下v-model是怎么回事。

clipboard.png

其實(shí)說(shuō)白了,v-model就是change和value的結(jié)合體。

廢話不多說(shuō),下面就來(lái)看一下在vue中如何封裝自定義的input組件。

封裝原生input

<template>
  <input type="text"  :value="value" @input="handleChange" />
</template>

<script>
export default {
  name: "AppInput",
  model: {
    prop: "value",
    event: "change",
  },
  props: {
    value: "",
  },
  data() {
    return {
    };
  },
  created() {},
  mounted() {},
  methods: {
    handleChange(e) {
      this.$emit("change", e.target.value);
    },
  },
};
</script>

封裝el-input

<template>
<!--  對(duì)el-input進(jìn)行了包裝-->
  <div>
    <el-input
      v-model="localValue"
      @change="$emit('change', $event)"></el-input>
      <!--
      el-input提供了input事件,讓我們感知el-input內(nèi)部原生input值的變化,通過(guò)$event可以獲取到具體的值
      通過(guò)emit再次傳遞給父組件一個(gè)input事件,父組件中,v-on:input="searchText = $event"這句就能正常使用了
      -->
    <span style="color: #f56c6c; font-size: 12px;"></span>
  </div>
</template>
 
<script>
    export default {
      name: "input-name",
      props: {
        // 保證父組件中,v-bind:value可以正常設(shè)置值
        value: [String],
      },
      data() {
        return {
          // 獲取props中value的值,并與el-input綁定,過(guò)程中不修改props中value的值,保證了單向數(shù)據(jù)流原則
          localValue: this.value
        }
      }
    }
</script>
<style lang="less" scoped>
</style>

上面的那種方式會(huì)在回顯數(shù)據(jù)時(shí)有問(wèn)題。解決辦法就是:如果出現(xiàn)異步回顯數(shù)據(jù)那么就需要用計(jì)算來(lái)作為中間值轉(zhuǎn)換。

<template>
<!--  對(duì)el-input進(jìn)行了包裝-->
  <div>
    <el-input
      v-model="localValue"
      @change="$emit('change', $event)"></el-input>
      <!--
      el-input提供了input事件,讓我們感知el-input內(nèi)部原生input值的變化,通過(guò)$event可以獲取到具體的值
      通過(guò)emit再次傳遞給父組件一個(gè)input事件,父組件中,v-on:input="searchText = $event"這句就能正常使用了
      -->
    <span style="color: #f56c6c; font-size: 12px;"></span>
  </div>
</template>
 
<script>
    export default {
      name: "input-name",
      props: {
        // 保證父組件中,v-bind:value可以正常設(shè)置值
        value: [String],
      },
      data() {
        return {
         
        }
      },
      computed: {
        localValue: {
          get: function () {
            console.log(this.value)
            return this.value;
          },
          set: function (v) {
            v;
          },
        },
  },
    }
</script>
<style lang="less" scoped>
</style>

VUE高級(jí)用法封裝input

這種方式更加簡(jiǎn)潔,并且不會(huì)出現(xiàn)第二種封裝方式出現(xiàn)的bug。

<template>
//這里不能使用v-model,會(huì)報(bào)子組件不能直接操作父組件傳入?yún)?shù)的錯(cuò)誤
//使用value的話其實(shí)就是做一個(gè)回顯因?yàn)橥鈱拥膙-model在這里使用已經(jīng)改變了外層的值了
    <el-input
      v-bind="$attrs"
      v-on="$listeners"
      :value="value"
    ></el-input>
</template>
<script>
export default {
  name: "f-input",
  data() {
    return {
    };
  },
  props: {
    value:""
  },
  created() {},
  mounted() {},
  methods: {}
};
</script>
//正常的使用方式
<f-input v-model="number"></f-input>
//不用v-model語(yǔ)法糖的方式
<f-input  :value="number" @change="number = $event,target.value"></f-input>

這里核心用到了兩個(gè)方法 attrs 和 listeners 其中 atters 可以把父組件標(biāo)簽上的所有自定義屬性(不包括props,tyle,class)同步到當(dāng)前元素中,listeners 可以把 f-input 標(biāo)簽上的所有方法同步到子組件中當(dāng)前元素中。

那么上面已經(jīng)知道 v-model 就是 change 和 value 的語(yǔ)法糖,那在 f-input 上綁定 listeners 就可以讀取到 f-input 的 v-model 的 change 事件,atters 可以讀取到 f-input 的 v-model 的 value 值。

$ 符號(hào)打不出來(lái)了,將就著看吧。如果還是不明白 atters和 listeners是怎么回事的可以看一下vue官網(wǎng)中的介紹。

image.png

看官網(wǎng)又出了一種封裝的寫法,感覺(jué)挺有意思,在這里記錄一下。

默認(rèn)情況下,組件上的 v-model 使用 modelValue 作為 prop 和 update:modelValue 作為事件。我們可以通過(guò)向 v-model 傳遞參數(shù)來(lái)修改這些名稱

子組件將需要一個(gè) firstName prop 和 lastName prop并發(fā)出 update:firstName 和 update:lastName要同步的事件

var Component = {
        props: {
            firstName: String,
            lastName: String
        },
        emits: ['update:firstName', 'update:lastName'],
        //vue3可以支持多個(gè)根元素,所有這個(gè)地方不會(huì)有報(bào)錯(cuò),vue2是會(huì)報(bào)錯(cuò)的。
        template: `
                <input 
                type="text"
                :value="firstName"
                @input="$emit('update:firstName', $event.target.value)">

                <input
                type="text"
                :value="lastName"
                @input="$emit('update:lastName', $event.target.value)">
            `
    }
<template>
  <my-component 
          v-model:first-name="firstName"
          v-model:last-name="lastName">
  </my-component>
  firstName:{{firstName}} lastName:{{lastName}}
</template>

<script>
   const App = {
        setup(props, context) {
            const data= reactive({
                firstName: 0,
                lastName: 0,
            });
            return {
                ...toRefs(data),
            }
        },
        components: {
            'my-component': Component,
        },
        methods: { },
    };
    const app = createApp(App).mount('#app');
</script>

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論