vue 复用组件要注意

304 阅读1分钟

vue 复用组件要注意

bug来源

我封装了一个键盘组件,在页面复用了三次.点击input1弹出键盘组件1...

点击键盘组件1给input1赋值, 我点击input2弹出键盘组件2给input2赋值时会将input1的值赋值到input2上.

代码如下

1.默认页面如下

image.png

2.输入666

image.png

3.切换组件2,输入999

image.png

image.png

为什么将input1的值带过来了

代码如下


          <uni-easyinput type="text" :clearable="false" v-model="value1" @focus="handleFocus(0)">
          <uni-easyinput type="text" :clearable="false" v-model="value2" @focus="handleFocus(1)">
          <uni-easyinput type="text" :clearable="false" v-model="value3" @focus="handleFocus(2)">
          
        <view v-if="isShow[0]">
          组件1
          <f-keyboard  :value="value1"  @change="change1" @confirm="confirm"></f-keyboard>
        </view>
        <view v-else-if="isShow[1]">
          组件2
          <f-keyboard  :value="value2" :isDecimal="false" @change="change2" @confirm="confirm"></f-keyboard>
        </view>
        <view v-else-if="isShow[2]">
          组件3
          <f-keyboard  :value="value3"  @change="change3" @confirm="confirm"></f-keyboard>
        </view>

那么问题来了,我用v-if,v-else-if进行判断了.而组件都会进行作用域隔离,即一个组件实例拥有一个私有的作用域.为啥还会将input1的值给input2呢

经过查询vue的渲染方式得知: 组件在渲染之前,生成虚拟dom.根据虚拟dom来渲染真实dom.如果发生改变,vue将生成新的虚拟dom("新的虚拟DOM" 并不会直接生成 "新的真实DOM",Vue会拿 "新的虚拟DOM" 与之前的 "真实的DOM" 去做比较.如果相同,直接使用.如果不同,则生成新的DOM对象.). 而问题就出在这儿: 我点击input2时.因为没有key得缘故,input2渲染真实dom的时候,会取input1的真实dom作为input2虚拟dom进行渲染.而这样,就将input1的值附加到input2上了.

2种解决方法:

  1. 使用 key 进行区分
  1. 使用 v-show (v-show不会删除真实dom,只会添加style进行隐藏.而我在切换时使用的还是input2的真实dom.)