一、人脸识别的实现
在原来的项目中使用了layui和jquery配合ccv.js和face.js实现了人脸识别
使用vue迭代的时候对于这部分代码还是一知半解
getCompetence() {
//必须在model中render后才可获取到dom节点,直接获取无法获取到model中的dom节点
this.$nextTick(() => {
const _this = this;
this.open = false; //切换成关闭摄像头
this.thisCancas = document.getElementById("canvasCamera");
this.thisContext = this.thisCancas.getContext("2d");
this.thisVideo = document.getElementById("videoCamera");
// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
// 使用getUserMedia,因为它会覆盖现有的属性。
// 这里,如果缺少getUserMedia属性,就添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先获取现存的getUserMedia(如果存在)
let getUserMedia =
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.getUserMedia;
// 有些浏览器不支持,会返回错误信息
// 保持接口一致
if (!getUserMedia) {
return Promise.reject(
new Error("getUserMedia is not implemented in this browser")
);
}
// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
};
}
const constraints = {
audio: false,
video: {
width: _this.videoWidth,
height: _this.videoHeight,
transform: "scaleX(-1)",
},
};
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
// 旧的浏览器可能没有srcObject
if ("srcObject" in _this.thisVideo) {
_this.thisVideo.srcObject = stream;
} else {
// 避免在新的浏览器中使用它,因为它正在被弃用。
_this.thisVideo.src = window.URL.createObjectURL(stream);
}
_this.thisVideo.onloadedmetadata = function (e) {
_this.thisVideo.play();
};
})
.catch((err) => {
this.$message.warning("没有开启摄像头权限或浏览器版本不兼容");
});
});
},
要想使用浏览器调用摄像头的话 网络传输协议必须是https
https和http的区别
a 、http
超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法。
HTTP特点:
无状态:协议对客户端没有状态存储,对事物处理没有“记忆”能力,比如访问一个网站需要反复进行登录操作
无连接:HTTP/1.1之前,由于无状态特点,每次请求需要通过TCP三次握手四次挥手,和服务器重新建立连接。比如某个客户机在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户的请求,所以每次需要重新响应请求,需要耗费不必要的时间和流量。
基于请求和响应:基本的特性,由客户端发起请求,服务端响应
简单快速、灵活
通信使用明文、请求和响应不会对通信方进行确认、无法保护数据的完整性
b 、https
《图解HTTP》这本书中曾提过HTTPS是身披SSL外壳的HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。
PS:TLS是传输层加密协议,前身是SSL协议,由网景公司1995年发布,有时候两者不区分。
HTTPS特点:
- 内容加密:采用混合加密技术,中间者无法直接查看明文内容
- 验证身份:通过证书认证客户端访问的是自己的服务器
- 保护数据完整性:防止传输的内容被中间人冒充或者篡改
二、项目上线之后存在一刷新页面就发生404页面跳转的问题
这个原因的本质是 history 和 hash 的区别
以 www.louhc.com/jichu/123 为例子(123为变量)直观上的区别是:
hash模式下,在浏览器地址栏里面会有: www.louhc.com/#/jichu/123 这种带 # 号的情况,视觉上不太美观。
history模式下,地址栏为:www.louhc.com/jichu/123 不会出现带#的情况 。致命区别
hash模式下,上线之后不会出现问题。
history 模式下,会出现一个致命的BUG,在服务器上面上线之后,点击页面跳转没有问题,但是一旦点击刷新页面会出现404错误,原因是history模式下刷新界面,就等同于向服务器直接请求: www.louhc.com/jichu/123。但是在服务器后端的路径配置中压根就没有 /jichu/123 ,所以后端匹配不到相应的值,就会返回404错误,。有的朋友就会有疑虑,为什么在vue项目开发的时候不会出现这种问题呢?因为在vue项目开发的时候是访问自己的8080服务器,后端有进行处理,在刷新界面后找不到相对路径时,会重新渲染index.html界面,把路由的控制权交给前端,然后前端负责路由的匹配,在找到符合/jichu /123 这种格式的路由后,就会匹配成功。从而达到页面正常显示的情况.。
所以在线上遇到这种情况下,我们需要后端进行相应的配置处理,在匹配不到路径的情况下重新渲染index.html 文件。
警告
需要注意的是:您的服务器将不再报告404错误,因为所有未找到的路径现在都可以处理您的index.html文件。要解决此问题,您应该在Vue应用程序中实施一个包罗万象的路由以显示404页面:
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '*', component: NotFoundComponent }
]
})
或者,如果您使用的是Node.js服务器,则可以通过使用服务器端的路由器来匹配输入URL来实现后备,如果没有路由匹配,则以404进行响应。查看Vue服务器端渲染文档以获取更多信息。
三、vue中播放音频无反应
一定要先将存在的音频文件导入进来,之后在进行赋值audio标签src赋值的操作,直接给到路径是无法播放的,具体原因不知。在下实在是才疏学浅。
四、el-ui中信息提示框的api
孤陋寡闻的我在处理需求的时候 是希望我每次的提示框都不要自动消失。并且加上关闭按钮
showClose 就是展示关闭按钮 下面依次 提示信息 提示类型 提示框存在的时间
五、节流和防抖在vue中的使用
此处用到了节流函数 用户一段时间内只可以发起一次操作,又多添加了控制按钮禁用的变量,让其变的更加合理一点
六、自定义指令全局的创建
在vue实例中使用该属性申明自定义指令,在directivs中申明自定义指令有两种方法,一种就是函数的形式(更加简单便捷),另一种就是使用对象的形式(能够定义更加精细)
1、函数形式:
参数:
(1)第一个参数为element:实质上为使用该属性的真实DOM
(2)第二个参数为binging:是一个对象,包含value属性值等;
何时调用:
(1)指令与元素成功绑定时调用:实质上就是对象形式的bing函数;
(2)令所在模板(例:id为root中)发生重新解析的时:实质上就是对象形式的update函数;
示例代码如下:
<div id="root">
<h2>当前的n值为:<span v-text="n"></span></h2>
<h2>放大10倍的n值为:<span v-big="n"></span></h2>
<button @click="n++">点我实现n+1</button>
</div>
new Vue({
el:'#root',
data:{
n:1
},
// 用于放置自定义指令:自定义指令可以写为函数形式,也可以写为对象形式
directives:{
// element是使用该属性的真实DOM(span),binding是一个对象(包含value属性值(n=1)等)
big(element,binding){
element.innerText = binding.value*10;
}
}
})
2、对象形式
(1)bind函数
指令与元素成功绑定时调用(2)inserted函数
指令所在元素被插入页面时调用,相比较于函数形式新增的功能;(3)update
指令所在模板被重新解析时调用,均存在两个参数:element、binding;
<div id="root">
<h2>当前的n值为:<span v-text="n"></span></h2>
<button @click="n++">点我实现n+1</button>
<input type="text" v-fbind="n">
</div>
new Vue({
el:'#root',
data:{
n:1
},
// 用于放置自定义指令:自定义指令可以写为函数形式,也可以写为对象形式
directives:{
fbind:{
//指令与元素成功绑定时调用
bind(element,binding){
element.value = binding.value
},
// 指令所在元素被插入页面时调用
inserted(element,binding){
element.focus()
},
// 指令所在模板被重新解析时调用
update(element,binding){
element.value = binding.value
}
}
}
})
注意:
a、自定义指令在使用时需要加上v-,在定义时不需要加上v-;b、当存在多个单词组成时:在使用时需要加上-分隔(v-big-number);在定义时需要加上引号还原他的原来形式('big-number':function(element,binding){ ... })//function可以省略
c、使用大写形式时会自动转换为小写,所以应该都使用小写形式防止混淆;
d、定义在directives中的自定义属性的this值都是window;
二、全局自定义指令
定义在directives:{}中的都是局部自定义指令,全局自定义指令的定义方式与过滤器类似,定义在new Vue的前面;1、对象式:
Vue.directives('big',{ ... }) //第一个参数为对象名,第二个参数为对象内容2、函数式:
Vue.directives('big',function(element,binding){ ... }) //第一个参数为函数名,第二个参数为函数体
七、vue.config.js的文件配置
配置脚手架(vue-cli)可以解决很多细节问题,比如设置打包文件的输出目录名,打包引入资源的初始路径、配置本地服务器、配置webpack等。
1、生成脚手架项目
1.npm install -g @vue/cli // 全局安装vue-cli
2.vue create xxx // 在当前目录下创建xxx项目
脚手架项目创建好之后项目目录中是没有vue.config.js文件的,我们需要在项目根路径下手动创建vue.config.js
2、vue.config.js基础配置代码
module.exports = {
publicPath: "./", // 公共路径 默认为"/",建议使用"./"相对路径
devServer: { // 本地服务器配置(npm run serve)
port: 8080, // 端口
host: "localhost", // 域名
https: false, // 是否开启https
open: true // 是否在开启服务器后自动打开浏览器访问该服务器
},
lintOnSave: false, // 取消lint语法检测,此处可不配置
outputDir:"dist", // build打包输出目录
assetsDir:"assets", // 静态文件输出目录,基于dist
indexPath: "index.html", // 输出html文件名
productionSourceMap: false, // 取消.map文件的打包,加快打包速度
configureWebpack: (config) => {
// process.env为环境变量,分别对应.env.development文件和.env.production文件 此处表示加快开发环境打包速度
if (process.env.NODE_ENV !== 'production') return;
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true; //生产环境去掉console.log
return { // 此处配置webpack.config.js的相关配置
plugins: [],
performance: {}
};
}
};
publicPath --- 公共路径配置项,默认为'/',此配置项是影响打包生成文件的引入资源公共路径的
publicPath: "/wang-xiao",
devServer ---本地服务器配置
devServer: { // 本地服务器配置(npm run serve)
port: 8080, // 端口
host: "localhost", // 域名
https: false, // 是否开启https
open: true // 是否在开启服务器后自动打开浏览器访问该服务器
},
这个配置项所影响的只有本地服务器,也就是用yarn serve 打开的webpack服务器的配置项。
lintOnSave ---lint 语法检测
lintOnSave:false
这里配置true时打包后会严格进行lint语法检测,这里通常配置为false。
outputDir ---build打包输出目录
outputDir:'wang-xiao'
就是打包的目录名,默认为dist
assetsDir --- 静态文件输出目录,基于dist
assetDir :'assets'
就是存放一些视频、图片、音频、icon、字体 的文件
indexPath --- 打包生成的html文件名
indexPath:'index.html'
productionSourceMap ---取消.map文件的打包
productionSourceMap: false,
加快打包速度
configureWebpack: (config) => { return {…} } ---在…中配置webpack配置项,相当于webpack.config.js
在vue-cli项目中webpack.config.js文件是无效的,但是可以在vue.config.js中的configureWebpack中进行webpack配置,下面展示一下我配置过的一个项目
module.exports = {
publicPath: "/face-client", // 公共路径 默认为"/",建议使用"./"相对路径
outputDir: "face-client",
pages:{
'index.html':{
template:'./public/index.html',
entry:'./src/main.js',
title:'青岛理工大学新生人脸识别系统',
filename:'index.html'
}
},
devServer: {
// 本地服务器配置(npm run serve)
// port: 8080, // 端口
// host: "0.0.0.0", // 域名
https: true, // 是否开启https
open: true, // 是否在开启服务器后自动打开浏览器访问该服务器
},
lintOnSave: false, // 取消lint语法检测,此处可不配置
productionSourceMap: false, // 取消.map文件的打包,加快打包速度
configureWebpack: (config) => {
// process.env为环境变量,分别对应.env.development文件和.env.production文件 此处表示加快开发环境打包速度
if (process.env.NODE_ENV !== "production") return;
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true; //生产环境去掉console.log
return {
// 此处配置webpack.config.js的相关配置
plugins: [],
performance: {},
};
},
};
创建vue空文件下方style标签报错
在下方小齿轮的设置中搜索eslint.enable,找到相对应的选项
取消勾选就可以解决问题
less报错问题
当我们在style中希望使用到less时,因为less并不能被webpack识别并打包,所以我们需要手动的挂载less-loder装备用来编译less中书写的css代码
npm install --save less-loader less
路由重定向
当我们的项目中使用到了vue-router来跳转页面的时候
我们需要在根app.vue中通过<router-veiw></router-vew>标签的形式占位,在router文件夹下方的.js文件中 导入我们需要用到的路由 并且通过redirect来将路由重新定向
小程序和普通网页开发的区别
运行环境的不同
网页运行在浏览器环境中
小程序运行在微信环境中
api不同
由于运行环境的不同,所以小程序中无法调用DOM和BOM的api 但是小程序中可以调用微信环境提供的各种api 例如: 地理定位 扫码 支付
开发模式不同
网页开发 浏览器+代码编辑器
小程序有自己的一套开发模式:
申请小程序开发账号
安装小程序开发者工具
创建和配置小程序项目
项目解构
1 pages用来存放所有小程序的页面
2utils用来存放工具性质的模块(例如:格式化时间的自定义模块)
3 app.js小程序项目的入口文件
4 app.json小程序项目的全局配置文件
5 app.wxss小程序项目的全局样式文件
6 project.config.json项目的配置文件
7 sitemap.json用来配置小程序及其页面是否允许被vx索引
小程序页面的组成部分
1 .js文件(页面的脚本文件 存放页面的数据 事件处理函数)
2 .json文件(当前页面的配置文件 配置窗口的外观表现等)
3 .wxml文件(页面的模板结构文件)
4 .wxss文件(当前页面的样式表文件)
$emit $on(非父子)
1.src文件夹新建common文件夹
2.common文件夹下新建bus.js文件
bus.js 写这个
import Vue from 'vue';
export default new Vue;
兄弟1 传递
<template>
<div>
第一个 给兄弟的数据是:{{ msg }}
<button @click="send">点击传递给兄弟数据</button>
</div>
</template>
<script>
import bus from "@/common/bus";
export default {
name: "HelloWorld",
data() {
return {
msg: "6666666666",
};
},
methods: {
send() {
bus.$emit("send", this.msg);
},
},
};
</script>
兄弟2 接收
<template>
<div>第二个 {{ msg }}</div>
</template>
<script>
import bus from "@/common/bus";
export default {
name: "HelloWorld",
data() {
return {
msg: "",
};
},
mounted() {
bus.$on("send", (data) => {
this.msg = data;
});
},
};
</script>