first commit
This commit is contained in:
commit
314efc7ff3
27
.gitignore
vendored
Normal file
27
.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
/build
|
||||
/logs
|
||||
|
||||
# sign
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
||||
.ide
|
||||
.preview.json
|
||||
6
.prettierignore
Normal file
6
.prettierignore
Normal file
@ -0,0 +1,6 @@
|
||||
package.json
|
||||
manifest.json
|
||||
README.md
|
||||
|
||||
# assets/js
|
||||
src/assets/js/*.js
|
||||
36
README.md
Normal file
36
README.md
Normal file
@ -0,0 +1,36 @@
|
||||
# 手表示例模版
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
├── sign # 存储 rpk 包签名模块(须自行生成);
|
||||
│ ├── certificate.pem # 证书文件
|
||||
│ └── private.pem # 私钥文件
|
||||
└── src
|
||||
│ ├── assets # 公用的资源(images/styles/字体...)
|
||||
│ │ ├──images # 存储 png/jpg/svg 等公共图片资源
|
||||
│ │ └──styles # 存放 less/css/sass 等公共样式资源
|
||||
│ ├── pages # 统一存放项目页面级代码
|
||||
│ ├── app.ux # 应用程序代码的入口文件
|
||||
│ ├── manifest.json # 配置蓝河应用基本信息
|
||||
│ └── components # 存放蓝河应用组件
|
||||
└── package.json # 定义项目需要的各种模块及配置信息
|
||||
```
|
||||
|
||||
### 模版说明
|
||||
|
||||
- `Demo` 页面:示例页面;
|
||||
- `DemoDetail`页面:详情页面;
|
||||
|
||||
## 如何使用
|
||||
|
||||
- **内置样式处理方案**;「蓝河应用」支持 `sass` 的预编译;这里采取 [dart sass](https://sass-lang.com/documentation) 方案,并内置了部分变量,以及常用混合方法,使得可以轻松开启样式编写、复用、修改等;
|
||||
- **添加新增页面命令脚本**;如果需要新建页面,只需运行:`yarn gen YourPageName` ,当然,也可以根据需要,自行定定制模板:*/command/gen/template.ux*;
|
||||
- **集成 [Prettier](https://prettier.io/)**;在检测代码中潜在问题的同时,统一团队代码规范、风格(`js`,`less`,`scss`等),从而促使写出高质量代码,以提升工作效率(尤其针对团队开发);
|
||||
|
||||
## 内置命令
|
||||
|
||||
| 命令 | 描述 | 备注 |
|
||||
|---|---|---|
|
||||
| `yarn gen ` | 新增「蓝河应用」页面 | 助你高效生成页面,模版可自定义,推荐 ✓|
|
||||
| `yarn prettier` | 一键美化代码(js/css/less/ux) | 实在是团队开发好帮手,推荐 ✓ |
|
||||
17
jsconfig.json
Normal file
17
jsconfig.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": false,
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedParameters": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"checkJs": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
41
package.json
Normal file
41
package.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "talk",
|
||||
"version": "1.1.0",
|
||||
"packageManager": "pnpm@7.1.0",
|
||||
"description": "Watch Template",
|
||||
"scripts": {
|
||||
"gen": "node ./scripts/gen/index.js",
|
||||
"precommit-msg": "echo '🚧 start pre-commit checks ...' && exit 0",
|
||||
"prettier": "node ./scripts/selfCloseInputTag.js && prettier --write \"src/**/*.{js,ux,less,scss,css}\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"colors": "^1.4.0",
|
||||
"husky": "^4.3.0",
|
||||
"lint-staged": "^10.5.1",
|
||||
"prettier": "^1.15.3",
|
||||
"prettier-plugin-ux": "^0.3.0"
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"printWidth": 80,
|
||||
"proseWrap": "never",
|
||||
"tabWidth": 2
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "yarn run precommit-msg && lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/**.{ux,js,json,pcss,md,vue}": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"keywords": [
|
||||
"多终端应用",
|
||||
"手表示例",
|
||||
"手表模版"
|
||||
]
|
||||
}
|
||||
1013
pnpm-lock.yaml
generated
Normal file
1013
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
87
scripts/gen/index.js
Normal file
87
scripts/gen/index.js
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @desc: gen script command,make a new page generated by one click.
|
||||
* @author: nicejade
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const colors = require('colors')
|
||||
|
||||
const newFolderName = process.argv[2]
|
||||
|
||||
String.prototype.firstUpperCase = function() {
|
||||
return this.replace(/\b(\w)/g, $1 => {
|
||||
return $1.toLowerCase()
|
||||
})
|
||||
}
|
||||
const resolve = dir => {
|
||||
return path.join(__dirname, '../..', dir)
|
||||
}
|
||||
|
||||
const successExecPrint = msg => {
|
||||
console.log(
|
||||
colors.green(`✓ `) +
|
||||
colors.cyan(`${msg} `) +
|
||||
colors.green('task has been successfully executed.')
|
||||
)
|
||||
}
|
||||
|
||||
function createNewPage(newFolderPath) {
|
||||
const mReg = new RegExp('@PAGE_CLASS_NAME', 'g')
|
||||
const pageContent = fs.readFileSync(`${__dirname}/template.ux`, 'UTF-8')
|
||||
const rootClassName = newFolderName
|
||||
.firstUpperCase()
|
||||
.replace(/([A-Z])/g, '-$1')
|
||||
.toLowerCase()
|
||||
const newContent = pageContent.replace(mReg, rootClassName)
|
||||
|
||||
fs.mkdirSync(newFolderPath, 0777)
|
||||
fs.writeFile(`${newFolderPath}/index.ux`, newContent, error => {
|
||||
if (error) throw `Something went wrong: ${error}`
|
||||
})
|
||||
successExecPrint('Create New Page')
|
||||
}
|
||||
|
||||
function saveRouter2Manifest() {
|
||||
const manifestPath = resolve('/src/manifest.json')
|
||||
let manifestConf = fs.readFileSync(manifestPath, 'UTF-8')
|
||||
manifestConf = JSON.parse(manifestConf)
|
||||
const routerPages = manifestConf.router.pages
|
||||
routerPages[`pages/${newFolderName}`] = {
|
||||
component: 'index'
|
||||
}
|
||||
manifestConf = JSON.stringify(manifestConf, null, 2)
|
||||
fs.writeFile(manifestPath, manifestConf, error => {
|
||||
if (error) throw `Something went wrong[@saveRouter2Manifest]: ${error}`
|
||||
})
|
||||
successExecPrint('Save Router Into Manifest')
|
||||
}
|
||||
|
||||
function main() {
|
||||
if (!newFolderName) {
|
||||
return console.warn(
|
||||
`⚠️ Please enter the name of the page you want to create.`.underline.red
|
||||
)
|
||||
}
|
||||
|
||||
const folderNameReg = /^[A-Z][[A-Za-z0-9]+$/
|
||||
if (!folderNameReg.test(newFolderName)) {
|
||||
return console.warn(
|
||||
`⚠️ Please enter the standard Folder name. Eg: XyzAbcde.`.underline.red
|
||||
)
|
||||
}
|
||||
|
||||
const newFolderPath = path.join(__dirname, `../../src/pages/${newFolderName}`)
|
||||
const isExist = fs.existsSync(newFolderPath)
|
||||
|
||||
if (isExist) {
|
||||
return console.warn(
|
||||
`⚠️ ${newFolderName} already exists in the /src/pages/ directory.`
|
||||
.underline.red
|
||||
)
|
||||
}
|
||||
createNewPage(newFolderPath)
|
||||
saveRouter2Manifest()
|
||||
}
|
||||
|
||||
main()
|
||||
27
scripts/gen/template.ux
Normal file
27
scripts/gen/template.ux
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="title">{{ title }}</text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: {
|
||||
title: '欢迎体验多终端应用开发'
|
||||
},
|
||||
|
||||
onInit() {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './../../assets/styles/style.scss';
|
||||
.wrapper {
|
||||
@include flex-box-mixins(column, center, center);
|
||||
.title {
|
||||
font-size: 8 * $size-factor;
|
||||
text-align: center;
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
36
scripts/selfCloseInputTag.js
Normal file
36
scripts/selfCloseInputTag.js
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file: selfCloseInputTag.js
|
||||
* @desc: 遍历指定目录下 .ux 文件,将其中 input 标签由 <input **></input> 转换为 <input ** />
|
||||
* @date: 2019-01-23
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const codePath = './src/'
|
||||
|
||||
const main = codePath => {
|
||||
const traversing = cpath => {
|
||||
const files = fs.readdirSync(cpath)
|
||||
files.forEach(fileName => {
|
||||
const fPath = path.join(cpath, fileName)
|
||||
const stats = fs.statSync(fPath)
|
||||
stats.isDirectory() && traversing(fPath)
|
||||
stats.isFile() && fPath.endsWith('.ux') && matchAndReplace(fPath)
|
||||
})
|
||||
}
|
||||
traversing(codePath)
|
||||
}
|
||||
|
||||
const matchAndReplace = path => {
|
||||
const pageContent = fs.readFileSync(path, 'UTF-8')
|
||||
const newContent = pageContent.replace(
|
||||
/(<)([\s]*?)(input\b[^\/]*?)>[\s\S]*?<\/input>/gm,
|
||||
'$1$3 />'
|
||||
)
|
||||
fs.writeFile(path, newContent, error => {
|
||||
if (error) throw `Something went wrong: ${error}`
|
||||
})
|
||||
}
|
||||
|
||||
main(codePath)
|
||||
9
src/app.ux
Normal file
9
src/app.ux
Normal file
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
/**
|
||||
* 应用级别的配置,供所有页面公用
|
||||
*/
|
||||
|
||||
export default {
|
||||
onCreate() {}
|
||||
}
|
||||
</script>
|
||||
BIN
src/assets/images/logo.png
Normal file
BIN
src/assets/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/message-arrow.png
Normal file
BIN
src/assets/images/message-arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 426 KiB |
BIN
src/assets/images/up.bin.png
Normal file
BIN
src/assets/images/up.bin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 348 B |
5
src/assets/styles/mixins.scss
Normal file
5
src/assets/styles/mixins.scss
Normal file
@ -0,0 +1,5 @@
|
||||
@mixin flex-box-mixins($direction: row, $justify: center, $align-items: center) {
|
||||
flex-direction: $direction;
|
||||
justify-content: $justify;
|
||||
align-items: $align-items;
|
||||
}
|
||||
2
src/assets/styles/style.scss
Normal file
2
src/assets/styles/style.scss
Normal file
@ -0,0 +1,2 @@
|
||||
@import './variables.scss';
|
||||
@import './mixins.scss';
|
||||
9
src/assets/styles/variables.scss
Normal file
9
src/assets/styles/variables.scss
Normal file
@ -0,0 +1,9 @@
|
||||
$brand: #09ba07;
|
||||
|
||||
$white: #ffffff;
|
||||
$black: #000000;
|
||||
$grey: #9393aa;
|
||||
$red: #fa0101;
|
||||
$green: #ffff00;
|
||||
|
||||
$size-factor: 5px;
|
||||
36
src/manifest.json
Normal file
36
src/manifest.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"package": "com.chorblack.talk",
|
||||
"name": "talk",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 1,
|
||||
"appCategory": [
|
||||
"other"
|
||||
],
|
||||
"icon": "/assets/images/logo.png",
|
||||
"features": [
|
||||
{
|
||||
"name": "blueos.app.appmanager.router"
|
||||
}
|
||||
],
|
||||
"deviceTypeList": [
|
||||
"watch",
|
||||
"watch-square"
|
||||
],
|
||||
"config": {
|
||||
"designWidth": 466
|
||||
},
|
||||
"router": {
|
||||
"entry": "pages/Demo",
|
||||
"pages": {
|
||||
"pages/Demo": {
|
||||
"component": "index"
|
||||
},
|
||||
"pages/DemoDetail": {
|
||||
"component": "index"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"backgroundColor": "#ffffff"
|
||||
}
|
||||
}
|
||||
411
src/pages/Demo/index.ux
Normal file
411
src/pages/Demo/index.ux
Normal file
@ -0,0 +1,411 @@
|
||||
<template>
|
||||
<scroll
|
||||
class="wrapper"
|
||||
scrollbar="{{true}}"
|
||||
bounces="{{true}}"
|
||||
scroll-y="{{true}}"
|
||||
id="wrapperbox">
|
||||
<scroll
|
||||
id="msgbox"
|
||||
bounces="false"
|
||||
scroll-y="true"
|
||||
@scrolltop="scrolltopHandler"
|
||||
@scrollbottom="scrollbottomHandler"
|
||||
scroll-bottom="{{scrollbottom}}"
|
||||
class="message-pannel">
|
||||
<div
|
||||
class="loading-wrap"
|
||||
if="{{showLoading}}"
|
||||
style="height:{{loadingHeight}}px">
|
||||
<vw-loading size="48" class="loading"></vw-loading>
|
||||
</div>
|
||||
<div class="message" for="{{msgList}}">
|
||||
<div class="message-item our" if="{{$item.side==='our'}}">
|
||||
<text class="txt txt-our" if="{{$item.message}}">
|
||||
{{ $item.message }}
|
||||
</text>
|
||||
<image class="img our" if="{{$item.img}}" src="{{$item.img}}"></image>
|
||||
</div>
|
||||
<div class="message-item other" else>
|
||||
<text class="txt txt-other" if="{{$item.message}}">
|
||||
{{ $item.message }}
|
||||
</text>
|
||||
<image
|
||||
class="img other"
|
||||
if="{{$item.img}}"
|
||||
src="{{$item.img}}"></image>
|
||||
</div>
|
||||
</div>
|
||||
<div id="item-arrow" class="message-item-arrow" style="height: 184px">
|
||||
<image
|
||||
src="../../assets/images/message-arrow.png"
|
||||
class="message-arrow"></image>
|
||||
</div>
|
||||
</scroll>
|
||||
<scroll scroll-y="true" class="reply-pannel">
|
||||
<div class="message-item-arrow" style="height: 124px">
|
||||
<image
|
||||
src="../../assets/images/reply-arrow.png"
|
||||
class="reply-arrow"></image>
|
||||
</div>
|
||||
<div class="input-box">
|
||||
<input
|
||||
for="{{replyMsg}}"
|
||||
class="btn"
|
||||
type="button"
|
||||
value="{{$item.value}}"
|
||||
@click="reply($item.text)" />
|
||||
</div>
|
||||
</scroll>
|
||||
</scroll>
|
||||
</template>
|
||||
<script>
|
||||
let num = 1
|
||||
let a, b, c
|
||||
export const listenMsg = (callback) => {
|
||||
a = setInterval(() => {
|
||||
const msg = '对方发来消息' + num++
|
||||
console.log('msg', msg)
|
||||
callback && callback(msg)
|
||||
}, 5000)
|
||||
return a
|
||||
}
|
||||
|
||||
let histroy = [
|
||||
{
|
||||
side: 'other',
|
||||
message: `借我500块钱!`,
|
||||
},
|
||||
{
|
||||
side: 'other',
|
||||
message: '急用!',
|
||||
},
|
||||
{
|
||||
side: 'other',
|
||||
message: '收到回复!',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '🧧请查收',
|
||||
},
|
||||
{
|
||||
side: 'other',
|
||||
message: '我们来念诗吧',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '好啊',
|
||||
},
|
||||
{
|
||||
side: 'other',
|
||||
message: '天苍苍,野茫茫,风吹草地,现牛羊',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '床前明月光,疑是地上霜,举头望明月,低头思故乡',
|
||||
},
|
||||
]
|
||||
|
||||
export const getHistroyMsg = (callback) => {
|
||||
const arr = histroy.splice(0, 4)
|
||||
c = setTimeout(() => {
|
||||
callback(arr)
|
||||
}, 1000)
|
||||
return c
|
||||
}
|
||||
|
||||
export const fastReplyMsg = [
|
||||
{
|
||||
value: '语音',
|
||||
text: '((( 15s',
|
||||
},
|
||||
{
|
||||
value: '表情',
|
||||
text: '😄',
|
||||
},
|
||||
{
|
||||
value: 'OK',
|
||||
text: 'OK',
|
||||
},
|
||||
{
|
||||
value: '好的',
|
||||
text: '好的',
|
||||
},
|
||||
{
|
||||
value: '是的',
|
||||
text: '是的',
|
||||
},
|
||||
{
|
||||
value: '我在路上',
|
||||
text: '我在路上',
|
||||
},
|
||||
{
|
||||
value: '我到了',
|
||||
text: '我到了',
|
||||
},
|
||||
{
|
||||
value: '现在忙',
|
||||
text: '现在忙,过会儿回复',
|
||||
},
|
||||
]
|
||||
|
||||
export const msgList = [
|
||||
{
|
||||
side: 'our',
|
||||
message: '新年快乐😄',
|
||||
},
|
||||
{
|
||||
side: 'other',
|
||||
message: '新年快乐!',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '开工大吉',
|
||||
},
|
||||
{
|
||||
side: 'other',
|
||||
message: '开工大吉!!',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '最近怎么样了啊',
|
||||
},
|
||||
{
|
||||
side: 'other',
|
||||
message: '最近很好',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '那就好',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '好的',
|
||||
},
|
||||
{
|
||||
side: 'our',
|
||||
message: '你借我的钱什么时候还',
|
||||
},
|
||||
{ side: 'other', img: '../../assets/images/message-arrow.png' },
|
||||
{
|
||||
side: 'our',
|
||||
message: '还在吗😊',
|
||||
},
|
||||
]
|
||||
|
||||
let loadHistroyMsgTimeId = -1
|
||||
let listenMsgTimeId = -1
|
||||
let getHistroyMsgTimeId = -1
|
||||
|
||||
export default {
|
||||
data: {
|
||||
showLoading: false,
|
||||
scrollbottom: '0',
|
||||
clientHeight: 750,
|
||||
loadingHeight: 100,
|
||||
msgListRectHeight: -1,
|
||||
msgList: msgList,
|
||||
replyMsg: fastReplyMsg,
|
||||
},
|
||||
onShow() {
|
||||
//listenMsgTimeId = listenMsg(this.otherPushMsg)
|
||||
},
|
||||
onDestroy() {
|
||||
clearTimeout(loadHistroyMsgTimeId)
|
||||
clearTimeout(getHistroyMsgTimeId)
|
||||
clearInterval(listenMsgTimeId)
|
||||
clearInterval(a)
|
||||
clearTimeout(b)
|
||||
clearTimeout(c)
|
||||
},
|
||||
async otherPushMsg(msg) {
|
||||
const bFlag = await this.isArrowBottom()
|
||||
this.pushMsg(msg, 'other')
|
||||
this.nextTick(() => {
|
||||
if (bFlag) {
|
||||
this.$element('msgbox').scrollBy({
|
||||
top: 10000,
|
||||
left: 0,
|
||||
behavior: 'smooth',
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 模拟 nextTick 功能
|
||||
*/
|
||||
async nextTick(callBack) {
|
||||
const height = await this.getRect()
|
||||
if (height != this.msgListRectHeight) {
|
||||
callBack && callBack()
|
||||
} else {
|
||||
b = setTimeout(() => {
|
||||
this.nextTick(callBack)
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
isArrowBottom() {
|
||||
return new Promise((reslove) => {
|
||||
this.$element('item-arrow').getBoundingClientRect({
|
||||
success: (data) => {
|
||||
reslove(data.bottom <= this.clientHeight)
|
||||
},
|
||||
})
|
||||
})
|
||||
},
|
||||
async scrolltopHandler() {
|
||||
if (this.showLoading) return
|
||||
const oldHeight = await this.getRect()
|
||||
this.showLoading = true
|
||||
getHistroyMsgTimeId = getHistroyMsg((msgs) => {
|
||||
this.msgList = [...msgs, ...this.msgList]
|
||||
this.scrollbottom = `${oldHeight - this.clientHeight}`
|
||||
this.showLoading = false
|
||||
this.scrollbottom = `${
|
||||
parseFloat(this.scrollbottom) + this.loadingHeight
|
||||
}`
|
||||
})
|
||||
},
|
||||
getRect() {
|
||||
return new Promise((reslove) => {
|
||||
this.$element('msgbox').getScrollRect({
|
||||
success({ height }) {
|
||||
reslove(height)
|
||||
},
|
||||
})
|
||||
})
|
||||
},
|
||||
reply(message) {
|
||||
this.pushMsg(message, 'our')
|
||||
this.nextTick(() => {
|
||||
this.$element('msgbox').scrollBy({
|
||||
top: 10000,
|
||||
left: 0,
|
||||
behavior: 'smooth',
|
||||
})
|
||||
this.$element('wrapperbox').scrollTo({
|
||||
top: 0,
|
||||
left: 0,
|
||||
behavior: 'smooth',
|
||||
})
|
||||
})
|
||||
},
|
||||
async pushMsg(message, side) {
|
||||
this.msgListRectHeight = await this.getRect()
|
||||
this.msgList.push({
|
||||
side,
|
||||
message,
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.wrapper {
|
||||
width: 466px;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
scroll-snap-type: y mandatory;
|
||||
background-color: #000000;
|
||||
}
|
||||
.loading-wrap {
|
||||
justify-content: center;
|
||||
width: 466px;
|
||||
height: 100px;
|
||||
}
|
||||
@keyframes Rotate {
|
||||
from {
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.loading {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
/* 单个动画 */
|
||||
animation-name: Rotate;
|
||||
animation-fill-mode: forwards;
|
||||
animation-duration: 1000ms;
|
||||
}
|
||||
.message-pannel {
|
||||
width: 466px;
|
||||
height: 100%;
|
||||
scroll-snap-align: end;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
}
|
||||
.message {
|
||||
width: 466px;
|
||||
border: 1px solid #000;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.message-item {
|
||||
width: 466px;
|
||||
padding: 0 60px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.our {
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.other {
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 300px;
|
||||
}
|
||||
.txt {
|
||||
color: #f0f8ff;
|
||||
padding: 20px;
|
||||
max-width: 350px;
|
||||
background-color: #405eff;
|
||||
}
|
||||
.txt-our {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.txt-other {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.reply-pannel {
|
||||
width: 466px;
|
||||
height: 100%;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
.message-item-arrow {
|
||||
width: 466px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.message-arrow {
|
||||
height: 32px;
|
||||
margin-bottom: 82px;
|
||||
width: 32px;
|
||||
}
|
||||
.reply-arrow {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
.input-box {
|
||||
width: 466px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.btn {
|
||||
width: 300px;
|
||||
height: 80px;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #405eff;
|
||||
}
|
||||
</style>
|
||||
27
src/pages/DemoDetail/index.ux
Normal file
27
src/pages/DemoDetail/index.ux
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="title">{{ text }}</text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: {
|
||||
text: '你好,世界'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './../../assets/styles/style.scss';
|
||||
|
||||
.wrapper {
|
||||
@include flex-box-mixins(column, center, center);
|
||||
margin: 0 10 * $size-factor;
|
||||
.title {
|
||||
font-size: 8 * $size-factor;
|
||||
text-align: center;
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user