
风水算命源码|风水起名源码|算命php源码开发搭建
易经是世界上已知最古老的文件之一,其文字记载可以追溯到3000年前。现在互联网发达,很多年轻人更喜欢借助网络,所以我们设计了风水算命源码来满足更多年轻人的需求,通过提供洞察性的指导,准确回答有关生活、爱情、商业、健康、自我实现和个人问题的问题。
风水算命源码及演示:m.appwin.top
package.json
```javascript
{
"name": "react-tarot",
"version": "0.1.0",
"private": true,
"devDependencies": {
"prettier": "^1.5.3",
"react-scripts": "1.0.10",
"tachyons": "^4.7.4"
},
"dependencies": {
"flow-bin": "^0.51.0",
"gh-pages": "^1.0.0",
"map.prototype.tojson": "^0.1.3",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.5",
"react-router-dom": "^4.1.2",
"redux": "^3.7.2",
"redux-localstorage": "^0.4.1",
"redux-logger": "^3.0.6",
"redux-observable": "^0.14.1",
"reselect": "^3.0.1",
"rxjs": "^5.4.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"flow": "flow",
"prettier": "./node_modules/.bin/prettier --single-quote --write 'src/*/.{js,jsx}'",
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
},
"homepage": "http://renvrant.github.io/tarot-me"
}
Footer
为问题添加注释
您可以编辑已保存读数的问题,其中有 255 个字符可用。例如:
[在空行后和方括号之间添加注释,详细说明所提问题的情况、结果或对阅读的进一步思考。]
分类你的阅读
给问题一个唯一的代码,例如#REL 用于关系问题,#FAM 用于家庭事务,#$$$ 用于财务问题,#CAR 用于职业问题,#PER 用于个人福祉,#HOM 用于有关所在位置的问题你活着...
此代码的工作方式与 Twitter 的“主题标签”相同。
然后,您可以在已保存的读数中搜索特定代码并获取所有内容,并且仅获取与其主题相关的问题。
源码操作指南
步骤1
在打开的屏幕中,在文本框中输入您的问题。
您无需输入问题。
把它写下来是可选的,但如果你以书面形式表述它,它有助于你专注于这个问题。
它将帮助您“在空中”获得您的主题。
它也有助于打印目的;当您将答案与问题一起打印在纸上时,您会更好地记住阅读内容。
当页面关闭时,问题就进入了网络空间。
当然,除非您将阅读内容保存在您的个人帐户中,但是很明显您将其写下来。
即使您不这样做,您仍然可以在已保存的阅读中编辑问题。
问题越详细,答案就越准确。
一个模糊的问题会引起一个模糊的答案。
第2步
现在您可以选择抽签或投掷硬币的方法之间进行选择。
虚拟硬币没有问题,但如果您坚持使用自己的真实金属硬币,您可以按下手动投掷硬币按钮并通过翻转来填写您的投掷结果硬币在屏幕上。
当你点击它们时硬币会翻转。
完成后,“读取”按钮对这两种方法的作用相同。
当您想恢复以前的阅读时,手动投币功能非常方便。
当你记住线条的图案时,你可以稍后再填写,然后再看答案。
无论哪种方式,如果您没有满意地输入您的问题,您可以简单地关闭窗口,更正问题并再次单击继续。
用手投掷三枚硬币,并通过操纵屏幕上的硬币填写结果。
头是阳 杨 (光),尾(或“写作”)是阴 阴 (暗)。
第一次单击硬币时,它会显示 yin 阴 (暗/尾巴)。 每进一步单击,您将在阴(暗/尾)和阳(亮/头)
之间切换 。 每次您投掷三个真实硬币时,请通过单击屏幕中的硬币来填写结果,直到它们与您的投掷相匹配。 您可以操作硬币,直到您按下读取按钮,该按钮将在您完成所有六行(= 18 个硬币)后出现。
步骤 3
每次您构建一条线时,无论是通过按下 虚拟投币按钮,还是选择手动投币按钮并填入三个硬币,都会从下向上一次构建一条六角线。
硬币的一面代表阴,另一面代表阳。
阴数为 2,阳数为 3。
一次投掷三枚硬币可以产生四种组合:
2阳,1阴(3+3+2)= 8
2 阴 1 阳 (2+2+3)= 7
3 阴 (2+2+2)= 6
3 阳 (3+3+3)= 9
如果阴或阳线中的任何一条是红色的,那条线就是一条变化的线,在你咨询的过程中会变成它的对立面。
第4步
要进行解释,请单击“阅读”按钮。
第 5 步
在下一个屏幕中,将出现Cast Hexagram选项卡。
用铸卦开始回答你的问题,经常解释你现在所处的情况,或者以前发生了什么。
第 6 步
单击更改行选项卡。
在您的咨询过程中,变化的线条会转变为它们的对立面。
多行变化时,解释有问题;如果这些线是矛盾的,选择哪一条?
在易经在线,我们已选择应用一套规则来确定作为对您问题的答案的一条变化的线路。最初选择了这条更改线,但您可以通过单击它。
更改行是您问题答案的一部分,但也可以通过单击任何非更改(黑色)行来读取它。
尽管这套规则既古老又普遍,但它只是处理这个微妙问题的众多方法之一。
把它当作一个指导方针,根本没有说服力。
以下规则适用于七种可能的换行数:
0.
没有换行。
只读施法卦。
1.
有一个换线。
咨询这条变化线。
2.
有两条换线。
如果两条线都是六(旧阴)或九(旧阳),则适用上线。
如果一个是六,另一个是九,则以六为准(*)。
3.
共有三个换行。
中间线很重要。
4.
有四个变化线。
阅读上面的非改变行。
5.
有五个变化线。
阅读唯一不变的行。
6.
所有的线路都在变化。
只有变形卦适用。
有两个例外:如果所有行都是六或所有行都是九,请同时阅读铸卦和变卦。
两行交替时,古阴胜古阳的规律的由来我们不得而知,但可能来自抽签法。
不同的卦线出现的机会取决于所使用的方法。
在易经网上我们用三币法,老阴的机率和老阳的机率是一样的,但是用蓍草法,老阴出现的机率是阴阳机的三倍。老杨。
可能是因为这个原因,老阴比老阳更“特殊”。
第 7 步
单击转换的十六进制选项卡。
变形卦描述了未来的情况,在线条改变之后,如果你遵循易经给出的建议。
在我们的例子中,易经所说的加速成长,当你不辞去现在的工作时,你一定会体验到。
(无论是在你现在的工作中,还是在你不辞职的任何其他情况下,《易经》都没有说。也许你无论如何都会被解雇,并在你自己的蒸汽下经历重生。)
如果没有换行,此卦等于铸卦。
第 8 步
单击“卦符号”选项卡以阅读组成铸卦的两个卦(基于文王)的解释。
卦由两个卦组成,一个在另一个之上。
仅显示铸卦的三卦符号。
三卦由三个阴阳线的任意组合组成。
易经是世界上已知最古老的文件之一,其文字记载可以追溯到3000年前。现在互联网发达,很多年轻人更喜欢借助网络,所以我们设计了风水算命源码来满足更多年轻人的需求,通过提供洞察性的指导,准确回答有关生活、爱情、商业、健康、自我实现和个人问题的问题。
风水算命源码及演示:m.appwin.top
package.json
```javascript
{
"name": "react-tarot",
"version": "0.1.0",
"private": true,
"devDependencies": {
"prettier": "^1.5.3",
"react-scripts": "1.0.10",
"tachyons": "^4.7.4"
},
"dependencies": {
"flow-bin": "^0.51.0",
"gh-pages": "^1.0.0",
"map.prototype.tojson": "^0.1.3",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.5",
"react-router-dom": "^4.1.2",
"redux": "^3.7.2",
"redux-localstorage": "^0.4.1",
"redux-logger": "^3.0.6",
"redux-observable": "^0.14.1",
"reselect": "^3.0.1",
"rxjs": "^5.4.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"flow": "flow",
"prettier": "./node_modules/.bin/prettier --single-quote --write 'src/*/.{js,jsx}'",
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
},
"homepage": "http://renvrant.github.io/tarot-me"
}
Footer
为问题添加注释
您可以编辑已保存读数的问题,其中有 255 个字符可用。例如:
[在空行后和方括号之间添加注释,详细说明所提问题的情况、结果或对阅读的进一步思考。]
分类你的阅读
给问题一个唯一的代码,例如#REL 用于关系问题,#FAM 用于家庭事务,#$$$ 用于财务问题,#CAR 用于职业问题,#PER 用于个人福祉,#HOM 用于有关所在位置的问题你活着...
此代码的工作方式与 Twitter 的“主题标签”相同。
然后,您可以在已保存的读数中搜索特定代码并获取所有内容,并且仅获取与其主题相关的问题。
源码操作指南
步骤1
在打开的屏幕中,在文本框中输入您的问题。
您无需输入问题。
把它写下来是可选的,但如果你以书面形式表述它,它有助于你专注于这个问题。
它将帮助您“在空中”获得您的主题。
它也有助于打印目的;当您将答案与问题一起打印在纸上时,您会更好地记住阅读内容。
当页面关闭时,问题就进入了网络空间。
当然,除非您将阅读内容保存在您的个人帐户中,但是很明显您将其写下来。
即使您不这样做,您仍然可以在已保存的阅读中编辑问题。
问题越详细,答案就越准确。
一个模糊的问题会引起一个模糊的答案。
第2步
现在您可以选择抽签或投掷硬币的方法之间进行选择。
虚拟硬币没有问题,但如果您坚持使用自己的真实金属硬币,您可以按下手动投掷硬币按钮并通过翻转来填写您的投掷结果硬币在屏幕上。
当你点击它们时硬币会翻转。
完成后,“读取”按钮对这两种方法的作用相同。
当您想恢复以前的阅读时,手动投币功能非常方便。
当你记住线条的图案时,你可以稍后再填写,然后再看答案。
无论哪种方式,如果您没有满意地输入您的问题,您可以简单地关闭窗口,更正问题并再次单击继续。
用手投掷三枚硬币,并通过操纵屏幕上的硬币填写结果。
头是阳 杨 (光),尾(或“写作”)是阴 阴 (暗)。
第一次单击硬币时,它会显示 yin 阴 (暗/尾巴)。 每进一步单击,您将在阴(暗/尾)和阳(亮/头)
之间切换 。 每次您投掷三个真实硬币时,请通过单击屏幕中的硬币来填写结果,直到它们与您的投掷相匹配。 您可以操作硬币,直到您按下读取按钮,该按钮将在您完成所有六行(= 18 个硬币)后出现。
步骤 3
每次您构建一条线时,无论是通过按下 虚拟投币按钮,还是选择手动投币按钮并填入三个硬币,都会从下向上一次构建一条六角线。
硬币的一面代表阴,另一面代表阳。
阴数为 2,阳数为 3。
一次投掷三枚硬币可以产生四种组合:
2阳,1阴(3+3+2)= 8
2 阴 1 阳 (2+2+3)= 7
3 阴 (2+2+2)= 6
3 阳 (3+3+3)= 9
如果阴或阳线中的任何一条是红色的,那条线就是一条变化的线,在你咨询的过程中会变成它的对立面。
第4步
要进行解释,请单击“阅读”按钮。
第 5 步
在下一个屏幕中,将出现Cast Hexagram选项卡。
用铸卦开始回答你的问题,经常解释你现在所处的情况,或者以前发生了什么。
第 6 步
单击更改行选项卡。
在您的咨询过程中,变化的线条会转变为它们的对立面。
多行变化时,解释有问题;如果这些线是矛盾的,选择哪一条?
在易经在线,我们已选择应用一套规则来确定作为对您问题的答案的一条变化的线路。最初选择了这条更改线,但您可以通过单击它。
更改行是您问题答案的一部分,但也可以通过单击任何非更改(黑色)行来读取它。
尽管这套规则既古老又普遍,但它只是处理这个微妙问题的众多方法之一。
把它当作一个指导方针,根本没有说服力。
以下规则适用于七种可能的换行数:
0.
没有换行。
只读施法卦。
1.
有一个换线。
咨询这条变化线。
2.
有两条换线。
如果两条线都是六(旧阴)或九(旧阳),则适用上线。
如果一个是六,另一个是九,则以六为准(*)。
3.
共有三个换行。
中间线很重要。
4.
有四个变化线。
阅读上面的非改变行。
5.
有五个变化线。
阅读唯一不变的行。
6.
所有的线路都在变化。
只有变形卦适用。
有两个例外:如果所有行都是六或所有行都是九,请同时阅读铸卦和变卦。
两行交替时,古阴胜古阳的规律的由来我们不得而知,但可能来自抽签法。
不同的卦线出现的机会取决于所使用的方法。
在易经网上我们用三币法,老阴的机率和老阳的机率是一样的,但是用蓍草法,老阴出现的机率是阴阳机的三倍。老杨。
可能是因为这个原因,老阴比老阳更“特殊”。
第 7 步
单击转换的十六进制选项卡。
变形卦描述了未来的情况,在线条改变之后,如果你遵循易经给出的建议。
在我们的例子中,易经所说的加速成长,当你不辞去现在的工作时,你一定会体验到。
(无论是在你现在的工作中,还是在你不辞职的任何其他情况下,《易经》都没有说。也许你无论如何都会被解雇,并在你自己的蒸汽下经历重生。)
如果没有换行,此卦等于铸卦。
第 8 步
单击“卦符号”选项卡以阅读组成铸卦的两个卦(基于文王)的解释。
卦由两个卦组成,一个在另一个之上。
仅显示铸卦的三卦符号。
三卦由三个阴阳线的任意组合组成。
收起阅读 »

#项目开发需求# 小程序网页等系列软件开发
有需求的老板看过来!
专业项目开发团队 java/uniapp/vue
线上有商城等其他项目案例 欢迎来咨询合作
专业技术接单:
我们线下有专业且成熟的技术团队,欢迎同行来甩单
公众号 小程序/app/ 支持定制各行业软件(java/php/vue/python/)
按照最终交易额度的20%来作为报酬 现付现结 一笔反一笔 现寻求各大销售精英合作。有意向的可以+v 18738004780
有需求的老板看过来!
专业项目开发团队 java/uniapp/vue
线上有商城等其他项目案例 欢迎来咨询合作
专业技术接单:
我们线下有专业且成熟的技术团队,欢迎同行来甩单
公众号 小程序/app/ 支持定制各行业软件(java/php/vue/python/)
按照最终交易额度的20%来作为报酬 现付现结 一笔反一笔 现寻求各大销售精英合作。有意向的可以+v 18738004780

【分享】renderjs使用经验-欢迎补充
时隔一年,我重新使用renderjs,却发现很多知识已经忘了。然而由于renderjs的学习资料少之又少,重新学习,消耗了我大量的时间和精力。为避免再次忘掉,同时也为了丰富renderjs资料,方便诸位同行,我决定写一些笔记。
本文纯属个人摸索,如有错漏,还请诸位多多指正!
一、renderjs基本概念及资料
-
学习renderjs的几份相关资料
1)renderjs简介
2)谜之wxs,uni-app如何用它大幅提升性能
3)小程序专题/wxs
4)wxs规范及wxs响应事件 -
与renderjs相关的几个示例
1)通过renderjs,在app和h5端使用完整的 echarts
2)uni-swipe-action滑动操作组件
二、视图层和逻辑层的伪分离
uniapp在APP-vue端、APP-nvue、小程序端、H5端……等所有端,都遵循了视图层和逻辑层分离的设计原则。
例如,下面的html模板隶属于视图层,而模板上绑定的响应数据、事件方法,以及<script>标签中的代码(示例1中未标出),都隶属于逻辑层。
示例1
<!--html模版,属于视图层;模板上绑定的响应数据、事件、方法,属于逻辑层-->
<template>
<text @tap="showCursor" class="my-text">
{{text1}}<text v-if="show === false" class="cursor">光标</text>{{text2}}
</text>
</template>
<script>
/*这里的所有代码,都属于逻辑层*/
export default {
data() {
return {
text1: 'left',
text2: 'right'
}
},
medthod: {
showCursor() {
......
}
}
}
</script>
当用户点击视图层时,如果视图层模板绑定了事件方法(例如showCursor方法),则视图层会通过某种机制,触发逻辑层的showCursor方法,执行逻辑层相关代码——这是视图层调用逻辑层代码的一种机制。而当逻辑层代码运行时,如果代码改变了同属逻辑层且对视图层有影响的那些响应数据 ,那么逻辑层也会通过某种机制,触发视图层的渲染行为,渲染相关视图——这是逻辑层代码控制视图层渲染行为的一种机制。这两种机制在大多数情况下都运行良好,保证和实现了逻辑层与视图层相互通信和解耦,在一定程度上解放了开发者。
不过,这样的解藕并不彻底,因为视图层和逻辑层依然运行于同一个webview下的同一个线程,它们依然在共享着内存,能够直接互访对方的数据(参考示例2或示例3)(虽然共享内存并不是什么坏事,反而还拥有高性能、速度快的优点。)
示例2
methods: {
showCursor() {
this.show = true; //更改逻辑层的响应数据,Vue将在内部保存更改,以便在随后的恰当时刻触发视图层的渲染行为,从而将<text class="cursor">光标</text>插入到{{text1}}和{{text2}}之间(参见示例1的html模板)
conlose.log(this.$el.innerHTML); //改变this.show后,立即查看视图层的渲染效果,发现Vue尚未将内部保存的更改送至试图层,因此<text class="cursor">光标</text>尚未载入到视图层(在这里,逻辑层的代码已经在调用视图层的$el和innerHTML了,这说明逻辑层和视图层是处于同一线程的、可以共享内存的)
this.$nextTick(()=> {
//当执行到这里的时候,vue已经将内部保存的更改送至了视图层,触发了视图层的渲染行为,并完成了视图层的渲染。也即,this.show=true引起的视图层渲染已经完完
conlose.log(this.$el.innerHTML); //由于视图层渲染完毕,所以此时查看innerHTML,会发现<text class="cursor">光标</text>已经插入到视图层
});
}
示例3
methods: {
async showCursor() {
this.show = true; //更改逻辑层的响应数据,Vue将在内部保存更改,以便在随后的恰当时刻触发视图层的渲染行为,从而将<text class="cursor">光标</text>插入到{{text1}}和{{text2}}之间(参见示例1的html模板)
conlose.log(this.$el.innerHTML); //改变this.show后,立即查看视图层的渲染效果,发现Vue尚未将内部保存的更改送至试图层,因此<text class="cursor">光标</text>尚未载入到视图层(在这里,逻辑层的代码已经在调用视图层的$el和innerHTML了,这说明逻辑层和视图层是处于同一线程的、可以共享内存的)
await this.$nextTick(); //等待Vue会将内部保存的更改送到视图层,在待视图层渲染完毕后,才从这里往下执行
conlose.log(this.$el.innerHTML); //由于视图层渲染完毕,所以此时查看innerHTML,会发现<text class="cursor">光标</text>已经插入到视图层
});
}
坏就坏在视图层和逻辑层同属一个线程,它们会相互影响、相互制约:当视图层的渲染量很大时,会阻塞逻辑层代码的运行;而当逻辑层的业务很繁忙时,又会阻塞视图层的渲染。这就容易引起卡顿。因而,在H5手机端,单线程不适用于交互复杂、渲染实时、业务复杂的场景,只能做一些简单的展示。(不过,在性能经常过剩PC端,单线程也能做很多事了,此处不表。)
三、真正的视图层和逻辑层分离
实际上,uniapp只有H5端是视图层和逻辑层工作于同一个线程中的,APP-VUE端、APP-NVUE端,以及小程序端,都是视图层和逻辑层分别工作于不同的两个线程中的。
这是因为,标准浏览器下的H5手机端向来拉胯,大家已经无语到习惯了,一般不指望在H5手机端设计复杂的业务和交互,基本上只做纯展示。而H5的PC端则由于CPU和GPU的强大处理能力,通常足够胜任各种交互复杂、渲染及时、业务复杂的场景。所以,H5的手机端和PC端都不需要双线程(PC端的确不需要,手机端是由于无奈)。
但是APP和小程序不一样啊,CPU和GPU弱鸡(相对于PC端)的同时,人们还对它们抱有巨大的期望,试图在它们身上实现复杂业务和交互。于是,为了追求高性能,APP端和小程序端都打开了两个线程——一个专用于视图渲染,叫渲染线程;一个专用于逻辑业务的处理,叫逻辑线程。这样带来的好处是:即使视图层的渲染量很大,且逻辑层业务也很繁忙,依然不太担心出现性能问题,两个线程各管各的就行了。这也就是为什么APP端和小程序端的性能上限比手机版H5端的性能上限高的原因。
不过,问题也随之而来,由于两个线程是相互独立的,视图层和逻辑层之间的数据关联遭到了割裂,不能再共享内存,不能再互访对方的数据。于是,在APP端和小程序端,前面的示例2和示例3,逻辑层不能再直接使用this.$el和this.$el.innerHTML了,因为$el和innerHTML隶属于视图层,它们在逻辑层中并不存在。
更大的问题在于,由于不能共享内存,视图层和逻辑层之间的数据必须经历(内部)序列化、反序列化和跨线程传送才能完成交换,交换效率十分低下,至少比单线程慢十倍。这就导致类似于touchmove视图跟手渲染这样原本在单线程上很容易实现的需求,在双线程上反而很难实现,总是出视觉上的卡顿现角。
如何解决这个问题呢?我们不妨这样思考:双线程中的渲染线程,它本来就是一个webview;而webview本来就拥有自己的视图层和js环境。既如此,那么我们只要把这个js环境放出来,视为视图层的私有“逻辑层”,那不就可以利用这个私有的逻辑层,在渲染线程内,独立处理touchmove视图跟手渲染这样的渲染任务,从而避免与逻辑线程进行跨线程的数据交换了嘛!
嗯,这个视图层私有的逻辑层,就叫做renderjs吧!
于是乎,APP端和小程序端,都拥有两个线程,一个是专用于视图层渲染的,叫渲染线程;另一个是专用于逻辑层业务的,叫逻辑线程。其中,渲染线程,既拥有自己的视图层,也拥有自己的私有逻辑层,叫renderjs层。
微信:renderjs层太强了,有点怕,得限制一下,让它整一下class和style得了,其它的不要碰。限制之后,就叫wxs吧!
某宝:俺也一样,不过,叫SJS吧!
百度:俺也一样,叫Filter……要不,也叫SJS吧!
WEEK、APP-NUE:我的渲染线程没有js环境,怎么办怎么办?要不,弄一个bingdingx糊弄糊弄吧?!
APP-VUE:虽然已经无敌,但为了兼容wxs,俺也把自己包装一下吧,让自己拥有和wxs一样的接口!wxs有的俺都有,wxs没有的俺也有!
PC端和H5端:虽然俺只有一个线程,但是为了和APP端兼容,俺也可以包装一个自己,假装拥有renderjs层!
四、renderjs详解
下面用代码框架展示视图层、renderjs层、逻辑层三者的关系,以及渲染线程、逻辑线程二者的关系。
示例4 一个标准的双线程模板
<template>
<text class="aaa"><!--这里的模板本身,隶属于渲染线程,可称为渲染线程的视图层,简称视图层。其上绑定的showCursor、text1、text2、show等,则隶属于逻辑线程(称为逻辑层)-->
<text class="bbb" @tap="showCursor">
{{text1}}<text class="cursor" v-if="show === false">光标</text>{{text2}}
</text>
</text>
</template>
<script module="text" lang="renderjs">
//这里的整个script块及代码,全部隶属于渲染线程,可称为渲染线程的逻辑层,或简称为renderjs层。
//它与上面视图层的关系,是同一线程(渲染线程)内的视图层和逻辑层之间的关系,因此它与视图层共享内存,在APP-VUE和Web端可以直接调用视图层的$el、innerHTML等属性和window、document、navigator等浏览器的js API,但在小程序端会功能受限(具体用法参见wxs、SJS等)。
//它与下面逻辑线程的关系,是两个不同线程之间的关系。
//由于渲染线程和逻辑线程二者并未共享内存,所以当前代码块(隶属于渲染线程的私有逻辑层,即renderjs层)不能直接调用隶属于另一个线程(逻辑线程)的showCursor、text1、text2、show等数据。
</script>
<script>
//这里的整个<script>块、代码,以及上面模板中绑定的showCursor、text1、text2、show等,全部隶属于逻辑线程,可称为逻辑层(逻辑线程只有逻辑层)
//在本模块中,可以随意访问showCursor、text1、text2、show等属性或方法,但是显然不能直接访问另一线程中的视图层和逻辑层数据
//也就是,既不能直接访问html模板中的$el、innerHTML等属性,也不能直接访问renderjs、wxs、SJS模块中的数据。而只能通过执行当前模块中的showCursor方法,或更改当前模块中的text1、text2、show属性,间接地、异步地影响视图层的渲染效果。
</script>
对于renderjs,请注意:
- 目前仅支持内联使用。
- 不要直接引用大型类库,推荐通过动态创建 script 方式引用。
- 可以使用 vue 组件的生命周期(不支持 beforeDestroy、destroyed、beforeUnmount、unmounted),不可以使用 App、Page 的生命周期
- 视图层和逻辑层通讯方式与 WXS 一致,另外可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例。
- 注意逻辑层给数据时最好一次性给到渲染层,而不是不停从逻辑层向渲染层发消息,那样还是会产生逻辑层和视图层的多次通信,还是会卡
- 观测更新的数据在视图层可以直接访问到。
- APP 端视图层的页面引用资源的路径相对于根目录计算,例如:./static/test.js。
- APP 端可以使用 dom、bom API,不可直接访问逻辑层数据,不可以使用 uni 相关接口(如:uni.request)
- H5 端逻辑层和视图层实际运行在同一个环境中,相当于使用 mixin 方式,可以直接访问逻辑层数据。
...未完,待续
时隔一年,我重新使用renderjs,却发现很多知识已经忘了。然而由于renderjs的学习资料少之又少,重新学习,消耗了我大量的时间和精力。为避免再次忘掉,同时也为了丰富renderjs资料,方便诸位同行,我决定写一些笔记。
本文纯属个人摸索,如有错漏,还请诸位多多指正!
一、renderjs基本概念及资料
-
学习renderjs的几份相关资料
1)renderjs简介
2)谜之wxs,uni-app如何用它大幅提升性能
3)小程序专题/wxs
4)wxs规范及wxs响应事件 -
与renderjs相关的几个示例
1)通过renderjs,在app和h5端使用完整的 echarts
2)uni-swipe-action滑动操作组件
二、视图层和逻辑层的伪分离
uniapp在APP-vue端、APP-nvue、小程序端、H5端……等所有端,都遵循了视图层和逻辑层分离的设计原则。
例如,下面的html模板隶属于视图层,而模板上绑定的响应数据、事件方法,以及<script>标签中的代码(示例1中未标出),都隶属于逻辑层。
示例1
<!--html模版,属于视图层;模板上绑定的响应数据、事件、方法,属于逻辑层-->
<template>
<text @tap="showCursor" class="my-text">
{{text1}}<text v-if="show === false" class="cursor">光标</text>{{text2}}
</text>
</template>
<script>
/*这里的所有代码,都属于逻辑层*/
export default {
data() {
return {
text1: 'left',
text2: 'right'
}
},
medthod: {
showCursor() {
......
}
}
}
</script>
当用户点击视图层时,如果视图层模板绑定了事件方法(例如showCursor方法),则视图层会通过某种机制,触发逻辑层的showCursor方法,执行逻辑层相关代码——这是视图层调用逻辑层代码的一种机制。而当逻辑层代码运行时,如果代码改变了同属逻辑层且对视图层有影响的那些响应数据 ,那么逻辑层也会通过某种机制,触发视图层的渲染行为,渲染相关视图——这是逻辑层代码控制视图层渲染行为的一种机制。这两种机制在大多数情况下都运行良好,保证和实现了逻辑层与视图层相互通信和解耦,在一定程度上解放了开发者。
不过,这样的解藕并不彻底,因为视图层和逻辑层依然运行于同一个webview下的同一个线程,它们依然在共享着内存,能够直接互访对方的数据(参考示例2或示例3)(虽然共享内存并不是什么坏事,反而还拥有高性能、速度快的优点。)
示例2
methods: {
showCursor() {
this.show = true; //更改逻辑层的响应数据,Vue将在内部保存更改,以便在随后的恰当时刻触发视图层的渲染行为,从而将<text class="cursor">光标</text>插入到{{text1}}和{{text2}}之间(参见示例1的html模板)
conlose.log(this.$el.innerHTML); //改变this.show后,立即查看视图层的渲染效果,发现Vue尚未将内部保存的更改送至试图层,因此<text class="cursor">光标</text>尚未载入到视图层(在这里,逻辑层的代码已经在调用视图层的$el和innerHTML了,这说明逻辑层和视图层是处于同一线程的、可以共享内存的)
this.$nextTick(()=> {
//当执行到这里的时候,vue已经将内部保存的更改送至了视图层,触发了视图层的渲染行为,并完成了视图层的渲染。也即,this.show=true引起的视图层渲染已经完完
conlose.log(this.$el.innerHTML); //由于视图层渲染完毕,所以此时查看innerHTML,会发现<text class="cursor">光标</text>已经插入到视图层
});
}
示例3
methods: {
async showCursor() {
this.show = true; //更改逻辑层的响应数据,Vue将在内部保存更改,以便在随后的恰当时刻触发视图层的渲染行为,从而将<text class="cursor">光标</text>插入到{{text1}}和{{text2}}之间(参见示例1的html模板)
conlose.log(this.$el.innerHTML); //改变this.show后,立即查看视图层的渲染效果,发现Vue尚未将内部保存的更改送至试图层,因此<text class="cursor">光标</text>尚未载入到视图层(在这里,逻辑层的代码已经在调用视图层的$el和innerHTML了,这说明逻辑层和视图层是处于同一线程的、可以共享内存的)
await this.$nextTick(); //等待Vue会将内部保存的更改送到视图层,在待视图层渲染完毕后,才从这里往下执行
conlose.log(this.$el.innerHTML); //由于视图层渲染完毕,所以此时查看innerHTML,会发现<text class="cursor">光标</text>已经插入到视图层
});
}
坏就坏在视图层和逻辑层同属一个线程,它们会相互影响、相互制约:当视图层的渲染量很大时,会阻塞逻辑层代码的运行;而当逻辑层的业务很繁忙时,又会阻塞视图层的渲染。这就容易引起卡顿。因而,在H5手机端,单线程不适用于交互复杂、渲染实时、业务复杂的场景,只能做一些简单的展示。(不过,在性能经常过剩PC端,单线程也能做很多事了,此处不表。)
三、真正的视图层和逻辑层分离
实际上,uniapp只有H5端是视图层和逻辑层工作于同一个线程中的,APP-VUE端、APP-NVUE端,以及小程序端,都是视图层和逻辑层分别工作于不同的两个线程中的。
这是因为,标准浏览器下的H5手机端向来拉胯,大家已经无语到习惯了,一般不指望在H5手机端设计复杂的业务和交互,基本上只做纯展示。而H5的PC端则由于CPU和GPU的强大处理能力,通常足够胜任各种交互复杂、渲染及时、业务复杂的场景。所以,H5的手机端和PC端都不需要双线程(PC端的确不需要,手机端是由于无奈)。
但是APP和小程序不一样啊,CPU和GPU弱鸡(相对于PC端)的同时,人们还对它们抱有巨大的期望,试图在它们身上实现复杂业务和交互。于是,为了追求高性能,APP端和小程序端都打开了两个线程——一个专用于视图渲染,叫渲染线程;一个专用于逻辑业务的处理,叫逻辑线程。这样带来的好处是:即使视图层的渲染量很大,且逻辑层业务也很繁忙,依然不太担心出现性能问题,两个线程各管各的就行了。这也就是为什么APP端和小程序端的性能上限比手机版H5端的性能上限高的原因。
不过,问题也随之而来,由于两个线程是相互独立的,视图层和逻辑层之间的数据关联遭到了割裂,不能再共享内存,不能再互访对方的数据。于是,在APP端和小程序端,前面的示例2和示例3,逻辑层不能再直接使用this.$el和this.$el.innerHTML了,因为$el和innerHTML隶属于视图层,它们在逻辑层中并不存在。
更大的问题在于,由于不能共享内存,视图层和逻辑层之间的数据必须经历(内部)序列化、反序列化和跨线程传送才能完成交换,交换效率十分低下,至少比单线程慢十倍。这就导致类似于touchmove视图跟手渲染这样原本在单线程上很容易实现的需求,在双线程上反而很难实现,总是出视觉上的卡顿现角。
如何解决这个问题呢?我们不妨这样思考:双线程中的渲染线程,它本来就是一个webview;而webview本来就拥有自己的视图层和js环境。既如此,那么我们只要把这个js环境放出来,视为视图层的私有“逻辑层”,那不就可以利用这个私有的逻辑层,在渲染线程内,独立处理touchmove视图跟手渲染这样的渲染任务,从而避免与逻辑线程进行跨线程的数据交换了嘛!
嗯,这个视图层私有的逻辑层,就叫做renderjs吧!
于是乎,APP端和小程序端,都拥有两个线程,一个是专用于视图层渲染的,叫渲染线程;另一个是专用于逻辑层业务的,叫逻辑线程。其中,渲染线程,既拥有自己的视图层,也拥有自己的私有逻辑层,叫renderjs层。
微信:renderjs层太强了,有点怕,得限制一下,让它整一下class和style得了,其它的不要碰。限制之后,就叫wxs吧!
某宝:俺也一样,不过,叫SJS吧!
百度:俺也一样,叫Filter……要不,也叫SJS吧!
WEEK、APP-NUE:我的渲染线程没有js环境,怎么办怎么办?要不,弄一个bingdingx糊弄糊弄吧?!
APP-VUE:虽然已经无敌,但为了兼容wxs,俺也把自己包装一下吧,让自己拥有和wxs一样的接口!wxs有的俺都有,wxs没有的俺也有!
PC端和H5端:虽然俺只有一个线程,但是为了和APP端兼容,俺也可以包装一个自己,假装拥有renderjs层!
四、renderjs详解
下面用代码框架展示视图层、renderjs层、逻辑层三者的关系,以及渲染线程、逻辑线程二者的关系。
示例4 一个标准的双线程模板
<template>
<text class="aaa"><!--这里的模板本身,隶属于渲染线程,可称为渲染线程的视图层,简称视图层。其上绑定的showCursor、text1、text2、show等,则隶属于逻辑线程(称为逻辑层)-->
<text class="bbb" @tap="showCursor">
{{text1}}<text class="cursor" v-if="show === false">光标</text>{{text2}}
</text>
</text>
</template>
<script module="text" lang="renderjs">
//这里的整个script块及代码,全部隶属于渲染线程,可称为渲染线程的逻辑层,或简称为renderjs层。
//它与上面视图层的关系,是同一线程(渲染线程)内的视图层和逻辑层之间的关系,因此它与视图层共享内存,在APP-VUE和Web端可以直接调用视图层的$el、innerHTML等属性和window、document、navigator等浏览器的js API,但在小程序端会功能受限(具体用法参见wxs、SJS等)。
//它与下面逻辑线程的关系,是两个不同线程之间的关系。
//由于渲染线程和逻辑线程二者并未共享内存,所以当前代码块(隶属于渲染线程的私有逻辑层,即renderjs层)不能直接调用隶属于另一个线程(逻辑线程)的showCursor、text1、text2、show等数据。
</script>
<script>
//这里的整个<script>块、代码,以及上面模板中绑定的showCursor、text1、text2、show等,全部隶属于逻辑线程,可称为逻辑层(逻辑线程只有逻辑层)
//在本模块中,可以随意访问showCursor、text1、text2、show等属性或方法,但是显然不能直接访问另一线程中的视图层和逻辑层数据
//也就是,既不能直接访问html模板中的$el、innerHTML等属性,也不能直接访问renderjs、wxs、SJS模块中的数据。而只能通过执行当前模块中的showCursor方法,或更改当前模块中的text1、text2、show属性,间接地、异步地影响视图层的渲染效果。
</script>
对于renderjs,请注意:
- 目前仅支持内联使用。
- 不要直接引用大型类库,推荐通过动态创建 script 方式引用。
- 可以使用 vue 组件的生命周期(不支持 beforeDestroy、destroyed、beforeUnmount、unmounted),不可以使用 App、Page 的生命周期
- 视图层和逻辑层通讯方式与 WXS 一致,另外可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例。
- 注意逻辑层给数据时最好一次性给到渲染层,而不是不停从逻辑层向渲染层发消息,那样还是会产生逻辑层和视图层的多次通信,还是会卡
- 观测更新的数据在视图层可以直接访问到。
- APP 端视图层的页面引用资源的路径相对于根目录计算,例如:./static/test.js。
- APP 端可以使用 dom、bom API,不可直接访问逻辑层数据,不可以使用 uni 相关接口(如:uni.request)
- H5 端逻辑层和视图层实际运行在同一个环境中,相当于使用 mixin 方式,可以直接访问逻辑层数据。
...未完,待续

jdk17新版本获取签名MD5
安装好jdk,设置好环境变量以后,新版本不提供md5的查看
想要查看需要使用新命令
keytool -exportcert -keystore 你的名称.keystore | openssl dgst -md5
如果提示openssl 不是内部命令
就要安装openssl
安装方法:(偷个懒 大家去看大佬的博客)
https://blog.csdn.net/qq_46550964/article/details/111507119
安装好jdk,设置好环境变量以后,新版本不提供md5的查看
想要查看需要使用新命令
keytool -exportcert -keystore 你的名称.keystore | openssl dgst -md5
如果提示openssl 不是内部命令
就要安装openssl
安装方法:(偷个懒 大家去看大佬的博客)
https://blog.csdn.net/qq_46550964/article/details/111507119

v-show和v-for用在用一个元素上,实现input搜索功能
- <van-field
- class="date-selector"
- v-model="search.kdgtName"
- placeholder="请输入搜索内容" />
- <van-cell
- v-show="item.name.includes(search.kdgtName)"
- key="i"
v-for="(item,i) in kdgtNameList"
class="date-item"
@click="setkdgtName(item)">
<span class="item-text">{{item.name}}</span>
</van-cell>
通过 v-show和 v-for以及includes的使用,实现input搜索功能。
注意:这只适合数据量较少的情况下。
固定定位下的水平垂直居中,可以试一试:
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
- <van-field
- class="date-selector"
- v-model="search.kdgtName"
- placeholder="请输入搜索内容" />
- <van-cell
- v-show="item.name.includes(search.kdgtName)"
- key="i"
v-for="(item,i) in kdgtNameList"
class="date-item"
@click="setkdgtName(item)">
<span class="item-text">{{item.name}}</span>
</van-cell>
通过 v-show和 v-for以及includes的使用,实现input搜索功能。
注意:这只适合数据量较少的情况下。
固定定位下的水平垂直居中,可以试一试:
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;

window.open 下载文件
通过window.open方法进行文件下载,例如:
window.open("https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/bf4ed9a0-4fdb-11eb-8a36-ebb87efcf8c0.png?attname=1.png");
注意:加上?attname=1.png可以下载一个命名为1的图片。
不是每个资源文件都可以window.open方法进行文件下载,但是通过加attname属性就可以
通过window.open方法进行文件下载,例如:
window.open("https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/bf4ed9a0-4fdb-11eb-8a36-ebb87efcf8c0.png?attname=1.png");
注意:加上?attname=1.png可以下载一个命名为1的图片。
不是每个资源文件都可以window.open方法进行文件下载,但是通过加attname属性就可以

UNIAPP 局域网打印
我是采用CLodop 插件开发局域网打印的, 需要手持设备,一台打印服务器,打印机在同一个局域网内即可。
目前测试稳定性还可以,满足业务使用
引用一个js文件即可,其他调用方式同CLodop调用方式一样。
我是采用CLodop 插件开发局域网打印的, 需要手持设备,一台打印服务器,打印机在同一个局域网内即可。
目前测试稳定性还可以,满足业务使用
引用一个js文件即可,其他调用方式同CLodop调用方式一样。

官方支持了google pay,但是没有支持google play支付,需要自己写原生插件
google play 的支付用于商店内的应用或应用内购买,多用于虚拟物品,游戏币等区域。
google pay 官方目的是用于线下/线上的实物类交易。
google play 的支付用于商店内的应用或应用内购买,多用于虚拟物品,游戏币等区域。
google pay 官方目的是用于线下/线上的实物类交易。

H5调用摄像头扫描条形码
参考文献:https://github.com/maslick/koder
识别效率相对较高
参考文献:https://github.com/maslick/koder
识别效率相对较高