HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

uniapp中 自身调用自身 递归调用自己

<view class="">  
    <template     v-for="(secondPl,index) in secondComments">  
        <view class="leavelMessageRember-item1"   >  
            <view class="contentName">  
                {{secondPl.userName}}&nbsp;回复&nbsp;@{{parentName}}  
            </view>  
            <view class="content">  
                {{secondPl.message}}   
            </view>   
        </view>  
        <view class=""    @click="shuouhui" v-if="!secondPl.children" style="padding-left: 5px;color: #aaaaaa;background-color: aliceblue;font-size: 12px;">  
            收回  
        </view>  
        <morePL  
            @Tback="shuouhui"     
            :parentName='secondPl.userName'  
            :secondComments="secondPl.children"  
        ></morePL>  
    </template>  
</view>
继续阅读 »
<view class="">  
    <template     v-for="(secondPl,index) in secondComments">  
        <view class="leavelMessageRember-item1"   >  
            <view class="contentName">  
                {{secondPl.userName}}&nbsp;回复&nbsp;@{{parentName}}  
            </view>  
            <view class="content">  
                {{secondPl.message}}   
            </view>   
        </view>  
        <view class=""    @click="shuouhui" v-if="!secondPl.children" style="padding-left: 5px;color: #aaaaaa;background-color: aliceblue;font-size: 12px;">  
            收回  
        </view>  
        <morePL  
            @Tback="shuouhui"     
            :parentName='secondPl.userName'  
            :secondComments="secondPl.children"  
        ></morePL>  
    </template>  
</view>
收起阅读 »

浏览器信息检测小工具

浏览器

https://passer-by.com/browser/

进入上方网页可以检测浏览器信息

https://passer-by.com/browser/

进入上方网页可以检测浏览器信息

HBuliderX编译器本身的BUG在哪里提交??

bug反馈

我最近使用HBuliderX写uniapp小程序的css样式时发现一个比较严重的BUG,在折叠的代码下面继续写新的同级的样式的时候再次展开前面的那个折叠的样式时,会自动将刚刚写好的css样式加入到之前折叠的那个样式当中去,语法是scss。请官方大大能够修复一下或者给个答复,这是编译器特性吗,还是什么。

继续阅读 »

我最近使用HBuliderX写uniapp小程序的css样式时发现一个比较严重的BUG,在折叠的代码下面继续写新的同级的样式的时候再次展开前面的那个折叠的样式时,会自动将刚刚写好的css样式加入到之前折叠的那个样式当中去,语法是scss。请官方大大能够修复一下或者给个答复,这是编译器特性吗,还是什么。

收起阅读 »

2025社区交流小区校园圈子模板

微信小程序

https://ext.dcloud.net.cn/plugin?id=21634

https://ext.dcloud.net.cn/plugin?id=21634

midButton按钮onTabBarMidButtonTap点击事件弹出弹窗

在使用midButton做凸起按钮的时候,在App.vue里使用uni.onTabBarMidButtonTap来监听点击事件,网上都是点击后执行的跳转页面,我想点击后出现弹窗。
把弹窗组件写在App.vue里,代码
<template>
<view>
<customDialog />
<router-view></router-view>
</view>
</template>
不使用router-view页面就是空的,使用router-view下方的tabBar就没了。
应该怎么处理呢?

继续阅读 »

在使用midButton做凸起按钮的时候,在App.vue里使用uni.onTabBarMidButtonTap来监听点击事件,网上都是点击后执行的跳转页面,我想点击后出现弹窗。
把弹窗组件写在App.vue里,代码
<template>
<view>
<customDialog />
<router-view></router-view>
</view>
</template>
不使用router-view页面就是空的,使用router-view下方的tabBar就没了。
应该怎么处理呢?

收起阅读 »

APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了

APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了

继续阅读 »

APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了
APP 什么时候支持requestMerchantTransfer 微信确认收款。 现在APP 卡主了

收起阅读 »

【记录】vue2--->vue3组合式

vue3

1、this.$nextTick,替换方案如下:

import { nextTick} from "vue";  
nextTick(function() {})

2、uni.createSelectorQuery().in(this),其他相似api需要this应该也是一样的,替换方案如下:

uniapp文档示例(选择组合式api):https://uniapp.dcloud.net.cn/api/ui/nodes-info.html#selectorquery-in

import { getCurrentInstance } from "vue";  
const instance = getCurrentInstance();  
const that = instance.proxy;  
const query = uni.createSelectorQuery().in(that);

评论区”朱小“的发问,加.in(that)和不加的区别。以下是查找到的内容,仅供参考:

3、子组件使用this.$parent,替换方案:props、provide/inject、emits或事件总线

4、子组件使用this.$root.$on("hook:onShow", () => {...相关逻辑})监听父组件onShow生命周期,替换方案如下:

import { onShow } from "@dcloudio/uni-app";  
onShow(() => {  
    ...相关逻辑  
})
继续阅读 »

1、this.$nextTick,替换方案如下:

import { nextTick} from "vue";  
nextTick(function() {})

2、uni.createSelectorQuery().in(this),其他相似api需要this应该也是一样的,替换方案如下:

uniapp文档示例(选择组合式api):https://uniapp.dcloud.net.cn/api/ui/nodes-info.html#selectorquery-in

import { getCurrentInstance } from "vue";  
const instance = getCurrentInstance();  
const that = instance.proxy;  
const query = uni.createSelectorQuery().in(that);

评论区”朱小“的发问,加.in(that)和不加的区别。以下是查找到的内容,仅供参考:

3、子组件使用this.$parent,替换方案:props、provide/inject、emits或事件总线

4、子组件使用this.$root.$on("hook:onShow", () => {...相关逻辑})监听父组件onShow生命周期,替换方案如下:

import { onShow } from "@dcloudio/uni-app";  
onShow(() => {  
    ...相关逻辑  
})
收起阅读 »

小程序版本

<template>
<view class="tagBall">
<view class="tag" v-for="(item, index) in texts" :key="index" :style="[getTagStyle(index)]">
<view>{{item.userName}}</view>
<view class="dot"></view>
</view>
</view>
</template>
<script>
export default {
props: {
speed: {
type: Number,
default: 0.5
},
texts: {
type: Array,
default: () => {
return [];
}
}
},
data() {
return {
tagEle: [],
RADIUS: 150,
fallLength: 240,
angleX: Math.PI / 400,
angleY: Math.PI / 400,
tags: [],
liviews: [],
CX: 0,
CY: 0,
timer: null,
clickX: 0,
clickY: 0
};
},
computed: {
getTagStyle() {
return (index) => {
const style = this.liviews[index] || {};
return {
fontSize: ${style.fontSize},
opacity: style.opacity,
transition: style.transition,
filter: style.filter,
zIndex: style.zIndex,
transformStyle: style.transformStyle,
left: ${style.left},
top: ${style.top},
perspective: '20000rpx',
transition: 'all linear 0.1s',
transform: style.transform,
};
};
}
},
destroyed() {
this.clearTimer();
},
mounted() {
this.initTags();
},
methods: {
clearTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
getTags(option) {
this.tagEle = option.tagEle;
this.CX = option.CX;
this.CY = option.CY;
this.init();
},
rotateX() {
const cos = Math.cos(this.angleX this.speed);
const sin = Math.sin(this.angleX
this.speed);
for (let i = 0; i < this.tags.length; i++) {
let t = this.tags[i];
const y1 = t.y cos + t.z sin;
const z1 = t.z cos - t.y sin;
t.y = y1;
t.z = z1;
}
},
rotateY() {
const cos = Math.cos(this.angleY this.speed);
const sin = Math.sin(this.angleY
this.speed);
for (let i = 0; i < this.tags.length; i++) {
let t = this.tags[i];
const x1 = t.x cos - t.z sin;
const z1 = t.z cos + t.x sin;
t.x = x1;
t.z = z1;
}
},
init() {
this.tags = [];
this.liviews = [];
for (let i = 0; i < this.tagEle.length; i++) {
const k = (2 (i + 1) - 1) / this.tagEle.length - 1;
const a = Math.acos(k);
const b = a
Math.sqrt(this.tagEle.length Math.PI);
const x = this.RADIUS
Math.sin(a) Math.cos(b);
const y = this.RADIUS
Math.sin(a) Math.sin(b);
const z = this.RADIUS
Math.cos(a);
const t = this.tag(this.tagEle[i], x / 2, y / 2, z / 2);
this.tags.push(t);
}
this.animate(this.tags);
},
tag(ele, x, y, z) {
return {
ele,
x,
y,
z
};
},
move(t, i) {
const scale = this.fallLength / (this.fallLength - t.z 1.3);
const alpha = (t.z + this.RADIUS) / (2
this.RADIUS);
this.liviews.push({
fontSize: 5 scale + 'px',
opacity: alpha + 0.5,
transition: 'all linear 0.5s',
filter: 'alpha(opacity=' + (alpha + 0.5)
100 + ')',
zIndex: parseInt(scale 100),
transformStyle: 'preserve-3d',
left: t.x + this.CX - t.ele.offsetWidth / 2 + 'px',
top: t.y + this.CY - t.ele.offsetHeight / 2 + 'px',
perspective: '2000rpx',
transformStyle: 'preserve-3d',
transform: scale(${alpha+0.5}),
});
},
animate(x) {
this.clearTimer();
this.timer = setInterval(() => {
this.rotateX();
this.rotateY();
this.liviews = [];
for (let i = 0; i < x.length; i++) {
this.move(x[i], i);
}
}, 25)
},
touchstartscene(e) {
this.clickX = e.touches[0].clientX;
this.clickY = e.touches[0].clientY;
this.clearTimer();
},
touchendscene() {
this.animate(this.tags);
this.clearTimer();
},
touchmovescene(e) {
const fx = this.getDirection(this.clickX, this.clickY, e.touches[0].clientX, e.touches[0].clientY);
let x = this.clickX - e.touches[0].clientX - this.CX;
let y = this.clickY - e.touches[0].clientY - this.CY;
if (fx === 1) {
x = e.touches[0].clientX - this.clickX;
y = e.touches[0].clientY - this.clickY - this.CY;
} else if (fx === 2) {
x = e.touches[0].clientX - this.clickX;
y = e.touches[0].clientY + this.CY;
} else if (fx === 3) {
x = this.clickX + e.touches[0].clientX + this.CX;
y = this.clickY - e.touches[0].clientY - this.CY;
} else {
x = this.clickX - e.touches[0].clientX - this.CX;
y = this.clickY - e.touches[0].clientY - this.CY;
}
this.angleY = x
0.0001;
this.angleX = y 0.0001;
this.rotateX();
this.rotateY();
this.liviews = [];
for (let i = 0; i < this.tags.length; i++) {
this.move(this.tags[i], i);
}
},
getDirection(startx, starty, endx, endy) {
const angx = endx - startx;
const angy = endy - starty;
let result = 0;
if (Math.abs(angx) < 2 && Math.abs(angy) < 2) {
return result;
}
const angle = Math.atan2(angy, angx)
180 / Math.PI;
if (angle >= -135 && angle <= -45) {
result = 1;
} else if (angle > 45 && angle < 135) {
result = 2;
} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
result = 3;
} else if (angle >= -45 && angle <= 45) {
result = 4;
}
return result;
},
initTags() {
let tagEles = [];
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.selectAll('.tag').boundingClientRect(rects => {
tagEles = rects.map(rect => ({
offsetWidth: rect.width,
offsetHeight: rect.height
}));
}).exec();
query.select('.tagBall').boundingClientRect(rect => {
const CX = rect.width / 2;
const CY = rect.height / 2;
this.getTags({
tagEle: tagEles,
CX,
CY
});
}).exec();
});
}
}
};
</script>
<style scoped>
.tagBall {
height: 214rpx;
position: relative;
perspective: 2000rpx;
transform-style: preserve-3d;
left: 0;
top: 0;
transition: all linear 0.1s;
margin-left: 40rpx;
}

.tag {  
    width: 150rpx;  
    position: absolute;  
    font-weight: 500;  
    font-size: 12rpx;  
    color: #000000;  
    display: flex;  
    flex-direction: column;  
    align-items: center;  
    transition: all ease-in-out 0.3s;  
}  

.dot {  
    width: 16rpx;  
    height: 16rpx;  
    background: #FCC928;  
    border-radius: 50%;  
    margin-top: 10rpx;  
}  

</style>

继续阅读 »

<template>
<view class="tagBall">
<view class="tag" v-for="(item, index) in texts" :key="index" :style="[getTagStyle(index)]">
<view>{{item.userName}}</view>
<view class="dot"></view>
</view>
</view>
</template>
<script>
export default {
props: {
speed: {
type: Number,
default: 0.5
},
texts: {
type: Array,
default: () => {
return [];
}
}
},
data() {
return {
tagEle: [],
RADIUS: 150,
fallLength: 240,
angleX: Math.PI / 400,
angleY: Math.PI / 400,
tags: [],
liviews: [],
CX: 0,
CY: 0,
timer: null,
clickX: 0,
clickY: 0
};
},
computed: {
getTagStyle() {
return (index) => {
const style = this.liviews[index] || {};
return {
fontSize: ${style.fontSize},
opacity: style.opacity,
transition: style.transition,
filter: style.filter,
zIndex: style.zIndex,
transformStyle: style.transformStyle,
left: ${style.left},
top: ${style.top},
perspective: '20000rpx',
transition: 'all linear 0.1s',
transform: style.transform,
};
};
}
},
destroyed() {
this.clearTimer();
},
mounted() {
this.initTags();
},
methods: {
clearTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
getTags(option) {
this.tagEle = option.tagEle;
this.CX = option.CX;
this.CY = option.CY;
this.init();
},
rotateX() {
const cos = Math.cos(this.angleX this.speed);
const sin = Math.sin(this.angleX
this.speed);
for (let i = 0; i < this.tags.length; i++) {
let t = this.tags[i];
const y1 = t.y cos + t.z sin;
const z1 = t.z cos - t.y sin;
t.y = y1;
t.z = z1;
}
},
rotateY() {
const cos = Math.cos(this.angleY this.speed);
const sin = Math.sin(this.angleY
this.speed);
for (let i = 0; i < this.tags.length; i++) {
let t = this.tags[i];
const x1 = t.x cos - t.z sin;
const z1 = t.z cos + t.x sin;
t.x = x1;
t.z = z1;
}
},
init() {
this.tags = [];
this.liviews = [];
for (let i = 0; i < this.tagEle.length; i++) {
const k = (2 (i + 1) - 1) / this.tagEle.length - 1;
const a = Math.acos(k);
const b = a
Math.sqrt(this.tagEle.length Math.PI);
const x = this.RADIUS
Math.sin(a) Math.cos(b);
const y = this.RADIUS
Math.sin(a) Math.sin(b);
const z = this.RADIUS
Math.cos(a);
const t = this.tag(this.tagEle[i], x / 2, y / 2, z / 2);
this.tags.push(t);
}
this.animate(this.tags);
},
tag(ele, x, y, z) {
return {
ele,
x,
y,
z
};
},
move(t, i) {
const scale = this.fallLength / (this.fallLength - t.z 1.3);
const alpha = (t.z + this.RADIUS) / (2
this.RADIUS);
this.liviews.push({
fontSize: 5 scale + 'px',
opacity: alpha + 0.5,
transition: 'all linear 0.5s',
filter: 'alpha(opacity=' + (alpha + 0.5)
100 + ')',
zIndex: parseInt(scale 100),
transformStyle: 'preserve-3d',
left: t.x + this.CX - t.ele.offsetWidth / 2 + 'px',
top: t.y + this.CY - t.ele.offsetHeight / 2 + 'px',
perspective: '2000rpx',
transformStyle: 'preserve-3d',
transform: scale(${alpha+0.5}),
});
},
animate(x) {
this.clearTimer();
this.timer = setInterval(() => {
this.rotateX();
this.rotateY();
this.liviews = [];
for (let i = 0; i < x.length; i++) {
this.move(x[i], i);
}
}, 25)
},
touchstartscene(e) {
this.clickX = e.touches[0].clientX;
this.clickY = e.touches[0].clientY;
this.clearTimer();
},
touchendscene() {
this.animate(this.tags);
this.clearTimer();
},
touchmovescene(e) {
const fx = this.getDirection(this.clickX, this.clickY, e.touches[0].clientX, e.touches[0].clientY);
let x = this.clickX - e.touches[0].clientX - this.CX;
let y = this.clickY - e.touches[0].clientY - this.CY;
if (fx === 1) {
x = e.touches[0].clientX - this.clickX;
y = e.touches[0].clientY - this.clickY - this.CY;
} else if (fx === 2) {
x = e.touches[0].clientX - this.clickX;
y = e.touches[0].clientY + this.CY;
} else if (fx === 3) {
x = this.clickX + e.touches[0].clientX + this.CX;
y = this.clickY - e.touches[0].clientY - this.CY;
} else {
x = this.clickX - e.touches[0].clientX - this.CX;
y = this.clickY - e.touches[0].clientY - this.CY;
}
this.angleY = x
0.0001;
this.angleX = y 0.0001;
this.rotateX();
this.rotateY();
this.liviews = [];
for (let i = 0; i < this.tags.length; i++) {
this.move(this.tags[i], i);
}
},
getDirection(startx, starty, endx, endy) {
const angx = endx - startx;
const angy = endy - starty;
let result = 0;
if (Math.abs(angx) < 2 && Math.abs(angy) < 2) {
return result;
}
const angle = Math.atan2(angy, angx)
180 / Math.PI;
if (angle >= -135 && angle <= -45) {
result = 1;
} else if (angle > 45 && angle < 135) {
result = 2;
} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
result = 3;
} else if (angle >= -45 && angle <= 45) {
result = 4;
}
return result;
},
initTags() {
let tagEles = [];
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.selectAll('.tag').boundingClientRect(rects => {
tagEles = rects.map(rect => ({
offsetWidth: rect.width,
offsetHeight: rect.height
}));
}).exec();
query.select('.tagBall').boundingClientRect(rect => {
const CX = rect.width / 2;
const CY = rect.height / 2;
this.getTags({
tagEle: tagEles,
CX,
CY
});
}).exec();
});
}
}
};
</script>
<style scoped>
.tagBall {
height: 214rpx;
position: relative;
perspective: 2000rpx;
transform-style: preserve-3d;
left: 0;
top: 0;
transition: all linear 0.1s;
margin-left: 40rpx;
}

.tag {  
    width: 150rpx;  
    position: absolute;  
    font-weight: 500;  
    font-size: 12rpx;  
    color: #000000;  
    display: flex;  
    flex-direction: column;  
    align-items: center;  
    transition: all ease-in-out 0.3s;  
}  

.dot {  
    width: 16rpx;  
    height: 16rpx;  
    background: #FCC928;  
    border-radius: 50%;  
    margin-top: 10rpx;  
}  

</style>

收起阅读 »

【TuiPlus】简洁高效 uniapp x UI组件库重磅发布,原生uts插件加持,保障流畅体验,助力快速开发,打造优质原生应用。

原生 图表 UI uts

项目介绍

> TuiPlus UI组件库 —— 全面兼容最新设计理念。本次重构不仅着眼于功能的提升,更深入探索用户体验的无限可能。我们的组件库致力于打造一个既全面又精致的UI设计平台,强调设计的精致度和扩展性,始终将用户体验放在首位。在细节的打磨上,我们精益求精,自豪地呈现——TuiPlus UI组件库。

> 创新与差异 —— 新版增加了UTS版图表,裁剪等众多组件,我们的专注点在于提供丰富且独特的组件。每一款组件都是经过匠心独运的设计和优化,确保性能卓越。特别是我们的UTS图表组件,采用高性能的canvas技术,实现了无需webview嵌套的纯canvas绘制,带来了行业领先的流畅度和响应速度。TuiPlus UI组件库全面支持iOS、Android以及Web/H5三端,无缝适配多种屏幕尺寸和形态,包括长屏、宽屏、PC、折叠屏和横屏,满足不同场景下的多样化需求。

!视频

TuiPlus文档地址:https://life.yundie.xyz/t-uvue-ui/docs/index.html

功能特性快速了解

TuiPlus扫码下载体验

web在线体验

Image

安卓下载链接

Image

继续阅读 »

项目介绍

> TuiPlus UI组件库 —— 全面兼容最新设计理念。本次重构不仅着眼于功能的提升,更深入探索用户体验的无限可能。我们的组件库致力于打造一个既全面又精致的UI设计平台,强调设计的精致度和扩展性,始终将用户体验放在首位。在细节的打磨上,我们精益求精,自豪地呈现——TuiPlus UI组件库。

> 创新与差异 —— 新版增加了UTS版图表,裁剪等众多组件,我们的专注点在于提供丰富且独特的组件。每一款组件都是经过匠心独运的设计和优化,确保性能卓越。特别是我们的UTS图表组件,采用高性能的canvas技术,实现了无需webview嵌套的纯canvas绘制,带来了行业领先的流畅度和响应速度。TuiPlus UI组件库全面支持iOS、Android以及Web/H5三端,无缝适配多种屏幕尺寸和形态,包括长屏、宽屏、PC、折叠屏和横屏,满足不同场景下的多样化需求。

!视频

TuiPlus文档地址:https://life.yundie.xyz/t-uvue-ui/docs/index.html

功能特性快速了解

TuiPlus扫码下载体验

web在线体验

Image

安卓下载链接

Image

收起阅读 »

华为外包前端招聘

外包

岗位职责:
1、负责WEB,PC,移动端(iOS、Android)等前端js框架设计及开发、发布和维护;
2、根据产品需求,分析并做出Web 3D的页面前端结构解决方案以及与后台交互整体架构解决方案;
3、与设计、后台开发人员保持良好沟通,能快速理解、消化各方需求,并落实为具体的开发工作;
4、优化代码,应用前沿技术,不断提高页面性能和用户体验。
任职要求:
1.二本及以上学历;
2、会使用WebGL及其框架three.js、vue.js 等前端技术开发3D页面demo;
3、一年以上前端开发工作经验,代码编写规范,编程基础扎实,熟练掌握openGL、osg、ogre开发且有WebGL经验亦可;
4、精通Web前端技术,包括HTML5/CSS/Javascript等,对性能优化、解决多浏览器兼容性问题有经验;对移动设备前端开发有经验;
5、熟悉w3c标准,对表现与数据分离、web语义化等有深刻理解;
6、自动构建工具(gulp或者grunt)的基本运用;
7、熟悉Angular4以上和Node.js,理解前端MVC逻辑,对路由、模块化和依赖注入有一定的掌握;
8、熟悉业界常见的开源组件,有开源项目开发经验者优先。
待遇环境
薪资:11k-28k。实际多少依据个人能力。
弹性工作制,上下班打卡。
园区健身房、食堂等,晚饭补贴,打车补贴等。

网申通道

继续阅读 »

岗位职责:
1、负责WEB,PC,移动端(iOS、Android)等前端js框架设计及开发、发布和维护;
2、根据产品需求,分析并做出Web 3D的页面前端结构解决方案以及与后台交互整体架构解决方案;
3、与设计、后台开发人员保持良好沟通,能快速理解、消化各方需求,并落实为具体的开发工作;
4、优化代码,应用前沿技术,不断提高页面性能和用户体验。
任职要求:
1.二本及以上学历;
2、会使用WebGL及其框架three.js、vue.js 等前端技术开发3D页面demo;
3、一年以上前端开发工作经验,代码编写规范,编程基础扎实,熟练掌握openGL、osg、ogre开发且有WebGL经验亦可;
4、精通Web前端技术,包括HTML5/CSS/Javascript等,对性能优化、解决多浏览器兼容性问题有经验;对移动设备前端开发有经验;
5、熟悉w3c标准,对表现与数据分离、web语义化等有深刻理解;
6、自动构建工具(gulp或者grunt)的基本运用;
7、熟悉Angular4以上和Node.js,理解前端MVC逻辑,对路由、模块化和依赖注入有一定的掌握;
8、熟悉业界常见的开源组件,有开源项目开发经验者优先。
待遇环境
薪资:11k-28k。实际多少依据个人能力。
弹性工作制,上下班打卡。
园区健身房、食堂等,晚饭补贴,打车补贴等。

网申通道

收起阅读 »

【一个好用的css】pointer-events;当前元素可不可以被点击,实现穿透点击,穿透层级高的视图,点击层级低的视图

点击事件 css样式 css

官方文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events

pointer-events: auto; 与pointer-events属性未指定时的表现效果相同,对于 SVG 内容,该值与visiblePainted效果相同
pointer-events: none; 元素永远不会成为鼠标事件的target。但是,当其后代元素的pointer-events属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶段触发父元素的事件侦听器。

下面这个例子是不会触发onTap事件的

<template>  
    <view>  
        <view class="a"></view>  
        <view class="b" @tap="onTap"></view>  
    </view>  
</template>  

<script>  
export default {  
    methods: {  
        onTap() {  
            console.log("点击了b");  
        }  
    }  
}  
</script>  

<style lang="scss" scoped>  
    .a {  
        position: fixed;  
        top: 0;  
        left: 0;  
        right: 0;  
        height: 100vh;  
        z-index: 10;  
    }  
    .b {  
        width: 100px;  
        height: 100px;  
        background-color: aqua;  
    }  
</style>

下面这个例子会触发onTap事件的,在a的样式加上pointer-events: none;,b的样式加上pointer-events: auto;其他不变

<template>  
    <view>  
        <view class="a"></view>  
        <view class="b" @tap="onTap"></view>  
    </view>  
</template>  

<script>  
export default {  
    methods: {  
        onTap() {  
            console.log("点击了b");  
        }  
    }  
}  
</script>  

<style lang="scss" scoped>  
    .a {  
        position: fixed;  
        top: 0;  
        left: 0;  
        right: 0;  
        height: 100vh;  
        z-index: 10;  
        pointer-events: none;  
    }  
    .b {  
        width: 100px;  
        height: 100px;  
        background-color: aqua;  
        pointer-events: auto;  
    }  
</style>

↓↓↓ 各位大佬点点赞

继续阅读 »

官方文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events

pointer-events: auto; 与pointer-events属性未指定时的表现效果相同,对于 SVG 内容,该值与visiblePainted效果相同
pointer-events: none; 元素永远不会成为鼠标事件的target。但是,当其后代元素的pointer-events属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶段触发父元素的事件侦听器。

下面这个例子是不会触发onTap事件的

<template>  
    <view>  
        <view class="a"></view>  
        <view class="b" @tap="onTap"></view>  
    </view>  
</template>  

<script>  
export default {  
    methods: {  
        onTap() {  
            console.log("点击了b");  
        }  
    }  
}  
</script>  

<style lang="scss" scoped>  
    .a {  
        position: fixed;  
        top: 0;  
        left: 0;  
        right: 0;  
        height: 100vh;  
        z-index: 10;  
    }  
    .b {  
        width: 100px;  
        height: 100px;  
        background-color: aqua;  
    }  
</style>

下面这个例子会触发onTap事件的,在a的样式加上pointer-events: none;,b的样式加上pointer-events: auto;其他不变

<template>  
    <view>  
        <view class="a"></view>  
        <view class="b" @tap="onTap"></view>  
    </view>  
</template>  

<script>  
export default {  
    methods: {  
        onTap() {  
            console.log("点击了b");  
        }  
    }  
}  
</script>  

<style lang="scss" scoped>  
    .a {  
        position: fixed;  
        top: 0;  
        left: 0;  
        right: 0;  
        height: 100vh;  
        z-index: 10;  
        pointer-events: none;  
    }  
    .b {  
        width: 100px;  
        height: 100px;  
        background-color: aqua;  
        pointer-events: auto;  
    }  
</style>

↓↓↓ 各位大佬点点赞

收起阅读 »

vue3 + uniapp 可以直接开发鸿蒙啦!

uniapp

7 月 20 号,uniapp 官网上线了 uniapp 开发鸿蒙应用的文档,标志着 Vue3 + uniapp 开发鸿蒙应用时代的开启。

鸿蒙开发的支持与限制

鸿蒙开发仅支持 Vue3,不支持 Vue2 和 plus,
支持 nvue,nvue 编译到鸿蒙后非原生渲染。

开发环境要求

DevEco-Studio 5.0.3.400 以上 (DevEco-Studio 较大,达10G*)
鸿蒙系统版本 API 12 以上,HBuilderX-alpha-4.22 以上
Windows 系统使用模拟器需开启特定功能,且家庭版需升级。

配置鸿蒙离线 SDK 及相关操作
包括下载、解压、在 DevEco-Studio 中打开、启动模拟器或连接真机、配置签名等步骤。
启动鸿蒙模拟器
分为三步,包括下载、解压、等待 Sync 结束等,还涉及开发者申请。

<​当前缺个机会,缺份工作,想靠大厂外包过渡下的兄弟姐妹们,可以一起来共事,前、后端/测试年前捞人,待遇给的还可以,感兴趣可以来>

安装完模拟器后,点击启动按钮启动模拟器

启动模拟器成功后,如果提示需要先签名,则进行配置签名

连接鸿蒙真机

注意:真机需要鸿蒙系统版本 API 12 以上

打开鸿蒙手机开发者模式,开启USB调试,通过USB线连接电脑,在此处选择你的手机名称,再启动项目即可,如果提示需要先签名,则进行配置签名

配置 HBuilderX 吊起 DevEco-Studio:在 HBuilderX 中进行相关设置,填写 DevEco-Studio 启动路径。
创建 uni-app 工程:在 BuilderX 新建空白项目,选 vue3,在 manifest.json 文件中配置鸿蒙离线 SDK 路径。

配置签名

注意:配置签名需要先启动模拟器或连接真机后才能配置

配置 HBuilderX settings.json
需在 HBuilderX 中进行特定的设置操作

打开HBuilderX,点击上方菜单 - 工具 - 设置,在出现的弹窗右侧窗体新增如下配置
注意:值填你自己的 DevEco-Studio 启动路径

json 代码解读复制代码"harmony.devTools.path" : "D:/Huawei/DevEco Studio"

使用 uts 调用鸿蒙原生 API, 第三方API
调用鸿蒙原生 API
uni-app在Android和iOS平台,支持uts插件和App原生语言插件。目前App原生语言插件已经停止维护。uts插件是主推的扩展方式。
鸿蒙系统有很多原生API,可以通过uts插件方式接入,被uni-app调用。

uts插件介绍
uts插件鸿蒙开发专题

调用第三方 API
新增于 HBuilderX 4.25,有特定的使用流程和限制。
鸿蒙的包用法和npm包差不多,在鸿蒙项目里面用ohpm安装三方库后,在 /uni_modules/uts插件名/utssdk/app-harmony/index.uts 内即可直接 import
注意:只能在满足uts插件 /uni_modules//utssdk/app-harmony/.uts 的文件下使用,无法直接在项目的pages中使用
具体使用流程:在项目的pages引入uts插件,uts插件内再引入鸿蒙第三方库调用
发布鸿蒙应用
鸿蒙官方文档提供了如何发布鸿蒙应用,详见 文档

注意事项

移植已有的 uni-app 项目源码时,如有其他 npm 依赖,请自行安装
现阶段条件编译仅 APP-HARMONY、APP 可以命中鸿蒙平台
每次HBuilderX改动源码后,DevEco-Studio 内需要点重新运行才能生效
如果模拟器白屏了,尝试重启软件 DevEco-Studio,再重启项目
如果模拟器无法连接了,尝试重启电脑
在HBuilderX里运行后,需要再去鸿蒙 DevEco Studio里运行
在HBuilderX里修改代码后,需要去鸿蒙 DevEco Studio里重新运行
如果有多个uni-app项目要编译到鸿蒙,那么鸿蒙离线sdk需要放置多份,每个uni-app的manifest中配置不同的离线sdk地址,否则会冲突,鸿蒙设备上目前没有基座概念

总结
这样我们就有了一个初始的鸿蒙项目,并且可以在鸿蒙模拟器上运行。关于更多 uniapp 开发鸿蒙的 API,大家可以直接参考 uniapp 官方文档

——转载自作者:码上解忧铺

继续阅读 »

7 月 20 号,uniapp 官网上线了 uniapp 开发鸿蒙应用的文档,标志着 Vue3 + uniapp 开发鸿蒙应用时代的开启。

鸿蒙开发的支持与限制

鸿蒙开发仅支持 Vue3,不支持 Vue2 和 plus,
支持 nvue,nvue 编译到鸿蒙后非原生渲染。

开发环境要求

DevEco-Studio 5.0.3.400 以上 (DevEco-Studio 较大,达10G*)
鸿蒙系统版本 API 12 以上,HBuilderX-alpha-4.22 以上
Windows 系统使用模拟器需开启特定功能,且家庭版需升级。

配置鸿蒙离线 SDK 及相关操作
包括下载、解压、在 DevEco-Studio 中打开、启动模拟器或连接真机、配置签名等步骤。
启动鸿蒙模拟器
分为三步,包括下载、解压、等待 Sync 结束等,还涉及开发者申请。

<​当前缺个机会,缺份工作,想靠大厂外包过渡下的兄弟姐妹们,可以一起来共事,前、后端/测试年前捞人,待遇给的还可以,感兴趣可以来>

安装完模拟器后,点击启动按钮启动模拟器

启动模拟器成功后,如果提示需要先签名,则进行配置签名

连接鸿蒙真机

注意:真机需要鸿蒙系统版本 API 12 以上

打开鸿蒙手机开发者模式,开启USB调试,通过USB线连接电脑,在此处选择你的手机名称,再启动项目即可,如果提示需要先签名,则进行配置签名

配置 HBuilderX 吊起 DevEco-Studio:在 HBuilderX 中进行相关设置,填写 DevEco-Studio 启动路径。
创建 uni-app 工程:在 BuilderX 新建空白项目,选 vue3,在 manifest.json 文件中配置鸿蒙离线 SDK 路径。

配置签名

注意:配置签名需要先启动模拟器或连接真机后才能配置

配置 HBuilderX settings.json
需在 HBuilderX 中进行特定的设置操作

打开HBuilderX,点击上方菜单 - 工具 - 设置,在出现的弹窗右侧窗体新增如下配置
注意:值填你自己的 DevEco-Studio 启动路径

json 代码解读复制代码"harmony.devTools.path" : "D:/Huawei/DevEco Studio"

使用 uts 调用鸿蒙原生 API, 第三方API
调用鸿蒙原生 API
uni-app在Android和iOS平台,支持uts插件和App原生语言插件。目前App原生语言插件已经停止维护。uts插件是主推的扩展方式。
鸿蒙系统有很多原生API,可以通过uts插件方式接入,被uni-app调用。

uts插件介绍
uts插件鸿蒙开发专题

调用第三方 API
新增于 HBuilderX 4.25,有特定的使用流程和限制。
鸿蒙的包用法和npm包差不多,在鸿蒙项目里面用ohpm安装三方库后,在 /uni_modules/uts插件名/utssdk/app-harmony/index.uts 内即可直接 import
注意:只能在满足uts插件 /uni_modules//utssdk/app-harmony/.uts 的文件下使用,无法直接在项目的pages中使用
具体使用流程:在项目的pages引入uts插件,uts插件内再引入鸿蒙第三方库调用
发布鸿蒙应用
鸿蒙官方文档提供了如何发布鸿蒙应用,详见 文档

注意事项

移植已有的 uni-app 项目源码时,如有其他 npm 依赖,请自行安装
现阶段条件编译仅 APP-HARMONY、APP 可以命中鸿蒙平台
每次HBuilderX改动源码后,DevEco-Studio 内需要点重新运行才能生效
如果模拟器白屏了,尝试重启软件 DevEco-Studio,再重启项目
如果模拟器无法连接了,尝试重启电脑
在HBuilderX里运行后,需要再去鸿蒙 DevEco Studio里运行
在HBuilderX里修改代码后,需要去鸿蒙 DevEco Studio里重新运行
如果有多个uni-app项目要编译到鸿蒙,那么鸿蒙离线sdk需要放置多份,每个uni-app的manifest中配置不同的离线sdk地址,否则会冲突,鸿蒙设备上目前没有基座概念

总结
这样我们就有了一个初始的鸿蒙项目,并且可以在鸿蒙模拟器上运行。关于更多 uniapp 开发鸿蒙的 API,大家可以直接参考 uniapp 官方文档

——转载自作者:码上解忧铺

收起阅读 »