雅荷心语博客
雅荷心语
心之所向便是光
  • 首页
  • 前端之旅
  • 后端之路
  • 软件工具
  • 心灵鸡汤
  • 心路历程
  • 视频资料
  • 关于我们
    • 关于我
    • 关于我
  • 微信平台
    • 业务合作
  • 首页
  • 前端之旅
  • 后端之路
  • 软件工具
  • 心灵鸡汤
  • 心路历程
  • 视频资料
  • 关于我们
    • 关于我
    • 关于我
  • 微信平台
    • 业务合作
  • 关注本站
    • 微信
    • 微博
    • 腾讯微博
    • Twitter
    • Facebook
    • RSS订阅
Hi, 请登录     我要注册     找回密码
分享到:

前端之旅

去分类设置中添加分类描述吧

关于对fluent-ffmpeg的一次简单尝试

2022-03-29admin阅读(97)评论(0)

今天简单研究了一下怎么用 nodejs 来操作 ffmpeg, 发现这个包, 做了一些简单的尝试, 做个记录!

其中 这段关于计算视频的码率: 

// 如果一个视频文件大小有10GB,时长为90分钟(5400秒), 那么它的码率(视频+音频)为:

// 10 x 1024 x 8 / 5400 = 15Mbps

// 视频文件体积:(音频码率+视频码率) x 时长 / 8

// 如果一个视频的视频码率为3Mbps, 音频码率为512Kbps, 时长90分钟(5400秒), 那么整个视频文件的大小就是:

// (512/1024 + 3) x 5400 / 8 = 2362MB

// 相反,如果一个视频文件大小有10GB,时长为90分钟(5400秒), 那么它的码率(视频+音频)为:

// 10 x 1024 x 8 / 5400 = 15Mbps

// 例:有一个1.5小时(5400秒)的影片,希望转换后文件大小刚好为700M

// 计算方法如下:

// 700×8÷5400×1024≈1061Kbps

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* Created by 天明
* Date: 2022/3/29
* Time: 5:43 下午
* Description:
*/
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath('/Applications/ffmpeg');
 
class Then {
constructor() {
}
static init() {
new Promise((resolve, reject) => {
console.log('获取大小和时长');
resolve()
}).then(_ => {
return new Promise((resolve, reject) => {
const Flow = ffmpeg('test.mp4').size('1280x720')
.videoBitrate('24000') //24M
.inputFPS(24)
.audioBitrate('128k').autopad(true, 'white')
.on('progress', (progress) => {
console.log('进度: ' + progress.percent + '% done');
})
.on('error', (err) => {
console.error('出现错误');
reject(err)
}).on('end', () => {
console.log('转码完成');
resolve();
});
Flow.output('out.mp4').run();
})
}).then(() => {
console.log('加水印开始');
return new Promise((resolve, reject) => {
const Flow = ffmpeg('out.mp4').input('logo.png')
.inputOptions([
'-filter_complex',
'overlay=10:10'
])
.on('progress', (progress) => {
console.log('进度: ' + progress.percent + '% done');
}).on('error', (err) => {
console.error('出现错误:');
reject(err)
}).on('end', () => {
console.log('转换完成');
resolve();
})
Flow.output('out2.mp4').run();
});
}).then(() => {
console.log('转码结束')
}).catch(err => {
console.error(err)
})
}
static bitRate() {}
}
 
Then.init()

 

这段记录了视频转码和添加水印的流程!

关于 安装 ffmpeg 流程

首先我们下载到服务器

https://johnvansickle.com/ffmpeg/

在列表中选择适合自己的版本,鼠标右键,复制链接地址。这里我直接选择了amd64的最新版本,复制到的下载地址是https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz。
打开Linux中要安装ffmpeg的目录,使用wget命令下载文件:
wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz。

可以看到下载完成的文件后缀名为 .tar.xz ,执行对应解压命令解压文件:

xz -d ffmpeg-git-amd64-static.tar.xz

再解压

tar -xvf ffmpeg-git-amd64-static.tar

解压完成后进入解压出来的这个目录ffmpeg-git-20190424-amd64-static/:

当然,如果想要ffmpeg命令全局可用,可以在bin目录加个链接。比如,分别执行如下命令,即可在:/usr/bin目录下创建ffmpeg和ffprobe软链接。

cd /usr/bin
ln -s /data/software/ffmpeg-git-20190424-amd64-static/ffmpeg ffmpeg
ln -s /data/software/ffmpeg-git-20190424-amd64-static/ffprobe ffprobe

这样在其他目录也都可以直接使用 ffmpeg 和 ffprobe 而不用加目录前缀了。

记录一个比较好用的 nodejs 压缩与解压包

2022-03-04admin阅读(160)评论(0)

compressing

可以很便捷的压缩与解压文件与目录!

配合

archive

强大压缩能力, 能解决不少问题

使用方式: 压缩与解压

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const compressing = require('compressing');
 
// compress a file
compressing.gzip.compressFile('file/path/to/compress', 'path/to/destination.gz')
.then(compressDone)
.catch(handleError);
// compress a file buffer
compressing.gzip.compressFile(buffer, 'path/to/destination.gz')
.then(compressDone)
.catch(handleError);
// compress a stream
compressing.gzip.compressFile(stream, 'path/to/destination.gz')
.then(compressDone)
.catch(handleError);

 

 

Git忽略规则(.gitignore配置)不生效原因和解决

2022-01-07admin阅读(167)评论(0)

第一种方法:

.gitignore中已经标明忽略的文件目录下的文件,git push的时候还会出现在push的目录中,或者用git status查看状态,想要忽略的文件还是显示被追踪状态。
原因是因为在git忽略目录中,新建的文件在git中会有缓存,如果某些文件已经被纳入了版本管理中,就算是在.gitignore中已经声明了忽略路径也是不起作用的,
这时候我们就应该先把本地缓存删除,然后再进行git的提交,这样就不会出现忽略的文件了。

解决方法: git清除本地缓存(改变成未track状态),然后再提交:
[root@kevin ~]# git rm -r –cached .
[root@kevin ~]# git add .
[root@kevin ~]# git commit -m ‘update .gitignore’
[root@kevin ~]# git push -u origin master

需要特别注意的是:
1).gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。
2)想要.gitignore起作用,必须要在这些文件不在暂存区中才可以,.gitignore文件只是忽略没有被staged(cached)文件,
对于已经被staged文件,加入ignore文件时一定要先从staged移除,才可以忽略。

第二种方法:(推荐)
在每个clone下来的仓库中手动设置不要检查特定文件的更改情况。
[root@kevin ~]# git update-index –assume-unchanged PATH //在PATH处输入要忽略的文件

在使用.gitignore文件后如何删除远程仓库中以前上传的此类文件而保留本地文件
在使用git和github的时候,之前没有写.gitignore文件,就上传了一些没有必要的文件,在添加了.gitignore文件后,就想删除远程仓库中的文件却想保存本地的文件。这时候不可以直接使用”git rm directory”,这样会删除本地仓库的文件。可以使用”git rm -r –cached directory”来删除缓冲,然后进行”commit”和”push”,这样会发现远程仓库中的不必要文件就被删除了,以后可以直接使用”git add -A”来添加修改的内容,上传的文件就会受到.gitignore文件的内容约束。

额外说明:git库所在的文件夹中的文件大致有4种状态

Untracked:

未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.

Unmodify:
文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改,
而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件

Modified:
文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态,
使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改

Staged:
暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态.
执行git reset HEAD filename取消暂存, 文件状态为Modified

Git 状态 untracked 和 not staged的区别
1)untrack 表示是新文件,没有被add过,是为跟踪的意思。
2)not staged 表示add过的文件,即跟踪文件,再次修改没有add,就是没有暂存的意思

 

转载来自: https://www.cnblogs.com/rainbowk/p/10932322.html

微信小程序插件入门教程

2021-12-16admin阅读(217)评论(0)

首先: 为什么我们要开发微信小程序插件?

微信小程序的主包大小只有 2M, 即使使用分包, 一些公共的插件也会占用主包的大小,  因此, 我们可以把一些公共组件或者页面, 以插件的形式作为一个独立的形式来加载, 既可以减少小程序包体积, 也可以用于多小程序页面复用, 下面简单做个小程序插件的开发入门教程!

首先, 我们需要在公众号的后台开通小程序插件!

iShot2021-12-16 18.24.26

开通之后, 打开开发者工具, 新建一个插件(这里需要注意, 小程序插件的 Appid 和 宿主小程序 Appid 是一样的)!

iShot2021-12-16 18.11.58

 

新建成功后, 直接生成了一个 DEMO 示例!

iShot2021-12-16 18.27.45

开发插件的话, 我们直接在 plugin 目录开发, 可以直接在 miniprogram 目录进行调试!

我们可以看到 miniprogram/app.json

1
2
3
4
5
6
7
8
9
10
11
12
{
  "pages": [
    "pages/index/index"
  ],
  "plugins": {
    "hello-plugin": {
      "version": "dev",
      "provider": "wx9f77d65eb4eff65b"
    }
  },
  "sitemapLocation": "sitemap.json"
}

直接在当前项目里调试插件, version 是 dev;

插件开发目录里面的文件, 我们打开 plugin/plugin.json

1
2
3
4
5
6
7
8
9
10
11
{
  "publicComponents": {
    "hello-component": "components/hello-component"
  },
  "pages": {
    "hello-page": "pages/hello-page",
    "test": "pages/test",
    "tianming": "pages/tianming"
  },
  "main": "index.js"
}

这个配置文件中,

publicComponents 是对外可使用的组件列表

pages 是可以跳转的页面

我们默认生成的项目, 预的是 miniprogram 目录里面的页面, 默认已经在 miniprogram/app.json 里面引入了插件!

因此若要打开 组件里面的 test 页面,

则直接:

1
2
3
<navigator id="nav" url="plugin://hello-plugin/test">
  打开插件页面
</navigator>

若要使用里面的 JS 方法, 则直接使用

1
2
const plugin = requirePlugin('hello-plugin')
plugin.sayHello()

若要在其他小程序里面使用正在开发的插件, 我们首先需要将插件上传!

iShot2021-12-16 18.41.31

上传成功后, 我们需要复制插件 ID: 46e9a7f122f768d606b170280d920a00

然后正常在自己小程序里面引入插件, 但是配置需要注意:

版本号是: dev-ID

provider: 插件的 appid

1
2
3
4
5
6
"plugins": {
    "vr29": {
      "version": "dev-74c62c62760b3521eedceb07a893ebc8",
      "provider": "wxefe655223916819e"
    }
  }

使用方式和前面讲到的没有区别!

若添加后遇到 插件未授权

iShot2021-12-16 19.28.11

先点击添加插件, 然后去后台审核即可!

若不想每次添加:

可以再小程序后台插件管理页面修改权限:

iShot2021-12-16 19.29.51

1
<navigator id="nav" url="plugin://vr29/test">天明测试</navigator>

 

打开结果如下:

iShot2021-12-16 19.34.39

这样, 我们发布的插件里面的页面在其他小程序里打开成功了!

小程序插件使用文档: https://developers.weixin.qq.com/miniprogram/dev/framework/plugin/using.html

小程序插件开发文档: https://developers.weixin.qq.com/miniprogram/dev/devtools/plugin.html

 

 

 

 

 

javascript中new URL()属性,轻松解析url地址

2021-09-05admin阅读(407)评论(0)

1.首先写一个假的地址(q=URLUtils.searchParams&topic=api)相当于当前的window.location.href

1
2
3
4
5
6
7
8
9
10
11
const urlParams = new URL(window.location.href);
urlParams.searchParams.has("topic") === true; // true
urlParams.searchParams.get("topic") === "api"; // true
urlParams.searchParams.getAll("topic"); // ["api"]
urlParams.searchParams.get("foo") === ""; // true
urlParams.searchParams.append("topic", "webdev");
urlParams.searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
urlParams.searchParams.set("topic", "More webdev");
urlParams.searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
urlParams.searchParams.delete("topic");
urlParams.searchParams.toString(); // "q=URLUtils.searchParams"

是不是很好用?参考(https://developer.mozilla.org/zh-CN/docs/Web/API/URLSearchParams#%E7%A4%BA%E4%BE%8B)

转载于:https://www.cnblogs.com/lanshu123/p/10668320.html

关于代码自动更新的一次实验

2021-08-14admin阅读(350)评论(0)

也是懒了, 之前 nuxt.js 的项目, 每次 build 完了之后, 都要手动把.nuxt 目录上传到 服务端执行重启, 随着项目越来越大, 编译文件上传cdn 后已经有 500 第一个了, 从本地传服务器太慢了得几分钟, 之前一直想做个自动发布 , 但是 太忙了没有做, 今天实在是忍不了了, 就简单做个自动发布,

自动上传还没有做, 后面打算依托七牛云或者 git 来做, 把资源包传上去再更新下来!

首先上传慢第一步是因为文件太多了,. 所以我们先把本地文件压缩一下: 简单实用 nodejs 做个脚本, 当然调用系统命令来压缩也是可以的!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const fs = require('fs');
const archiver = require('archiver');
const path = require('path')
const sonDir = path.resolve(__dirname,  './');
const outFile = sonDir + '/nuxt.zip';
try {
  fs.unlinkSync(outFile)
} catch (e) {}
 
let output = fs.createWriteStream(outFile);
let archive = archiver('zip', {
  zlib: {level: 9}
})
 
output.on('close', function () {
  console.log(`总共 ${archive.pointer()} 字节`)
  console.log('archiver完成文件的归档,文件输出流描述符已关闭')
})
output.on('end', function () {
  console.log('数据源已耗尽')
})
archive.on('warning', function (err) {
  if (err.code === 'ENOENT') {
    console.warn('stat故障和其他非阻塞错误')
  } else {
    throw err
  }
})
archive.on('error', function (err) {
  throw err
})
archive.pipe(output)
const appendDir = sonDir + '/.nuxt/';
console.log('appendDir', appendDir);
archive.directory(appendDir, '.nuxt', {})
archive.finalize();

压缩完成后, 本地就会多出一个 nuxt.zip, 可以实用七牛的资源公布功能把 压缩包同步上去, 再触发服务端的下载, 下载后解压, 目前还没有做, 先手动上传!

直接上传 nuxt.zip 也就是一秒钟的事情,

传完了之后我也不想手动去解压然后重启pm2 ,  简单用 php 做个本地服务端来解决吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$http = new Swoole\Http\Server('0.0.0.0', 8421);
$http->on('Request', function ($request, $response) {
  list($controller, $action) = explode('/', trim($request->server['request_uri'], '/'));
  $response->header('Content-Type', 'text/html; charset=utf-8');
  if ($controller == 'update' && $action == 'vr') {
    // 代码发布使用
    exec('unzip -o ./nuxt.zip', $return);
    sleep(1);
    exec('pm2 reload 6', $return2);
    print_r($return);
    print_r($return2);
    $response->end($return2);
  }
});
$http->start();

 

使用 pm2 启动这个 php 文件, 然后监听 8421 端口, 如果端口遇到 路径为 /update/vr 的, 就执行解压操作, 然后重启pm2

因为我服务端已经存在文件, 因此解压时候需要带 -o 覆盖文件,

然后在以后的项目里新增一个控制器, 调用本地的 127.0.0.1:8421/update/vr来执行解压重启操作,

因为我们的 8421 端口没有对外开放, 所以使用内网其他服务器来调起服务器, 这样也比较安全一些~

可以使用 php 在本地起一个 curl 来访问一下新增的控制器,触发解压, 当然也可直接使用 node, 因为前端项目, 所以用 node 吧~

1
2
3
4
const axios = require('axios')
axios.get('https://嘻嘻嘻嘻嘻嘻.html?key=xxx').then(res=>{
  console.log(res.data)
})

大概如下, 本地调用一下, 加了个 key, 防止被恶意使用,

这样我们本地执行这个文件, 就可以触发服务端的代码解压和更新操作了~

最终的 script 如下:

1
2
3
4
5
6
7
8
9
10
"scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "zip": "node zip.js",
    "deploy": "node deploy.js",
    "build-upload": "nuxt build && node upload.js && node zip.js",
    "start": "nuxt start",
    "upload": "node upload.js",
    "generate": "nuxt generate"
  },

 

关于 PC 端微信小程序开发的尝试

2021-07-15admin阅读(894)评论(0)

在之前, 自动 Pc 端电脑可以打开小程序之后, 就留意到了 Pc 端使用小程序的场景, 奈何之前一直体验不好, 近期, 又做了一次尝试, 感觉比之前好多了,

首先在使用之前, 我们需要先 在 pages.json 里面加入配置项让小程序支持横屏显示, 否则就一个手机这么大的区域也不好操作~

"resizable": true 可使小程序在PC上横屏窗口展示

“pageOrientation”: “auto”

手机端设置 "pageOrientation": "auto" 或 iPad 上设置 "resizable": true 时会允许屏幕旋转,此时使用 Page 的 onResize 事件或者 wx.onWindowResize 方法可对该操作进行监听,进而判断是使用横屏还是竖屏布局。

如果是 uniapp 开发, 则需要在: manifest.json 里配置

1
2
3
4
5
6
"mp-weixin": {
     /* 微信小程序特有相关 */
    "usingComponents": true,
    "resizable": true,
    "pageOrientation": "auto"
},

配置成功之后, 我们在预览打开小程序就可以看到横屏

具体文档介绍: https://developers.weixin.qq.com/miniprogram/dev/framework/ability/adapt.html

小程序也新增了

match-media

属性

media query 匹配检测节点。可以指定一组 media query 规则,满足时,这个节点才会被展示。

通过这个节点可以实现“页面宽高在某个范围时才展示某个区域”这样的效果。

具体文档: https://developers.weixin.qq.com/miniprogram/dev/component/match-media.html

我们也可以简单的使用媒体查询加match-media来做个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style>
@media (min-width: 480px) {
  .content {
    width: 100%;
    height: 100vh;
    background: #dd524d;
  }
}
@media (max-width: 480px) {
  .content {
    width: 100%;
    height: 100vh;
    background: #007aff;
  }
}
</style>

XHTML
1
2
3
4
5
6
7
8
9
10
11
<template>
  <view class="content" @click="toView">
    <match-media min-width="300" max-width="600">
      <view>当页面宽度在 300 ~ 500 px 之间时展示这里</view>
    </match-media>
    <match-media min-height="400" orientation="landscape">
      <view>当页面高度不小于 400 px 且屏幕方向为纵向时展示这里</view>
    </match-media>
    <h1>当前 UA: {{ua}}</h1>
  </view>
</template>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
  export default {
    data() {
      return {
        ua: "",
      };
    },
    components: {},
    methods: {
      toView() {
        wx.navigateTo({
          url: "/pages/index/web",
        });
      },
    },
    onLoad() {
      this.ua = wx.getSystemInfoSync().platform;
    },
  };
</script>

之后我们在机型里面选择大于 480px 的宽度,则显示不一样颜色

iShot2021-07-15 16.42.40

我们启动真机调试, 选择电脑端调试,即可看到正常显示的界面了;

通过这些, 我们就可以和正常开发 h5 的响应式网页一样正常开发小程序了~

主要注意:

小程序如何判断是 PC 平台?
通过 getSystemInfo 官方接口(platform 是 windows)
通过 UA(PC UA 包含 MiniProgramEnv/Windows)

这里实际上, 如果是 mac 电脑, 则 platform 是 mac

记录一次使用 uniapp 结合微信原生 api 封装弹窗组件方法

2021-07-13admin阅读(1190)评论(0)

产生原因:

一直以来, 使用 uniapp 封装组件, 然后通过使用 props 来给组件传参控制组件内容, 或者使用 slot , 但是比如页面有多个弹窗, 则需要修改数据然后再 更新显示隐藏, 如果是在某个流程里面, 比如 常见的 Confirm 类, 则需要设置组件的回调来接受事件, 其实是比较麻烦的, 今天经过一系列的分析, 终于想到了一个方案,

主要用到的 api 就是微信的 selectComponent()

大概思路就是,. 我正常弹窗, 然后在 弹窗 js 里设置回调, 这样我就不用 在组件里去接受用户的选择结果事件,

首先是弹窗的组件, 里面定义弹窗的一些事件和简单的界面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<style scoped>
.page {
  margin: 50px;
}
</style>
<template>
  <div class="page" v-if="openPopup">
    <h1>{{content}}:{{test}}</h1>
    <button @click="okay">确定</button>
    <button @click="cancel">取消</button>
  </div>
</template>
 
<script>
/**
* Created by iyahe@qq.com
* Date: 2021/7/13
* Time: 3:53 下午
* Description:
*/
export default {
  name: "popup",
  mixins: [],
  props: {},
  data() {
    return {
      content: '我是组件',
      openPopup: false,
      onConfirm:function (){},
      onCancel: function (){},
      test: ''
    }
  },
  computed: {},
  watch: {},
  components: {},
  methods: {
    close () {
      // this.$set(this,'test', Math.random())
      this.$mp.component.setData({
        openPopup: false
      })
    },
    okay (e) {
      // 不知道什么原因, 这里直接给 onConfirm 赋值, 第一次会无法更新数据,所以才用原生方法用 setData 赋值
      const { onConfirm } = this.$mp.component.data
      this.close()
      onConfirm(e);
    },
    cancel(e){
      // 同上
      const { onCancel } = this.$mp.component.data
      this.close()
      onCancel(e);
    }
  },
  created() {},
  mounted() {}
}
</script>

然后是我们的弹窗处理类, 里面用来处理弹窗的赋值

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Created by 天明
* Date: 2021/7/13
* Time: 4:06 下午
* Description:
*/
export default {
alert(message) {
const page = getCurrentPages();
// 如果有多个弹窗, 这个 #popup 可以当做参数传入进来,
const popup = page[0].selectComponent('#popup')
return new Promise((resolve, reject) => {
popup.setData({
'content': message,
'onConfirm': (e) => {
resolve(e)
},
'onCancel': (e) => {
reject(e)
},
'openPopup': true
});
})
}
};

 

最后使我们使用的页面里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<style scoped>
.page {
  margin: 50px;
}
</style>
<template>
  <div class="page" v-if="openPopup">
    <h1>{{content}}:{{test}}</h1>
    <button @click="okay">确定</button>
    <button @click="cancel">取消</button>
  </div>
</template>
 
<script>
/**
* Created by iyahe@qq.com
* Date: 2021/7/13
* Time: 3:53 下午
* Description:
*/
export default {
  name: "popup",
  mixins: [],
  props: {},
  data() {
    return {
      content: '我是组件',
      openPopup: false,
      onConfirm:function (){},
      onCancel: function (){},
      test: ''
    }
  },
  computed: {},
  watch: {},
  components: {},
  methods: {
    close () {
      this.$set(this,'test', Math.random())
      this.$mp.component.setData({
        openPopup: false
      })
    },
    okay (e) {
      // 不知道什么原因, 这里直接给 onConfirm 赋值, 第一次会无法更新数据,所以才用原生方法用 setData 赋值
      const { onConfirm } = this.$mp.component.data
      this.close()
      onConfirm(e);
    },
    cancel(e){
      // 同上
      const { onCancel } = this.$mp.component.data
      this.close()
      onCancel(e);
    }
  },
  created() {},
  mounted() {}
}
</script>

 

经过简单的扩展后, 就可以愉快的使用了,

再也不用 比如用户点了确认, 然后 this.$emit(‘okay’,xxx), 父组件 接收 okay 的回调,再去处理业务逻辑了,

现在直接可以

1
2
3
4
5
message.alert('你好呀, 我是传入的内容').then(_=>{
  // 点了确认后的业务逻辑
}).catch(_=>{
  // 点了取消后的业务逻辑
})

 

vue2 和 vue3 有哪些区别

2021-05-14admin阅读(467)评论(0)

总结出一些基本的区别

Vue3的新特性,如下:

  • 速度更快
  • 体积减少
  • 更易维护
  • 更接近原生
  • 更易使用

vue3相比vue2

  • 重写了虚拟Dom实现
  • 编译模板的优化
  • 更高效的组件初始化
  • undate性能提高1.3~2倍
  • SSR速度提高了2~3倍

compositon Api

  • 可与现有的Options API一起使用
  • 灵活的逻辑组合与复用
  • Vue3模块可以和其他框架搭配使用

Vue 3 中需要关注的一些新功能包括:

  • framents
  • Teleport
  • composition Api
  • createRenderer

framents

在 Vue3.x 中,组件现在支持有多个根节点

Teleport
Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术,就有点像哆啦A梦的“任意门”

在vue2中,像 modals,toast 等这样的元素,如果我们嵌套在 Vue 的某个组件内部,那么处理嵌套组件的定位、z-index 和样式就会变得很困难
通过Teleport,我们可以在组件的逻辑位置写模板代码,然后在 Vue 应用范围之外渲染它

1
2
3
4
5
6
7
<button @click="showToast" class="btn">打开 toast</button>
<!-- to 属性就是目标位置 -->
<teleport to="#teleport-target">
    <div v-if="visible" class="toast-wrap">
        <div class="toast-msg">我是一个 Toast 文案</div>
    </div>
</teleport>

其他小改变

destroyed 生命周期选项被重命名为 unmounted

beforeDestroy 生命周期选项被重命名为 beforeUnmount

[prop default工厂函数不再有权访问 this 是上下文

自定义指令 API 已更改为与组件生命周期一致

data 应始终声明为函数

来自 mixin 的 data 选项现在可简单地合并

attribute 强制策略已更改

一些过渡 class 被重命名

组建 watch 选项和实例方法 $watch不再支持以点分隔的字符串路径。请改用计算属性函数作为参数。

<template> 没有特殊指令的标记 (v-if/else-if/else、v-for 或 v-slot) 现在被视为普通元素,并将生成原生的 <template> 元素,而不是渲染其内部内容。

在Vue 2.x 中,应用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板/渲染选项,则最终编译为模板)。Vue 3.x 现在使用应用容器的 innerHTML,这意味着容器本身不再被视为模板的一部分。

vue 如何封装一个 input 组件

2021-05-14admin阅读(542)评论(0)

首先我们需要知道:

v-model实际上只是一个语法糖:

<input v-model=”password”>

作用与以下相似:

<input type=”text” :value=”password” @input=”password=$event.target.value”>

也就是通过v-model传递的值,最终是传递给了子组件props中value属性,子组件修改value值需要通过触发input事件并传递需要修改的值给父组件。

如果知道了这个, 那我们封装一个 简单的input 组件就很简单了~

父组件

1
2
<aaa v-model="vvvalue" />
<div class="p">{{ vvvalue }}</div>

子组件

1
<input @input="$emit('input', $event.target.value)" type="text" />

  • 1
  • 2
  • 3
  • 4
  • ...
  • 下一页
  • 共 13 页
关于我

小天明 北京·朝阳 前端搬砖工程师

碎碎念):(来自公众号)

热门文章

  • 踩坑记录——iphone上safari开启隐身模式时localStorage变为只读-雅荷心语博客踩坑记录——iphone上safari开启隐身模式时localStorage变为只读2017-02-21评论(4)
  • 程序员是怎样一群人-雅荷心语博客程序员是怎样一群人2015-12-08评论(3)
  • 百度你个大毒瘤 - 吐糟博客这几天打不开事情-雅荷心语博客百度你个大毒瘤 – 吐糟博客这几天打不开事情2015-12-28评论(2)
  • call_user_func_array 这个函数什么时候用-雅荷心语博客call_user_func_array 这个函数什么时候用2016-09-02评论(2)
  • PHP 非对称加密 openssl 加密及解密方法-雅荷心语博客PHP 非对称加密 openssl 加密及解密方法2016-05-17评论(2)
2022年5月
一 二 三 四 五 六 日
« 三    
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

最新评论

  • 前端小武 5年前 (2017-04-06)说:
    我看到了layer
  • 丁艳平 5年前 (2017-03-03)说:
  • Dawn 6年前 (2016-09-16)说:
    call_user_func_array最后的例子是错哦,你用bc方法去调用类里 另外一个方法就知道问题所在了。情况1.调用非静态方法 第一个参数应该传[类的实例,调用方法] (既然有类实例了直接-&
  • Dawn 6年前 (2016-06-21)说:
    tp框架设置了全局捕获异常的,这也没什么。坑的是 他捕获了异常。然后全部返回404。。。不知道的 还以为自己网站被删除了
  • Dawn 6年前 (2016-05-17)说:
    构造函数里的判断 用异常机制可能更好一些

左邻右舍

  • Brian's Blog
  • 易水寒
  • 楼教主
  • 贤心
  • 阿米龙

雅荷心语博客 -心之所向便是光

联系我们关于我们

© 2022 雅荷心语博客   网站地图

emlogdux_heademlogdux_footer