提交 5fee8623 编写于 作者: DCloud_Heavensoft's avatar DCloud_Heavensoft

Update README.md

上级 323ba9bf
......@@ -10,25 +10,49 @@ uni-app x 项目在编译到小程序平台时,将部分特性对齐了web与a
## vue
### 组件启用virtualHost
### 自定义组件启用virtualHost带来的影响@virtualHost
uni-app x 项目在编译到小程序端时,为了避免自定义组件多一层dom嵌套影响flex等样式而默认启用了virtualHost,同时默认启用了[mergeVirtualHostAttributes特性](https://uniapp.dcloud.net.cn/collocation/manifest.html#mp-weixin)
标准的小程序下的自定义组件会多套一层DOM,这会影响flex等样式。而uni-app x默认都是flex的
启用virtualHost会让组件在实际渲染时不会额外包裹一层dom节点。这会对组件外使用选择器选择组件产生影响。
所以为了拉齐样式表现,uni-app x 项目在编译到小程序时,默认启用了virtualHost,该配置是小程序平台提供的一种策略,可以取消多套的一层。\n
同时默认启用了[mergeVirtualHostAttributes特性](https://uniapp.dcloud.net.cn/collocation/manifest.html#mp-weixin),在取消多套的一层后,将原本父层的属性设置,合并到子层。
* 无法在组件外层通过 getElementById 获取到自定义组件 UniElement 对象。
* 无法在组件外层通过 SelectorQuery 获取到自定义组件的信息。但可以通过将自定义组件的实例传入 in 参数来获取。
`去掉一层`以及`合并父属性到子`,这2件事会对真实渲染的DOM产生影响。*尤其会影响在组件外获取组件的DOM*
```js
uni.createSelectorQuery().in(this.$refs.xx).select('.xx').boundingClientRect((data) => {
console.log('boundingClientRect:', data)
}).exec()
我们先看一个例子:
有个组件c1,父级外层代码如下
```html
<c1 id="c1parent" ref="c1ref" class="class1parent"></c1>
```
c1组件的代码如下:
```html
<template>
<view class="classchild">
</view>
</template>
```
mergeVirtualHostAttributes合并策略
* 会将组件外层设置的 style、class 以及 v-show 指令生成的 hidden 属性合并到组件根节点上。比如外层设置了一个 id,是不会自动合并到组件根节点上的,此时通过uni.createSelectorQuery()是无法使用id选择器获取到根节点的。但因为class会合并,所以通过class选择器可以获取到根节点。
* 仅对组件是单个根节点才会合并,组件内多个根节点的时候不会合并。
然后看下mergeVirtualHostAttributes属性合并策略:
1. 仅将组件外层设置的 style、class 以及 v-show 指令生成的 hidden 属性,这3个属性合并到组件根节点上,其他外层设置的属性都丢弃了。
2. 仅对组件是单个根节点才会合并,组件内多个根节点的时候不会合并。父层全部丢弃。
根据策略看,上述代码在运行时合并后,父层的id丢掉了,class属性合并,所以`class1parent``classchild` 同时生效。
那么父层通过`uni.getElementById("c1parent")`是拿不到UniElement的。
同样父层通过`uni.createSelectorQuery().in(this.$page).select('#c1parent')`也拿不到NodesRef。
但createSelectorQuery是支持设定查找范围的,上面的代码是在页面里查找,如果在父层代码里通过in方法指定查找组件,例如:`uni.createSelectorQuery().in(this.$refs['c1ref'] as ComponentPublicInstance).select('.class1parent') `,可以拿到c1组件的NodesRef
实际上,不管是通过`.class1parent` 还是 `.classchild`,都可以拿到。因为样式合并后,这2个class在运行时同时存在。
假使在c1组件内部的根节点上设置了id属性`c1child`,通过`uni.createSelectorQuery().in(this.$refs['c1ref'] as ComponentPublicInstance).select('#c1child')`也可以获取。只是很少有组件会这么做。
获取组件的NodesRef,主要的用途是获取boundingClientRect,受小程序限制,这个使用场景目前有点复杂。DCloud会继续寻找优化方案。
vue组件的方法调用不受影响。
### refs@refs
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册