公司的项目,记录开发快应用中踩的坑。javascript
版本:1030css
更新日期:2019-07-10html
PS:由于版本更新会有些快,手机的换代有些快,因此可能这里说的问题在手机上并不会出现问题,因此这里仅供参考。vue
UI的坑太多了,太多不支持了,感受一时也列表出太多。简单写写吧。java
快应用太多选择器不支持,详见官方文档:快应用 - style 样式编程
太多规则不支持,而且建议不要省略样式的定义,会出现没法预料的问题。bash
<!-- 本来的写法 -->
.a,
.b {
color: red;
}
.a {
font-size: 14px;
}
.b {
font-size: 20px;
}
<!--建议写法-->
.a {
color: red;
font-size: 14px;
}
.b {
color: red;
font-size: 20px;
}
复制代码
包括动画的,若是 0% 和 100% 是如出一辙的,也要分开。。由于...就是不支持。。会出现编辑器ok手机不ok。。。app
建议使用某种布局的工具,像咱们公司使用的一个 flex 布局的工具。。编辑器
若是页面布局都是flex布局,还算方便,原有的布局不用太大修改,默认的 div 元素须要加上函数
flex-grow: 1;
flex-direction: column;
复制代码
这样才是相似 block,占据整行,由上至下。
另外,定位元素最好设定高度,否则它的高度极可能占据屏幕的100%。
手机上有个bug,通常状况下,咱们会定义某个元素块一些样式,而后使用 .active 再去定义一些新的样式,已到达在点击或者某个操做修改类而更新UI,例如:
<div class="test-div">
<h1>你好</h1>
</div>
<div class="test-div active">
<h1>你好</h1>
</div>
<style> <!--正常的状况--> .test-div { background-color: red; } .test-div h1 { font-size: 12px; color: #000; } <!--active的状况--> .test-div.active { background-color: gray; } .test-div.active h1 { font-size: 20px; color: red; } </style>
复制代码
咱们通常会这样写,给元素加个 active 来切换UI。
可是快应用很神奇的地方在于,切换的UI的类名,只有当前元素的规则生效,其后代元素的不生效。
也就是,在正常的H5中,给 div.test-div 加一个 active ,它会改变背景色,而后它的子元素 h1 会改变字体大小和颜色。
快应用中,给 div.test-div 加一个 active ,它会改变背景色,而后...就没有而后了,h1 的样式不生效。。。
因此,在不知道何时会修复的状况下,上面的例子建议改为这样(只写一下 active 的 css):
<div class="test-div">
<h1>你好</h1>
</div>
<div class="test-div div-active">
<h1 class="h1-active">你好</h1>
</div>
<style> <!--active的状况--> .test-div.div-active { background-color: gray; } .test-div h1.h1-active { font-size: 20px; color: red; } </style>
复制代码
JS部分,普通方法大多能够共用,可是对于页面、结构的部分快应用和 vue 仍是有一些不一样的地方,因此使用一些 hack 方法来模拟 vue 的开发结构,最大适应本身的编程习惯。
由于快应用的生命周期、方法都在同级,因此为了保持vue开发的习惯,对文件进行了分割,以下部分:
const BASE_URL = '/Common/img';
export default {
props: {
list: {
default: []
}
},
data() {
return {
iconXXX: BASE_URL + '/xxxxx.png'
};
}
};
复制代码
export default {
// 这个是挂载计算属性的方法,下一节会讲解
initComputed() {
let _this = this;
let computed = _this.computed();
for (let key of Object.keys(computed)) {
Object.defineProperty(_this, key, {
get() {
return computed[key].call(_this);
}
});
}
},
// 以 data 的形式以 function 定义
computed() {
return {
a() {
// code ...
},
b() {
// code ...
}
};
}
};
复制代码
export default {
onInit() {}
};
复制代码
export default {
funcA() {},
funcB() {}
};
复制代码
使用的话,就在 ux 文件中引入并拼接:
import dataMixin from './mixin/data';
import computedMixin from './mixin/computed';
import methodsMixin from './mixin/methods';
import lifeMixin from './mixin/life';
export default {
...dataMixin, // 数据
...computedMixin, // 计算属性
...methodsMixin, // 方法
...lifeMixin // 生命周期
};
复制代码
1030不支持计算属性,而 computed 是在1050版本才出的,如今尚未兼容,因此修改了一下写法。
快应用中,computed 写法:
<script> export default { data(){ return { a: 1, b: 2 } }, computed(){ return { // 似 data 的写法 data1(){ // some code... } } }, // 计算属性初始化 initComputed() { let _this = this; let computed = _this.computed(); for (let key of Object.keys(computed)) { Object.defineProperty(_this, key, { get() { return computed[key].call(_this); } }); } }, onInit(){ this.initComputed(); // 执行计算属性初始化 } } </script>
复制代码
子元素 $emit ,外层监听,不能用驼峰式,而且返回的在对象的 detail 中。
针对上面的状况,写了一个辅助方法来引入。
// proxyEvent.js
export default {
proxyEmit(f = '', p = {}) {
if (f) {
this.$emit('proxyOn', { f, p });
}
},
proxyOn({ detail: { f, p } } = {}) {
if (this[f] && typeof this[f] === 'function') {
this[f](p);
}
}
};
复制代码
在 .ux 文件中之内挂在到主对象中。
import proxyEvent from './proxyEvent';
export default {
...proxyEvent
}
复制代码
在子组件中,全部使用 this.$emit 的方法地方修改为 this.proxyEmit,第一个参数为要触发的事件名称,也为要触发的父元素函数。 在父组件中,组件上只须要 @proxy-on="proxyOn" 便可。
例子:
<template>
<div>
<text @click="proxyEmit('sayHelloEvent', { value: 'hello~' })">点击触发</text>
</div>
</template>
<script> import proxyEvent from './proxyEvent'; export default { ...proxyEvent } </script>
复制代码
<template>
<sayHello @proxy-on="proxyOn"></sayHello>
</template>
<import name="sayHello" src="./sayHello.ux"></import>
<script> import proxyEvent from './proxyEvent'; export default { ...proxyEvent, sayHelloEvent(params){ console.log(params); // { value: 'hello~' } } } </script>
复制代码
在 vue 中能够用子组件是这样引入和获取的:
<template>
<div>
<child ref="child-component"></child>
</div>
</template>
<script> import child from './components/child.vue'; export default { components: { child }, created(){ console.log(this.$refs['child-component']); // child component } } </script>
复制代码
在快应用中能够用子组件是这样引入和获取的:
<template>
<div>
<child id="child-component"></child>
</div>
</template>
<import name="child" src="./components/child.ux"></import>
<script> export default { onInit(){ console.log(this.$child('child-component')); // child component } } </script>
复制代码