vue 复用组件要注意
bug来源
我封装了一个键盘组件,在页面复用了三次.点击input1弹出键盘组件1...
点击键盘组件1给input1赋值, 我点击input2弹出键盘组件2给input2赋值时会将input1的值赋值到input2上.
代码如下
1.默认页面如下
2.输入666
3.切换组件2,输入999
为什么将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种解决方法:
- 使用 key 进行区分
- 使用 v-show (v-show不会删除真实dom,只会添加style进行隐藏.而我在切换时使用的还是input2的真实dom.)