首页

js判断屏幕分辨率的代码

前端达人

一般我们可以通过下面的代码判断分辨率

复制代码 代码如下:
<script language="JavaScript">
<!-- Begin
function redirectPage() {
var wjb51=screen.width;
var hjb51=screen.height;
alert("经系统检测,你的屏幕分辨率为 " + wjb51+"*"+ hjb51 + "by 脚本之家17jquery.com");
}
// End -->
</script>

js判断浏览器分辨率

复制代码 代码如下:
<script>
function ScreenWidth(){
if (screen.width == 1440){
alert("1440*900");
}else if (screen.width == 800){
alert("800*600");
}else if (screen.width == 1152){
alert("1152*864");
}else {
alert("do not know!");
}
}
</script>
<input type="button" name="" value="fenbianli " οnclick=" ScreenWidth()"/>
内容来自17jquery

说明:这段js代码可改造一下,改为screen.width>=1024 screen.width=800两种情况

所以我选择使用下面的代码:

复制代码 代码如下:
if(screen.width>=1440){
alert('宽屏幕可以加载广告了');
//一些广告代码
}

用JS判断不同分辨率调用不同的CSS样式文件

最近看一个网站,发现显示器不同的分辨率,样式文件调用的也不一样,今天写了一个例子研究一下,
复制代码 代码如下:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<link rel="stylesheet" id="sc" type="text/css" href="css/c1.css"/>
<script type="text/javascript">
window.οnlοad=function(){
var sc=document.getElementById("sc");
var d=document.getElementById("d");
if(screen.width>1024) //获取屏幕的的宽度
{
sc.setAttribute("href","css/c2.css"); //设置css引入样式表的路径
d.innerHTML = "你的电脑屏幕宽度大于1024,我的宽度是 1200px, 背景色现在是红色。";
}
else{

sc.setAttribute("href","css/c1.css"); 17jquery.com
d.innerHTML = "你的电脑屏幕宽度小于或是等于1024,我的宽度是 960px, 背景色现在是蓝色。";
}
}
</script>
</head>
<body>
<div id="d"></div>
</body>
</html>

c1.css里面的内容

复制代码 代码如下:
*{ margin:0; padding:0;}

div{ width:960px; height:400px; margin:0 auto; background:blue; color:#ffffff;}


c2.css里面的内容

*{ margin:0; padding:0;}

div{ width:1200px; height:400px; margin:0 auto; background:red; color:#fff;}

 

分享此文一切功德,皆悉回向给文章原作者及众读者.

免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

 

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

 

Vue新建项目+git托管+初始配置+项目打包优化

前端达人

1、已全局安装vue-cli和nodejs(第一次需要)

2、利用Vue-cli创建项目

  • 打开项目所在文件夹
  • vue create ‘项目名’
  • 选择手动配置

babel:js编辑器
typeScript:超集js【需要指定数据类型】
PWA:离线可用
Linter/Formatter:约束代码规范,配合eslint
unit/e2e testing:测试
在这里插入图片描述
在这里插入图片描述

3、git远程仓库初始化(创建并添加公钥,配一次即可)

4、本地项目托管

  • 新建仓库,给仓库命名即可,无任何勾选
  • 第二次新建仓库,不需要再git全局设置
  • 已经创建了项目,进入vscode终端(管理员)(or cmd进入项目路径)
  • git init
  • 执行橙色代码(第一句表示远程仓库地址,第二句表示首次推送主分支到云端仓库,origin为云仓库别名)

在这里插入图片描述

5、项目文件夹

node_modules:放置项目依赖的地方
public:一般放置一些共用的静态资源,包括页签图标、index.html,打包上线的时候,public文件夹里面资源原封不动打包到dist文件夹里面;<%= BASE_URL %>是public所在路径,使用绝对路径

脚手架目录public和assets区别:参考链接
在这里插入图片描述

src:程序员源代码文件夹

  • assets文件夹:经常放置一些静态资源(图片),assets文件夹里面资源webpack会进行打包为一个模块(js文件夹里面)
  • components文件夹:一般放置非路由组件(或者项目共用的组件)
  • App.vue 唯一的根组件
  • main.js 入口文件【程序最先执行的文件】
  • babel.config.js:babel配置文件【翻译官:如ES6翻译成ES5,兼容好】
  • package.json:应用包配置文件;看到项目描述、项目依赖、项目运行指令【项目信息记录:‘项目身份证’】
  • package-lock.json: 包版本控制文件
  • .gitignore: git版本管制忽略的配置
  • README.md:项目说明文件

补充:通过 vue.config.js 可以修改 webpack 的默认配置
在这里插入图片描述

6、初始配置

a. 浏览器自动打开html,vue-cli-service serve --open

package.json文件中
        "scripts": {
         "serve": "vue-cli-service serve --open",
          "build": "vue-cli-service build",
          "lint": "vue-cli-service lint"
        },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

b.关闭eslint校验工具

创建vue.config.js文件:需要对外暴露
module.exports = {
   lintOnSave:false,
}
  • 1
  • 2
  • 3
  • 4

c. src文件夹的别名的设置 【@表示src文件夹,@在"node_modules","dist"不能用】

创建jsconfig.json文件
{
    "compilerOptions": {
        "baseUrl": "./",
        "paths": {
            "@/*": [
                "src/*"
            ]
        }
    },
    "exclude": [
        "node_modules",
        "dist"
    ]
}

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

7、后台项目的环境安装配置;参考黑马项目

  • MySQL数据库;
  • Node.js环境【因为后台接口依赖Node.js】 Nodejs安装及环境配置链接
  • 安装API依赖包;
  • postman测试后台项目接口:【安装与使用见连接】
    https://blog.csdn.net/m0_61843874/article/details/123324727
    https://www.bilibili.com/video/BV1hP4y177gS/?spm_id_from=333.337.search-card.all.click&vd_source=c4d71976fd97f04545873bc4552dfb71
    选择好请求方式;输入URL;body——x-www-form-urlencoded(普通形式输入请求参数)

8、清除初始静态样式,梳理app.vue根组件在这里插入图片描述

9、清除初始路由配置;清除初始的路由组件和非路由组件

新建routes.js放路由规则在这里插入图片描述

10、生成项目报告

npm run build  -- --report
  • 1

11、项目优化

  1. Vue项目在执行build命令期间中移除所有console.log 链接
  2. 通过 vue.config.js 可以修改 webpack 的默认配置
    在这里插入图片描述
  3. 为开发模式与发布模式指定不同的打包入口
    在这里插入图片描述
    3.1 打包入口的修改,可以通过 configureWebpack和 chainWebpack节点来实现:
    在这里插入图片描述
    3.2 通过 chainWebpack 自定义打包入口
    新建./src/main-prod.js和./src/main-dev.js文件;在vue.config.js进行如下配置
chainWebpack: config => {
    config.when(process.env.NODE_ENV === 'production',config=>{
      config.entry('app').clear().add('./src/main-prod.js')
    })
    config.when(process.env.NODE_ENV === 'development',config=>{
      config.entry('app').clear().add('./src/main-dev.js')
    })
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. 通过externals 加载外部 CDN 资源,对于externals中的第三方依赖包,在用到依赖包的时候,会找window全局对象上查找并直接使用现成的对象,能够让打包的项目体积更小;只有production模式才有必要配置externals节点

第一步:vue.config.js——>配置externals节点
在这里插入图片描述

//配置后的vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave:false,
  // 通过 chainWebpack 为开发模式与发布模式指定不同的打包入口
  chainWebpack: config => {
    // 发布模式
    config.when(process.env.NODE_ENV === 'production',config=>{
      config.entry('app').clear().add('./src/main-prod.js')

   <span class="token comment">// 通过externals 加载外部 CDN 资源</span>
  config<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'externals'</span><span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token literal-property property">vpe</span> <span class="token operator">:</span> <span class="token string">' Vue '</span><span class="token punctuation">,</span>
    <span class="token string-property property">'vue-router'</span><span class="token operator">:</span> <span class="token string">'VueRouter'</span><span class="token punctuation">,</span>
    <span class="token literal-property property">axios</span><span class="token operator">:</span> <span class="token string">'axios'</span><span class="token punctuation">,</span>
    <span class="token literal-property property">lodash</span><span class="token operator">:</span> <span class="token string">'_'</span><span class="token punctuation">,</span> 
    <span class="token literal-property property">echarts</span><span class="token operator">:</span> <span class="token string">'echarts'</span><span class="token punctuation">,</span>
    <span class="token literal-property property">nprogress</span><span class="token operator">:</span><span class="token string">'NProgress'</span><span class="token punctuation">,</span>
    <span class="token string-property property">'vue-quill-editor'</span><span class="token operator">:</span> <span class="token string">'VueQuillEditor'</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

config<span class="token punctuation">.</span><span class="token function">when</span><span class="token punctuation">(</span>process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">NODE_ENV</span> <span class="token operator">===</span> <span class="token string">'development'</span><span class="token punctuation">,</span><span class="token parameter">config</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
  config<span class="token punctuation">.</span><span class="token function">entry</span><span class="token punctuation">(</span><span class="token string">'app'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">'./src/main-dev.js'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

}
})

 

  • 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

第二步:导入的样式表也会被导入到输出文件中,导致体积大;临时注释掉main.prod.js中的import的VueQuillEditor样式表;进行如下配置;【注意版本号】
在这里插入图片描述
进一步添加js文件的CDN引用:
在这里插入图片描述

<!-- 富文本编辑器样式表文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.core.min.css"/>
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.snow.min.css" />
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.bubble.min.css"/>

<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/vue/2.6.14/vue.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> <span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/vue-router/3.5.1/vue-router.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span> <span class="token operator">--</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/axios/1.3.4/axios.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/lodash.js/4.17.21/lodash.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/echarts/5.4.1/echarts.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
  <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 富文本编辑器的 js 文件 <span class="token operator">--</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/quill/1.3.7/quill.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span> 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  1. .通过 CDN 优化 ElementUl 的打包

第一步:在这里插入图片描述

<!-- element-ui的样表文件-->
    <link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.13/theme-chalk/index.css" />
    <!-- element-ui的 js 又件-->
    <script src="https://cdn.staticfile.org/element-ui/2.15.13/index.js"></script>
  • 1
  • 2
  • 3
  • 4

第二步:临时注释掉
// 引入自定义插件 (封装element按需引入模块)
// import element from ‘./plugins/element’

  1. 首页内容定制(根据production模式和development模式定制)
    不同的打包环境下,首页内容可能会有所不同,我们可以通过插件的方式进行定制;
    isProd的值为True表示production模式,为FALSE表示development模式;

第一步:对vue.config.js中chainWebpack的属性进行调整:

// 通过 chainWebpack 为开发模式与发布模式指定不同的打包入口
  chainWebpack: config => {
    // 1、发布模式
    config.when(process.env.NODE_ENV === 'production',config=>{
      config.entry('app').clear().add('./src/main-prod.js')

   <span class="token comment">// 通过externals 加载外部 CDN 资源</span>
  config<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'externals'</span><span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token literal-property property">vue</span> <span class="token operator">:</span> <span class="token string">' Vue '</span><span class="token punctuation">,</span>
    <span class="token string-property property">'vue-router'</span><span class="token operator">:</span> <span class="token string">'VueRouter'</span><span class="token punctuation">,</span>
    <span class="token literal-property property">axios</span><span class="token operator">:</span> <span class="token string">'axios'</span><span class="token punctuation">,</span>
    <span class="token literal-property property">lodash</span><span class="token operator">:</span> <span class="token string">'_'</span><span class="token punctuation">,</span> 
    <span class="token literal-property property">echarts</span><span class="token operator">:</span> <span class="token string">'echarts'</span><span class="token punctuation">,</span>
    <span class="token string-property property">'vue-quill-editor'</span><span class="token operator">:</span> <span class="token string">'VueQuillEditor'</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>

  <span class="token comment">// 不同的打包环境下,首页内容可能会有所不同</span>
  <span class="token comment">// 我们可以通过插件的方式进行定制,根据isProd的值,来决定如何染页面结构,发布模式插件配置如下:</span>
  config<span class="token punctuation">.</span><span class="token function">plugin</span><span class="token punctuation">(</span><span class="token string">'html'</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">tap</span><span class="token punctuation">(</span><span class="token parameter">args</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>isProd <span class="token operator">=</span> <span class="token boolean">true</span>
    <span class="token keyword">return</span> args
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token comment">// 2、开发模式</span>
config<span class="token punctuation">.</span><span class="token function">when</span><span class="token punctuation">(</span>process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">NODE_ENV</span> <span class="token operator">===</span> <span class="token string">'development'</span><span class="token punctuation">,</span><span class="token parameter">config</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
  config<span class="token punctuation">.</span><span class="token function">entry</span><span class="token punctuation">(</span><span class="token string">'app'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">'./src/main-dev.js'</span><span class="token punctuation">)</span>

  <span class="token comment">// 不同的打包环境下,首页内容可能会有所不同</span>
  <span class="token comment">// 我们可以通过插件的方式进行定制,根据isProd的值,来决定如何染页面结构,开发模式插件配置如下:</span>
  config<span class="token punctuation">.</span><span class="token function">plugin</span><span class="token punctuation">(</span><span class="token string">'html'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">tap</span><span class="token punctuation">(</span><span class="token parameter">args</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>isProd <span class="token operator">=</span> <span class="token boolean">false</span>
    <span class="token keyword">return</span> args
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

}

 

  • 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

第二步:在public/index.html首页中,可以根据isProd的值,来决定如何染页面结构

<title><%=htmlWebpackPlugin.options.isProd?'':'dev-' %>电商后台管理系统</title>

<!-- 在production模式下isProd = true,会获取CDN里的依赖资源,development模式下isProd = false,用本地下载的依赖 -->
<% if(htmlWebpackPlugin.options.isProd){ %>
前面CDN引入的依赖资源(富文本编辑器+elemen-ui)
<% } %>


前面CDN引入的依赖资源(富文本编辑器+elemen-ui),代码如下:
<!-- 富文本编辑器样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.core.min.css"/>
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.snow.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.bubble.min.css"/>


<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/vue/2.6.14/vue.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/vue-router/3.5.1/vue-router.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/axios/1.3.4/axios.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/lodash.js/4.17.21/lodash.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/echarts/5.4.1/echarts.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
  <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 富文本编辑器的 js 文件 <span class="token operator">--</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/quill/1.3.7/quill.min.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span> 

<span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> element<span class="token operator">-</span>ui的样表文件<span class="token operator">--</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>link rel<span class="token operator">=</span><span class="token string">"stylesheet"</span> href<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/element-ui/2.15.13/theme-chalk/index.css"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> element<span class="token operator">-</span>ui的 js 又件<span class="token operator">--</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"https://cdn.staticfile.org/element-ui/2.15.13/index.js"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>

 

 

  • 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

第三步:由于对首页内容根据production模式和development模式进行了定制,需要将前面注释掉的富文本编辑器样式,以及element-ui样式引入取消注释,最终项目会根据不同模式展示首页

7. 路由懒加载
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后**[当路由被访问的时候才加载对应组件**],这样就会更加高效。

在这里插入图片描述

简化:
不需要在route.js文件 import UserDetails from ‘./views/UserDetails.vue’;直接路由懒加载
{
name:‘search’, //商品搜索
path:‘/search’,
component:()=>import(‘@/pages/Search’), [路由被访问才加载组件]

 

 

分享此文一切功德,皆悉回向给文章原作者及众读者.

免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

 

 

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

 

【Git】 取消上一次commit或push

前端达人

(转自csdn)

目录

一、取消上一次commit

方法1:使用 Git reset

方法2:使用 Git revert

方法3:使用 Git checkout

二、取消上一次push

git push --force

git reflog

git reset

git push --force

三、扩展

commit参数

--mixed

--soft

--hard

--amend


一、取消上一次commit

如果你需要取消上一次的 Git 提交,有几个不同的方法可以实现。其中包括撤消提交、提交到新的分支、使用 Git 回滚等等。

下面介绍三种方法:

方法1:使用 Git reset

使用 Git reset 命令来取消上一次提交

git reset HEAD~1

这会把 HEAD 指针移回上一个提交(HEAD~1),并清除最后一次提交的内容。

git reset HEAD^

撤回两次或者n次

git reset HEAD~2

方法2:使用 Git revert

使用 Git revert 命令来撤消上一次提交并创建一个新的提交来撤消原来的提交:

git revert HEAD

这会创建一个新的提交来撤消提交之前的更改。在命令行中输入该命令后,你需要编辑撤消的提交信息,以便 Git 创建一个新的提交。

方法3:使用 Git checkout

还可以使用 Git checkout 命令来将工作树恢复到上一次提交的状态。这将清除所有未提交的更改,所以请确保你有一个备份:

git checkout HEAD~1

这会将工作树恢复到上一次提交的状态,也就是你上一次提交之前的状态。请注意,这里的修改都将被丢弃。

无论你使用的是哪种方法,请确保在撤消提交之前首先备份你的工作。这可以帮助你避免在操作过程中意外删除无法恢复的内容。

二、取消上一次push

如果你已经push了代码,并且想要撤回这个commit,可以通过以下步骤实现:

git push --force

首先,在使用git push命令时,需要加上--force参数,强制覆盖远程仓库上已经存在的commit。命令如下:

git push --force origin <branch_name>

其中,<branch_name>表示你要撤销的分支名称。

git reflog

如果在本地仓库没有回到该commit的上一个状态,需要使用git reflog命令找到该commit的SHA-1值。命令如下:

git reflog

该命令会列出整个Git仓库的提交历史记录,包括HEAD指针所指向的提交和已经被废弃的提交。

git reset

找到要回到的某个commit的SHA-1值,然后使用如下命令回到该commit的状态:

git reset --hard <commit_SHA-1>

其中,<commit_SHA-1>表示要回到的commit的SHA-1值。

git push --force

然后使用之前的推送命令进行推送,添加--force参数,覆盖远程仓库的历史提交记录。命令如下:

git push --force origin <branch_name>

提醒:使用git push --force命令可能会导致远程仓库、其他成员的仓库和历史版本产生不可逆的影响,因此操作时需要谨慎。一般情况下,在工作流中使用git revert命令回滚某个commit,以保证版本控制的完整性和可维护性。

三、扩展

git log  查看提交日志

commit参数

--mixed

 不删除工作空间改动代码,撤销 commit,并撤销 git add . 操作

 git reset --mixed HEAD^ 效果等同 git reset HEAD^

--soft

    不删除工作空间改动代码,撤销commit,不撤销git add .

--hard

    删除工作空间改动代码,撤销commit,撤销git add .

--amend

修改注释, 进入vim编辑器, 改完:wq即可

 

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

国内 Linux 集群服务器网络差无法 Git Clone 大项目的解决办法

前端达人

GitHub 是一个软件源代码托管服务平台,Linux 上使用的大部分工具都可以在上面获得。

但是由于 GitHub 的服务器在国外,国内访问经常出现网络问题导致访问失败,尤其是使用 git clone 对 repo 进行克隆的时候,会经常出现因网络问题而克隆失败。

Linux 集群服务器的用户,在比较难实现科学上网的前提下,对大型 repo 克隆的任务显得尤为困难,而且想使用 gradle build 的话,git clone 似乎是唯一选择。

既然 git clone 一两次不成功,那我就想办法让他 clone 到成功为止,于是我就写了一个循环脚本,将它投递到计算节点上 24h 运行,直到它克隆成功才结束任务。

以克隆 GATK (repo 大小约 300mb)为例,脚本如下:

#!/bin/bash
#SBATCH --job-name=GitClone        #任务名称
#SBATCH --nodelist=litchi-0-1    #计算节点名称
#SBATCH --partition=WHEEL        #使用 WHEEL 用户组
#SBATCH --nodes=1                #使用计算节点数量
#SBATCH --ntasks=1                #使用 1 个线程
#SBATCH --mail-type=end            #任务结束时发送邮件
#SBATCH --mail-user=***@qq.com  #邮箱地址
#SBATCH --output=/home/$USER/Slurm_JobLogs/JobLog_%j_%x.log        #标准输出保存路径
#SBATCH --error=/home/$USER/Slurm_JobLogs/JobLog_%j_%x.err        #标准错误保存路径
#------------------------------------------------------------
# PRINT JOB'S INFORMATION
  source /home/$USER/.bashrc
  threads=$SLURM_NTASKS
  echo "## Job:[$SLURM_JOB_NAME]"
  echo "## Node:[$SLURM_NODELIST]"
  echo "## CPUs:[$SLURM_NTASKS]"
  echo "## Mem:[$SLURM_MEM_PER_NODE]"
  echo `date`
  echo -e $(printf -- "-%.0s" {1..100})"\n" #cut-off-line
#------------------------------------------------------------
# PATH
  repo_url="https://github.com/broadinstitute/gatk.git"
  repo_name="gatk"
#------------------------------------------------------------
# SHELL
  cd /home/$USER/Accessories/Softwares
  while true; do                #循环执行任务
    git clone $repo_url            #执行 git clone
    if [ $? -eq 0 ]; then        #如果以上命令的退出码等于 0 (任务成功)
      echo "Git clone successful!"
      break                        #则退出循环
    else                        #如果命令的退出码不等于 0 (任务失败)
      echo "Git clone failed:( Retrying..."
      rm -rf ./${repo_name}        #则删除这个repo
      sleep 1                    #睡眠 1 秒缓冲一下继续循环
    fi
  done
#------------------------------------------------------------
# JOB ENDS
  echo -e $(printf -- "-%.0s" {1..100}) #cut-off-line
  echo "## Runtime:[`sacct -j $SLURM_JOB_ID --format=Elapsed --noheader | awk '{print $1}' | sed -n '2p'`]"
  • 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

这个脚本的路径为 ~/Scripts/GitClone_GATK.sh

将任务投递到计算节点运行:

sbatch ~/Scripts/GitClone_GATK.sh
  • 1

最终,这个任务运行了 40 次,历时 13h,终于是克隆成功了!

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

GIT生成SSH公钥图文教程 转自csdn

前端达人

GIT介绍

GIT是一种分布式版本控制系统,用于追踪文件的变化和协作开发。本文将详细介绍GIT的基本架构、工作流程和常用命令,并对其优势和应用场景进行分析。

1. GIT的基本架构

GIT的基本架构由三个主要组件组成:工作区(Working Directory)、暂存区(Stage)和仓库(Repository)。

  • 工作区即本地文件夹,用于存放项目文件。
  • 暂存区是位于工作区与仓库之间的缓冲区域,用于临时存储修改。
  • 仓库则是存放项目历史记录的地方,包含项目所有文件的完整历史。

2. GIT的工作流程

GIT的工作流程通常包括以下几个步骤:

  • 初始化仓库:使用git init命令初始化一个空白的仓库。
  • 添加文件:使用git add命令将文件添加到暂存区中。
  • 提交修改:使用git commit命令将暂存区的修改提交到仓库中。
  • 分支管理:使用git branch命令创建、切换和删除分支。
  • 远程仓库:使用git remote命令管理远程仓库,并使用git pushgit pull命令与远程仓库进行数据同步。

3. GIT常用命令

以下是GIT的一些常用命令及其功能:

  • git init:初始化一个新的仓库。
  • git add <file>:将指定文件添加到暂存区中。
  • git commit -m "<message>":提交暂存区的修改并添加注释。
  • git status:显示工作区和暂存区的状态。
  • git log:显示仓库的提交历史。
  • git branch:管理分支,包括创建、切换和删除分支。
  • git checkout [branch]:切换到指定分支。
  • git merge <branch>:将指定分支合并到当前分支。
  • git remote add <name> <url>:添加远程仓库。
  • git push <remote> <branch>:将本地分支推送到远程仓库。
  • git pull <remote> <branch>:从远程仓库拉取最新代码。

4. GIT的优势

GIT具有以下几个优势:

  • 分布式:每个开发者都拥有完整的仓库副本,可以在离线环境下进行工作,并能方便地处理分支操作和合并冲突。
  • 高效性:GIT采用了快照方式保存文件,不会重复存储相同的内容,大幅节省存储空间。
  • 数据完整性:使用哈希算法确保每个文件和每次提交都有唯一的标识,可以有效避免数据损坏和篡改。
  • 可扩展性:GIT具有良好的插件和扩展支持,可以根据需求灵活地进行功能扩展。

5. GIT的应用场景

由于GIT的优势和高效性,它广泛应用于软件开发中的版本控制和协作管理。以下是几个常见的应用场景:

  • 代码版本控制:开发人员可以使用GIT来追踪和管理代码的版本变化,轻松地回退、回顾和比较代码的不同版本。
  • 多人协作开发:GIT支持跨团队和跨地域的多人协作开发,能够有效解决代码冲突,并提供完整的历史记录和审计功能。
  • 敏捷开发:GIT的分支管理和快速迭代特性非常适合敏捷开发方法,可以帮助团队快速迭代并保持项目的整洁和稳定。

综上所述,GIT作为一种强大的分布式版本控制系统,在软件开发中发挥着重要的作用。通过了解GIT的基本架构、工作流程和常用命令,开发人员可以更好地利用和实践GIT,提高代码管理和协作效率。

教程

1.下载安装git客户端

此处省略1万字,本人是通过idea开发工具下载的git.

2.鼠标右键进入,给 GIT base Here 

 

输入 生成SSH公钥命令

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

然后需要输入的地方,回车,如图所示,生成ssh公钥成功

 

在找到公钥生成的位置,打开id_rsa.pub文件,即可找到ssh公钥

 

 在git服务平台如码云、conding、github等里添加自己公钥

 

补充知识

SSH公钥是一种加密技术,用于实现安全的远程登录和文件传输。它使用非对称加密算法,将用户的公钥保存在被访问的服务器上,而私钥则由用户自己保管。

当用户要进行远程登录或文件传输时,客户端会生成一对公钥和私钥,并将公钥发送给服务器。服务器将收到的公钥存储起来。当用户进行身份验证时,服务器会向客户端发送一个随机的挑战,并使用存储的公钥对其进行加密。用户收到挑战后,使用自己保管的私钥进行解密并返回结果给服务器。如果解密结果正确,身份验证就成功了。

SSH公钥具有以下优点:

  1. 安全性:使用非对称加密算法,确保通信和数据传输的安全性。
  2. 方便性:无需记住密码,只需要保管好私钥即可。
  3. 灵活性:可以在多个终端之间共享公钥,方便用户同时访问多台服务器。
  4. 可审计性:公钥在服务器上留下痕迹,方便审计和管理。

为了确保SSH公钥的安全,用户应该妥善保管自己的私钥,并定期更新公钥,防止被恶意利用。此外,服务器管理员也应确保正确配置和管理公钥,避免安全漏洞的出现。

git入门:Linux操作系统下 git环境搭建 | 生成公私密钥

前端达人

前言

该示例是在ubuntu下完成的

 

 

一、安装 git 和 ssh

sudo apt-get install git
sudo apt-get install openssh-server

二、配置公钥

因为git和 GitHub之间是通过ssh加密传输的,因此需要配置公钥,所以需要先生成公私密钥。

命令:该邮箱是你注册GitHub的邮箱地址

ssh-keygen -t rsa -C “xxxxxxxxxx@163.com”

如图,表示生成成功

三、得到公钥在GitHub配置

进入 .ssh 文件里,查看id_rsa.pub,表示公钥(public)

复制该密钥到GitHub里配置

标题title随便起

四、查看能否通信成功

输入该命令:如果出现下面这句话,就说明成功了。

ssh -T git@github.com

五、配置邮箱和用户名

通过以下两个命令配置用户名和邮箱,以后提交代码文件,就会附带该用户的信息。

git config --global user.name " xxx "
git config --global user.email " xxx@xx.com"

在 .gitconfig文件可查看

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

好看的圣诞树(动态效果) 转自 csdn

前端达人

、制作方法 

1.复制代码到Dreamweaver或HBuilder或vscode中

2.点击运行---运行到浏览器---选择你要打开的浏览器

3.打开后会出现这个界面,前四个是固定音乐,最后一个是自主选择的音乐,你可以选择你电脑上的歌曲,什么歌曲都行(第一次打开可能会有点慢,稍等片刻即可,选择音乐的时候点一下没反应的话多点几下即可,第一次打开这属于正常现象)

 

4.特别提醒:打开的时候电脑一定要处于联网状态
 

三、源代码

 
  1.  
    <!DOCTYPE html>
  2.  
    <html lang="en">
  3.  
     
  4.  
    <head>
  5.  
    <meta charset="UTF-8">
  6.  
     
  7.  
    <title>圣诞树</title>
  8.  
     
  9.  
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
  10.  
     
  11.  
    <style>
  12.  
    * {
  13.  
    box-sizing: border-box;
  14.  
    }
  15.  
     
  16.  
     
  17.  
    body {
  18.  
    margin: 0;
  19.  
    height: 100vh;
  20.  
    overflow: hidden;
  21.  
    display: flex;
  22.  
    align-items: center;
  23.  
    justify-content: center;
  24.  
    background: #161616;
  25.  
    color: #c5a880;
  26.  
    font-family: sans-serif;
  27.  
    }
  28.  
     
  29.  
     
  30.  
    label {
  31.  
    display: inline-block;
  32.  
    background-color: #161616;
  33.  
    padding: 16px;
  34.  
    border-radius: 0.3rem;
  35.  
    cursor: pointer;
  36.  
    margin-top: 1rem;
  37.  
    width: 300px;
  38.  
    border-radius: 10px;
  39.  
    border: 1px solid #c5a880;
  40.  
    text-align: center;
  41.  
    }
  42.  
     
  43.  
     
  44.  
    ul {
  45.  
    list-style-type: none;
  46.  
    padding: 0;
  47.  
    margin: 0;
  48.  
    }
  49.  
     
  50.  
     
  51.  
    .btn {
  52.  
    background-color: #161616;
  53.  
    border-radius: 10px;
  54.  
    color: #c5a880;
  55.  
    border: 1px solid #c5a880;
  56.  
    padding: 16px;
  57.  
    width: 300px;
  58.  
    margin-bottom: 16px;
  59.  
    line-height: 1.5;
  60.  
    cursor: pointer;
  61.  
    }
  62.  
     
  63.  
    .separator {
  64.  
    font-weight: bold;
  65.  
    text-align: center;
  66.  
    width: 300px;
  67.  
    margin: 16px 0px;
  68.  
    color: #a07676;
  69.  
    }
  70.  
     
  71.  
     
  72.  
    .title {
  73.  
    color: #a07676;
  74.  
    font-weight: bold;
  75.  
    font-size: 1.25rem;
  76.  
    margin-bottom: 16px;
  77.  
    }
  78.  
     
  79.  
     
  80.  
    .text-loading {
  81.  
    font-size: 2rem;
  82.  
    }
  83.  
    </style>
  84.  
     
  85.  
    <script>
  86.  
    window.console = window.console || function (t) { };
  87.  
    </script>
  88.  
     
  89.  
     
  90.  
     
  91.  
    <script>
  92.  
    if (document.location.search.match(/type=embed/gi)) {
  93.  
    window.parent.postMessage("resize", "*");
  94.  
    }
  95.  
    </script>
  96.  
     
  97.  
     
  98.  
    </head>
  99.  
     
  100.  
    <body translate="no">
  101.  
    <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/build/three.min.js"></script>
  102.  
    <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/EffectComposer.js"></script>
  103.  
    <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/RenderPass.js"></script>
  104.  
    <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/ShaderPass.js"></script>
  105.  
    <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/CopyShader.js"></script>
  106.  
    <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/LuminosityHighPassShader.js"></script>
  107.  
    <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/UnrealBloomPass.js"></script>
  108.  
     
  109.  
    <div id="overlay">
  110.  
    <ul>
  111.  
    <li class="title">请选择音乐</li>
  112.  
    <li>
  113.  
    <button class="btn" id="btnA" type="button">
  114.  
    Snowflakes Falling Down by Simon Panrucker
  115.  
    </button>
  116.  
    </li>
  117.  
    <li><button class="btn" id="btnB" type="button">This Christmas by Dott</button></li>
  118.  
    <li><button class="btn" id="btnC" type="button">No room at the inn by TRG Banks</button></li>
  119.  
    <li><button class="btn" id="btnD" type="button">Jingle Bell Swing by Mark Smeby</button></li>
  120.  
    <li class="separator">或者</li>
  121.  
    <li>
  122.  
    <input type="file" id="upload" hidden />
  123.  
    <label for="upload">Upload File</label>
  124.  
    </li>
  125.  
    </ul>
  126.  
    </div>
  127.  
     
  128.  
    <script id="rendered-js">
  129.  
    const { PI, sin, cos } = Math;
  130.  
    const TAU = 2 * PI;
  131.  
     
  132.  
    const map = (value, sMin, sMax, dMin, dMax) => {
  133.  
    return dMin + (value - sMin) / (sMax - sMin) * (dMax - dMin);
  134.  
    };
  135.  
     
  136.  
    const range = (n, m = 0) =>
  137.  
    Array(n).
  138.  
    fill(m).
  139.  
    map((i, j) => i + j);
  140.  
     
  141.  
    const rand = (max, min = 0) => min + Math.random() * (max - min);
  142.  
    const randInt = (max, min = 0) => Math.floor(min + Math.random() * (max - min));
  143.  
    const randChoise = arr => arr[randInt(arr.length)];
  144.  
    const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];
  145.  
     
  146.  
    let scene, camera, renderer, analyser;
  147.  
    let step = 0;
  148.  
    const uniforms = {
  149.  
    time: { type: "f", value: 0.0 },
  150.  
    step: { type: "f", value: 0.0 }
  151.  
    };
  152.  
     
  153.  
    const params = {
  154.  
    exposure: 1,
  155.  
    bloomStrength: 0.9,
  156.  
    bloomThreshold: 0,
  157.  
    bloomRadius: 0.5
  158.  
    };
  159.  
     
  160.  
    let composer;
  161.  
     
  162.  
    const fftSize = 2048;
  163.  
    const totalPoints = 4000;
  164.  
     
  165.  
    const listener = new THREE.AudioListener();
  166.  
     
  167.  
    const audio = new THREE.Audio(listener);
  168.  
     
  169.  
    document.querySelector("input").addEventListener("change", uploadAudio, false);
  170.  
     
  171.  
    const buttons = document.querySelectorAll(".btn");
  172.  
    buttons.forEach((button, index) =>
  173.  
    button.addEventListener("click", () => loadAudio(index)));
  174.  
     
  175.  
     
  176.  
    function init() {
  177.  
    const overlay = document.getElementById("overlay");
  178.  
    overlay.remove();
  179.  
     
  180.  
    scene = new THREE.Scene();
  181.  
    renderer = new THREE.WebGLRenderer({ antialias: true });
  182.  
    renderer.setPixelRatio(window.devicePixelRatio);
  183.  
    renderer.setSize(window.innerWidth, window.innerHeight);
  184.  
    document.body.appendChild(renderer.domElement);
  185.  
     
  186.  
    camera = new THREE.PerspectiveCamera(
  187.  
    60,
  188.  
    window.innerWidth / window.innerHeight,
  189.  
    1,
  190.  
    1000);
  191.  
     
  192.  
    camera.position.set(-0.09397456774197047, -2.5597086635726947, 24.420789670889008);
  193.  
    camera.rotation.set(0.10443543723052419, -0.003827152981119352, 0.0004011488708739715);
  194.  
     
  195.  
    const format = renderer.capabilities.isWebGL2 ?
  196.  
    THREE.RedFormat :
  197.  
    THREE.LuminanceFormat;
  198.  
     
  199.  
    uniforms.tAudioData = {
  200.  
    value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, format)
  201.  
    };
  202.  
     
  203.  
     
  204.  
    addPlane(scene, uniforms, 3000);
  205.  
    addSnow(scene, uniforms);
  206.  
     
  207.  
    range(10).map(i => {
  208.  
    addTree(scene, uniforms, totalPoints, [20, 0, -20 * i]);
  209.  
    addTree(scene, uniforms, totalPoints, [-20, 0, -20 * i]);
  210.  
    });
  211.  
     
  212.  
    const renderScene = new THREE.RenderPass(scene, camera);
  213.  
     
  214.  
    const bloomPass = new THREE.UnrealBloomPass(
  215.  
    new THREE.Vector2(window.innerWidth, window.innerHeight),
  216.  
    1.5,
  217.  
    0.4,
  218.  
    0.85);
  219.  
     
  220.  
    bloomPass.threshold = params.bloomThreshold;
  221.  
    bloomPass.strength = params.bloomStrength;
  222.  
    bloomPass.radius = params.bloomRadius;
  223.  
     
  224.  
    composer = new THREE.EffectComposer(renderer);
  225.  
    composer.addPass(renderScene);
  226.  
    composer.addPass(bloomPass);
  227.  
     
  228.  
    addListners(camera, renderer, composer);
  229.  
    animate();
  230.  
    }
  231.  
     
  232.  
    function animate(time) {
  233.  
    analyser.getFrequencyData();
  234.  
    uniforms.tAudioData.value.needsUpdate = true;
  235.  
    step = (step + 1) % 1000;
  236.  
    uniforms.time.value = time;
  237.  
    uniforms.step.value = step;
  238.  
    composer.render();
  239.  
    requestAnimationFrame(animate);
  240.  
    }
  241.  
     
  242.  
    function loadAudio(i) {
  243.  
    document.getElementById("overlay").innerHTML =
  244.  
    '<div class="text-loading">正在下载音乐,请稍等...</div>';
  245.  
    const files = [
  246.  
    "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Simon_Panrucker/Happy_Christmas_You_Guys/Simon_Panrucker_-_01_-_Snowflakes_Falling_Down.mp3",
  247.  
    "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Dott/This_Christmas/Dott_-_01_-_This_Christmas.mp3",
  248.  
    "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/TRG_Banks/TRG_Banks_Christmas_Album/TRG_Banks_-_12_-_No_room_at_the_inn.mp3",
  249.  
    "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/Mark_Smeby/En_attendant_Nol/Mark_Smeby_-_07_-_Jingle_Bell_Swing.mp3"];
  250.  
     
  251.  
    const file = files[i];
  252.  
     
  253.  
    const loader = new THREE.AudioLoader();
  254.  
    loader.load(file, function (buffer) {
  255.  
    audio.setBuffer(buffer);
  256.  
    audio.play();
  257.  
    analyser = new THREE.AudioAnalyser(audio, fftSize);
  258.  
    init();
  259.  
    });
  260.  
     
  261.  
     
  262.  
     
  263.  
     
  264.  
    }
  265.  
     
  266.  
     
  267.  
    function uploadAudio(event) {
  268.  
    document.getElementById("overlay").innerHTML =
  269.  
    '<div class="text-loading">请稍等...</div>';
  270.  
    const files = event.target.files;
  271.  
    const reader = new FileReader();
  272.  
     
  273.  
    reader.onload = function (file) {
  274.  
    var arrayBuffer = file.target.result;
  275.  
     
  276.  
    listener.context.decodeAudioData(arrayBuffer, function (audioBuffer) {
  277.  
    audio.setBuffer(audioBuffer);
  278.  
    audio.play();
  279.  
    analyser = new THREE.AudioAnalyser(audio, fftSize);
  280.  
    init();
  281.  
    });
  282.  
    };
  283.  
     
  284.  
    reader.readAsArrayBuffer(files[0]);
  285.  
    }
  286.  
     
  287.  
    function addTree(scene, uniforms, totalPoints, treePosition) {
  288.  
    const vertexShader = `
  289.  
    attribute float mIndex;
  290.  
    varying vec3 vColor;
  291.  
    varying float opacity;
  292.  
    uniform sampler2D tAudioData;
  293.  
    float norm(float value, float min, float max ){
  294.  
    return (value - min) / (max - min);
  295.  
    }
  296.  
    float lerp(float norm, float min, float max){
  297.  
    return (max - min) * norm + min;
  298.  
    }
  299.  
    float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
  300.  
    return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
  301.  
    }
  302.  
    void main() {
  303.  
    vColor = color;
  304.  
    vec3 p = position;
  305.  
    vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
  306.  
    float amplitude = texture2D( tAudioData, vec2( mIndex, 0.1 ) ).r;
  307.  
    float amplitudeClamped = clamp(amplitude-0.4,0.0, 0.6 );
  308.  
    float sizeMapped = map(amplitudeClamped, 0.0, 0.6, 1.0, 20.0);
  309.  
    opacity = map(mvPosition.z , -200.0, 15.0, 0.0, 1.0);
  310.  
    gl_PointSize = sizeMapped * ( 100.0 / -mvPosition.z );
  311.  
    gl_Position = projectionMatrix * mvPosition;
  312.  
    }
  313.  
    `;
  314.  
    const fragmentShader = `
  315.  
    varying vec3 vColor;
  316.  
    varying float opacity;
  317.  
    uniform sampler2D pointTexture;
  318.  
    void main() {
  319.  
    gl_FragColor = vec4( vColor, opacity );
  320.  
    gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  321.  
    }
  322.  
    `;
  323.  
    const shaderMaterial = new THREE.ShaderMaterial({
  324.  
    uniforms: {
  325.  
    ...uniforms,
  326.  
    pointTexture: {
  327.  
    value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`)
  328.  
    }
  329.  
    },
  330.  
     
  331.  
     
  332.  
    vertexShader,
  333.  
    fragmentShader,
  334.  
    blending: THREE.AdditiveBlending,
  335.  
    depthTest: false,
  336.  
    transparent: true,
  337.  
    vertexColors: true
  338.  
    });
  339.  
     
  340.  
     
  341.  
    const geometry = new THREE.BufferGeometry();
  342.  
    const positions = [];
  343.  
    const colors = [];
  344.  
    const sizes = [];
  345.  
    const phases = [];
  346.  
    const mIndexs = [];
  347.  
     
  348.  
    const color = new THREE.Color();
  349.  
     
  350.  
    for (let i = 0; i < totalPoints; i++) {
  351.  
    const t = Math.random();
  352.  
    const y = map(t, 0, 1, -8, 10);
  353.  
    const ang = map(t, 0, 1, 0, 6 * TAU) + TAU / 2 * (i % 2);
  354.  
    const [z, x] = polar(ang, map(t, 0, 1, 5, 0));
  355.  
     
  356.  
    const modifier = map(t, 0, 1, 1, 0);
  357.  
    positions.push(x + rand(-0.3 * modifier, 0.3 * modifier));
  358.  
    positions.push(y + rand(-0.3 * modifier, 0.3 * modifier));
  359.  
    positions.push(z + rand(-0.3 * modifier, 0.3 * modifier));
  360.  
     
  361.  
    color.setHSL(map(i, 0, totalPoints, 1.0, 0.0), 1.0, 0.5);
  362.  
     
  363.  
    colors.push(color.r, color.g, color.b);
  364.  
    phases.push(rand(1000));
  365.  
    sizes.push(1);
  366.  
    const mIndex = map(i, 0, totalPoints, 1.0, 0.0);
  367.  
    mIndexs.push(mIndex);
  368.  
    }
  369.  
     
  370.  
    geometry.setAttribute(
  371.  
    "position",
  372.  
    new THREE.Float32BufferAttribute(positions, 3).setUsage(
  373.  
    THREE.DynamicDrawUsage));
  374.  
     
  375.  
     
  376.  
    geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
  377.  
    geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
  378.  
    geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
  379.  
    geometry.setAttribute("mIndex", new THREE.Float32BufferAttribute(mIndexs, 1));
  380.  
     
  381.  
    const tree = new THREE.Points(geometry, shaderMaterial);
  382.  
     
  383.  
    const [px, py, pz] = treePosition;
  384.  
     
  385.  
    tree.position.x = px;
  386.  
    tree.position.y = py;
  387.  
    tree.position.z = pz;
  388.  
     
  389.  
    scene.add(tree);
  390.  
    }
  391.  
     
  392.  
    function addSnow(scene, uniforms) {
  393.  
    const vertexShader = `
  394.  
    attribute float size;
  395.  
    attribute float phase;
  396.  
    attribute float phaseSecondary;
  397.  
    varying vec3 vColor;
  398.  
    varying float opacity;
  399.  
    uniform float time;
  400.  
    uniform float step;
  401.  
    float norm(float value, float min, float max ){
  402.  
    return (value - min) / (max - min);
  403.  
    }
  404.  
    float lerp(float norm, float min, float max){
  405.  
    return (max - min) * norm + min;
  406.  
    }
  407.  
    float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
  408.  
    return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
  409.  
    }
  410.  
    void main() {
  411.  
    float t = time* 0.0006;
  412.  
    vColor = color;
  413.  
    vec3 p = position;
  414.  
    p.y = map(mod(phase+step, 1000.0), 0.0, 1000.0, 25.0, -8.0);
  415.  
    p.x += sin(t+phase);
  416.  
    p.z += sin(t+phaseSecondary);
  417.  
    opacity = map(p.z, -150.0, 15.0, 0.0, 1.0);
  418.  
    vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
  419.  
    gl_PointSize = size * ( 100.0 / -mvPosition.z );
  420.  
    gl_Position = projectionMatrix * mvPosition;
  421.  
    }
  422.  
    `;
  423.  
     
  424.  
    const fragmentShader = `
  425.  
    uniform sampler2D pointTexture;
  426.  
    varying vec3 vColor;
  427.  
    varying float opacity;
  428.  
    void main() {
  429.  
    gl_FragColor = vec4( vColor, opacity );
  430.  
    gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  431.  
    }
  432.  
    `;
  433.  
    function createSnowSet(sprite) {
  434.  
    const totalPoints = 300;
  435.  
    const shaderMaterial = new THREE.ShaderMaterial({
  436.  
    uniforms: {
  437.  
    ...uniforms,
  438.  
    pointTexture: {
  439.  
    value: new THREE.TextureLoader().load(sprite)
  440.  
    }
  441.  
    },
  442.  
     
  443.  
     
  444.  
    vertexShader,
  445.  
    fragmentShader,
  446.  
    blending: THREE.AdditiveBlending,
  447.  
    depthTest: false,
  448.  
    transparent: true,
  449.  
    vertexColors: true
  450.  
    });
  451.  
     
  452.  
     
  453.  
    const geometry = new THREE.BufferGeometry();
  454.  
    const positions = [];
  455.  
    const colors = [];
  456.  
    const sizes = [];
  457.  
    const phases = [];
  458.  
    const phaseSecondaries = [];
  459.  
     
  460.  
    const color = new THREE.Color();
  461.  
     
  462.  
    for (let i = 0; i < totalPoints; i++) {
  463.  
    const [x, y, z] = [rand(25, -25), 0, rand(15, -150)];
  464.  
    positions.push(x);
  465.  
    positions.push(y);
  466.  
    positions.push(z);
  467.  
     
  468.  
    color.set(randChoise(["#f1d4d4", "#f1f6f9", "#eeeeee", "#f1f1e8"]));
  469.  
     
  470.  
    colors.push(color.r, color.g, color.b);
  471.  
    phases.push(rand(1000));
  472.  
    phaseSecondaries.push(rand(1000));
  473.  
    sizes.push(rand(4, 2));
  474.  
    }
  475.  
     
  476.  
    geometry.setAttribute(
  477.  
    "position",
  478.  
    new THREE.Float32BufferAttribute(positions, 3));
  479.  
     
  480.  
    geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
  481.  
    geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
  482.  
    geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
  483.  
    geometry.setAttribute(
  484.  
    "phaseSecondary",
  485.  
    new THREE.Float32BufferAttribute(phaseSecondaries, 1));
  486.  
     
  487.  
     
  488.  
    const mesh = new THREE.Points(geometry, shaderMaterial);
  489.  
     
  490.  
    scene.add(mesh);
  491.  
    }
  492.  
    const sprites = [
  493.  
    "https://assets.codepen.io/3685267/snowflake1.png",
  494.  
    "https://assets.codepen.io/3685267/snowflake2.png",
  495.  
    "https://assets.codepen.io/3685267/snowflake3.png",
  496.  
    "https://assets.codepen.io/3685267/snowflake4.png",
  497.  
    "https://assets.codepen.io/3685267/snowflake5.png"];
  498.  
     
  499.  
    sprites.forEach(sprite => {
  500.  
    createSnowSet(sprite);
  501.  
    });
  502.  
    }
  503.  
     
  504.  
    function addPlane(scene, uniforms, totalPoints) {
  505.  
    const vertexShader = `
  506.  
    attribute float size;
  507.  
    attribute vec3 customColor;
  508.  
    varying vec3 vColor;
  509.  
    void main() {
  510.  
    vColor = customColor;
  511.  
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
  512.  
    gl_PointSize = size * ( 300.0 / -mvPosition.z );
  513.  
    gl_Position = projectionMatrix * mvPosition;
  514.  
    }
  515.  
    `;
  516.  
    const fragmentShader = `
  517.  
    uniform vec3 color;
  518.  
    uniform sampler2D pointTexture;
  519.  
    varying vec3 vColor;
  520.  
    void main() {
  521.  
    gl_FragColor = vec4( vColor, 1.0 );
  522.  
    gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  523.  
    }
  524.  
    `;
  525.  
    const shaderMaterial = new THREE.ShaderMaterial({
  526.  
    uniforms: {
  527.  
    ...uniforms,
  528.  
    pointTexture: {
  529.  
    value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`)
  530.  
    }
  531.  
    },
  532.  
     
  533.  
     
  534.  
    vertexShader,
  535.  
    fragmentShader,
  536.  
    blending: THREE.AdditiveBlending,
  537.  
    depthTest: false,
  538.  
    transparent: true,
  539.  
    vertexColors: true
  540.  
    });
  541.  
     
  542.  
     
  543.  
    const geometry = new THREE.BufferGeometry();
  544.  
    const positions = [];
  545.  
    const colors = [];
  546.  
    const sizes = [];
  547.  
     
  548.  
    const color = new THREE.Color();
  549.  
     
  550.  
    for (let i = 0; i < totalPoints; i++) {
  551.  
    const [x, y, z] = [rand(-25, 25), 0, rand(-150, 15)];
  552.  
    positions.push(x);
  553.  
    positions.push(y);
  554.  
    positions.push(z);
  555.  
     
  556.  
    color.set(randChoise(["#93abd3", "#f2f4c0", "#9ddfd3"]));
  557.  
     
  558.  
    colors.push(color.r, color.g, color.b);
  559.  
    sizes.push(1);
  560.  
    }
  561.  
     
  562.  
    geometry.setAttribute(
  563.  
    "position",
  564.  
    new THREE.Float32BufferAttribute(positions, 3).setUsage(
  565.  
    THREE.DynamicDrawUsage));
  566.  
     
  567.  
     
  568.  
    geometry.setAttribute(
  569.  
    "customColor",
  570.  
    new THREE.Float32BufferAttribute(colors, 3));
  571.  
     
  572.  
    geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
  573.  
     
  574.  
    const plane = new THREE.Points(geometry, shaderMaterial);
  575.  
     
  576.  
    plane.position.y = -8;
  577.  
    scene.add(plane);
  578.  
    }
  579.  
     
  580.  
    function addListners(camera, renderer, composer) {
  581.  
    document.addEventListener("keydown", e => {
  582.  
    const { x, y, z } = camera.position;
  583.  
    console.log(`camera.position.set(${x},${y},${z})`);
  584.  
    const { x: a, y: b, z: c } = camera.rotation;
  585.  
    console.log(`camera.rotation.set(${a},${b},${c})`);
  586.  
    });
  587.  
     
  588.  
    window.addEventListener(
  589.  
    "resize",
  590.  
    () => {
  591.  
    const width = window.innerWidth;
  592.  
    const height = window.innerHeight;
  593.  
     
  594.  
    camera.aspect = width / height;
  595.  
    camera.updateProjectionMatrix();
  596.  
     
  597.  
    renderer.setSize(width, height);
  598.  
    composer.setSize(width, height);
  599.  
    },
  600.  
    false);
  601.  
     
  602.  
    }
  603.  
    </script>
  604.  
     
  605.  
    </body>
  606.  
     
  607.  
    </html>
 

WebSocket:实现实时双向数据传输的Web通信协议

前端达人

 

前言

在当今互联网时代,实时通信已成为很多应用的需求。为了满足这种需求,WebSocket协议被设计出来。WebSocket是一种基于TCP议的全双工通信协议,通过WebSocket,Web应用程序可以与服务器建立持久的连接,实现实时双向数据输,提供极低的延迟和高效的数据传输。


WebSocket原理

  • HTTP请求-响应协议

在理解WebSocket原理之前,我们需要了解HTTP请求-响应协议。HTTP是一种无状态的请求-响应协议,客户端通过发送HTTP请求到服务器,服务器接收并处理请求,并返回HTTP响应给客户端。但是,在传统的HTTP协议中,客户端只能发送请求,而服务器只能通过响应来处理客户端的请求。

  • WebSocket协议

WebSocket协议是在HTTP协议的基础上进行扩展的。在建立WebSocket连接时,客户端首先发送一个HTTP请求到服务器,并将Upgrade头部字段设置为"websocket",表示希望升级到WebSocket协议。服务器接收到这个请求后,如果支持WebSocket协议,会返回一个状态码101 Switching Protocols的HTTP响应,并通过Upgrade头部字段将连接升级为WebSocket连接。

升级完成后,客户端和服务器之间的通信不再遵循HTTP请求-响应模式,而是通过WebSocket协议进行双向的实时通信。客户端和服务器可以直接发送消息给对方,不需要等待对方的请求。


如何使用WebSocket

建立WebSocket连接:

要建立WebSocket连接,需要在客户端和服务器之间进行系列的握手操作。下面是详细的代码教程,示了如何在Web应用程序中建立WebSocket连接。

在户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("ws://example.com/socket");

// 监听连接建立事件
socket.onopen = function() {
console.log("WebSocket连接已建立");
// 在连接建立后,可以发送消息到服务器
socket.send("Hello Server!");
};


// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
var message = event.data;
console.log("接收到服务器发送的消息:" + message);
};


// 监听连接关闭事件
socket.onclose = function(event) {
console.log("WebSocket连接已关闭");
};


// 监听连接错误事件
socket.onerror = function(event) {
console.error("WebSocket连接错误:" + event};

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({ port: 8080 });


// 监听连接建立事件
wss.on("connection", function(socket) {
console.log("WebSocket连接已建立");


// 监听接收到客户端发送的消息
socket.on("message", function(message) {
console.log("接收到户端发送的消息:" + message);


<span class="token comment">// 向客户端发送消息</span>
socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">"Hello Client!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

});


// 监听连接关闭事件
socket.on("close", function() {
console.log("WebSocket连接已关闭");
});
});

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在以上代码中,客户端通过创建WebSocket对象,并指定服务器地址"ws://example.com/socket"来建立WebSocket连接。同时,客户端通过监听onopen事件,可以在连接建立后发送消息到服务器。服务器端使用WebSocket.Server类创建WebSocket服务器,并监听"connection事件来处理连接建立后的操作。服务器端通过socket.on(“message”)来监听接收到客户端发送的消息,并通过socket.send()向客户端发送消息。

数据传输:

建立WebSocket连接后,客户端和服务器可以通过WebSocket对象进行双向的实时数据传输。下面是一个示例代码,演示了如何在客户端和服务器之间进行数据传输。

在客户端(JavaScript):

// 发送消息到服务器
socket.send("Hello Server!");

// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
var message = event.data;
console.log("接收到服务器发送的消息:" + message);
};

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在服务器端(示例使用Node.js):

// 向客户端发送消息
socket.send("Hello Client!");

// 监听接收到客户端发送的消息
socket.on("message", function(message) {
console.log("接收到客户端发送的消息:" + message);
});

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在以上代码中,客户端通过调用socket.send()方法将消息发送到服务器,服务器通过socket.send()方法将消息发送到客户端。客户端通过监听socket.onmessage事件来接收服务器发送的消息,服务器通过监听socket.on("message")事件来接收客户端发送的消息。

通过以上代码示例,你可以详细了解如何使用WebSocket建立连接并进行数据传输。请注意,示例代码中使用的服务器地址和端口号需要根据实际情况进行修改。同时,你还可以在具体应用中根据需要使用WebSocket的其他方法和事件来实现更复杂的功能。


WebSocket的真实使用场景

即时通讯:

WebSocket非常适合用于即时通讯应用,因为它能够实现实时双向通信。以下是一个简单的即时聊天应用的代码教程。

在客户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("ws://example.com/socket");

// 监听连接建立事件
socket.onopen = function() {
console.log("WebSocket连接已建立");


// 监听文本框输入,按下Enter键时发送消息
var input = document.getElementById("input");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
var message = input.value;
socket.send(message);
input.value = "";
}
});
};


// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
var message = event.data;
console.log("接收到服务器发送的消息:" + message);


// 将接收到的消息显示在聊天窗口中
var chatWindow = document.getElementById("chatWindow");
chatWindow.innerHTML += "<p>" + message + "</p>";
};


// 监听连接关闭事件
socket.onclose = function(event) {
console.log("WebSocket连接已关闭");
};


// 监听连接错误事件
socket.onerror = function(event) {
console.error("WebSocket连接错误:" + event};

 

  • 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

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({ port: 8080 });


// 监听连接建立事件
wss.on("connection", function(socket) {
console.log("WebSocket连接已建立");


// 监听接收到客户端发送的消息
socket.on("message", function(message) {
console.log("接收到客户端发送的消息:" + message);


<span class="token comment">// 向所有连接的客户端发送消息</span>
wss<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">client</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  client<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

});


// 监听连接关闭事件
socket.on("close", function() {
console.log("WebSocket连接已关闭");
});
});

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在上述代码中,客户端通过创建WebSocket对象连接到服务器。输入框中的文本框用于录入要发送的消息,按下Enter键时会将消息发送给服务器。服务器接收到消息后,通过遍历所有连接的客户端,向每个客户端发送消息。

这样,多个客户端就可以实时地进行聊天,并且所有的消息都会实时地在各个客户端之间同步显示。

多人协作:

WebSocket还可用于多人协作应用,让多个用户可以实时地协同编辑文档或画布。以下是一个简单的代码教程。

在客户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("ws://example.com/socket");

// 监听连接建立事件
socket.onopen = function() {
console.log("WebSocket连接已建立");


// 监听文本框输入,按下Enter键时发送绘画指令
var canvas = document.getElementById("canvas");
canvas.addEventListener("mousedown", function(event) {
// 绘画指令的数据格式可以自定义,这里使用了简单的示例
var instruction = {
type: "draw",
position: {
x: event.clientX,
y: event.clientY
}
};
socket.send(JSON.stringify(instruction));
});
};


// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
var message = JSON.parse(event.data);
console.log("接收到服务器发送的消息:" + message);


// 根据消息执行相应的操作,示例中处理了绘画指令
if (message.type === "draw") {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(message.position.x, message.position.y, 5, 0, 2 * Math.PI);
ctx.fill();
}
};


// 监听连接关闭事件
socket.onclose = function(event) {
console.log("WebSocket连接已关闭");
};


// 监听连接错误事件
socket.onerror = function(event) {
console.error("WebSocket连接错误:" + event};

 

  • 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

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({ port: 8080 });


// 监听连接建立事件
wss.on("connection", function(socket) {
console.log("WebSocket连接已建立");


// 监听接收到客户端发送的消息
socket.on("message", function(message) {
console.log("接收到客户端发送的消息:" + message);


<span class="token comment">// 向所有连接的客户端发送消息</span>
wss<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">client</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  client<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

});


// 监听连接关闭事件
socket.on("close", function() {
console.log("WebSocket连接已关闭");
});
});

 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在上述代码中,客户端通过创建WebSocket对象连接到服务器。当鼠标在画布上按下时,将绘画指令发送给服务器。服务器接收到绘画指令后,将指令广播给所有连接的客户端,并在各个客户端上进行绘画操作。

这样,多个用户就可以实时地协同编辑同一个画布或文档,所有的绘画指令都会即时同步在各个客户端之间。

实时数据更新:

WebSocket还可以用于实时数据更新应用,例如股票交易应用中的实时股票价格更新。以下是一个简单的代码教程。

在客户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("链接");

// 监听连接建立事件
socket.onopen = function() {
console.log("WebSocket连接已建立");
};


// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
var message = JSON.parse(event.data);
console.log("接收到服务器发送的消息:" + message);


// 对接收到的实时数据进行处理
var stockPriceElement = document.getElementById("stockPrice");
stockPriceElement.innerText = message.price;
};


// 监听连接关闭事件
socket.onclose = function(event) {
console.log("WebSocket连接已关闭");
};


// 监听连接错误事件
socket.onerror = function(event) {
console.error("WebSocket连接错误:" + event};

 

  • 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

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({ port: 8080 });


// 模拟实时股票价格更新
setInterval(function() {
var stockPrice = Math.random() * 100;


// 向所有连接的客户端发送实时数据
wss.clients.forEach(function(client) {
var data = {
price: stockPrice
};
client.send(JSON.stringify(data));
});
}, 2000);


// 监听连接建立事件
wss.on("connection", function(socket) {
console.log("WebSocket连接已建立");


// 初始化发送实时数据
var stockPrice = Math.random() * 100;
var data = {
price: stockPrice
};
socket.send(JSON.stringify(data));


// 监听连接关闭事件
socket.on("close", function() {
console.log("WebSocket连接已关闭");
});
});

 

  • 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

在上述代码中,客户端通过创建WebSocket对象连接服务器。服务器使用setInterval函数模拟实时股票价格的更新,并将更新的数据发送给所有连接的客户端。客户端监听接收到服务器发送的消息,并处理接收到的实时数据。

这样,在股票交易应用中,多个用户可以实时地接收和显示股票价格的更新信息。包括打游戏的时候,队友之间互相沟通,打字交流,或者走位,放技能等等,都是即时的。


WebSocket的优势与局限性

  • WebSocket的优势:
  • 双向实时通信:WebSocket提供了双向的实时信能力,客户端和服务器可以通过该协议进行双向数据传输,实时反馈更新信息,实现即时通讯、实时数据推送等功能。

  • 较低的延迟:与传统的HTTP请求相比,WebSocket降低了通信的开销,减少了传输和处理数据的延迟,因此可以更快进行实时数据传输。

  • 更高的性能:由于WebSocket使用较少的头部信息和更有效的消息传输格式,因此在相同带宽下可以传输更多的数据,提高了性能和效率。

  • 广泛的浏览器支持:WebSocket是HTML5的一部分,并且得到了大多数现代浏览器的支持,因此它可以在各种平台和设备上使用。

  • 连接保持:与传统的HTTP请求不同,WebSocket连接保持在建立之后,双方可以随时进行数据传输,避免了不必要的连接和断开操作。

  • WebSocket的局限性:
  • 兼容性问题:虽然现代浏览器广泛支持WebSocket,但在某些旧版本或特定设备上可能存在兼容性问题。为了兼容性,可以使用轮训技术(如长轮询)作为备选方案。

  • 部署和维护复杂性:WebSocket服务器的设置和配置可能比传统的Web服务器复杂一些,需要专门的服务器环境和配置。

  • 安全性问题:由于WebSocket是在HTTP协议的基础上建立的,它们共享相同的安全风险,例如跨站点脚本(XSS)和跨站请求伪造(CSRF)。因此,在使用WebSocket时需要考虑到安全性,并采取适当的安全措施。

  • 扩展问题:WebSocket协议还不支持像HTTP/2那样的一些高级特性,例如头部压缩和流量控制。在某些特殊情况下,可能需要通过其他方式实现这些功能。

尽管WebSocket具有上述局限性,但它仍然是实时通讯、实时数据传输和实时协作等场景下的首选协议,因为它具备了双向实时通信和较低延迟等一系列的优势。在开发时,需要根据具体需求和限制,综合考虑使用WebSocket的适用性。


结论

WebSocket是一种能够提供双向实时通信的协议,适用于需要实时数据传输和双向通信的场景。它具有较低的延迟、更高的性和广泛的浏览器持等优势,能够实现即时通讯、多人协和实时数据更新等功能。

然而,WebSocket也存在兼容性、部署和维护复杂性、安全性问题以及缺乏一些高级特性等局限性。在开发时,需要仔细考虑具体需求和限制,并必要时采取适当的解决方案。

总的来说,WebSocket在实时通信和实时数据传输方面具有明显的优势,是构建现代Web应用的重要工具之一。

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

Vue2 watch监听props的值

前端达人

再次遇到监听子组件收到父组件传过来的值,如果这个值变化,页面中的值发现是不会跟着同步变化的。所以监听props中的值,一直监听。

 

代码:

 
  1.  
    props: {
  2.  
    start:{
  3.  
    type: String,
  4.  
    },
  5.  
    end:{
  6.  
    type: String,
  7.  
    }
  8.  
    },
 

 

 
  1.  
    computed:{
  2.  
    myStart:function(){
  3.  
    return this.start
  4.  
    },
  5.  
    myEnd:function(){
  6.  
    return this.end
  7.  
    }
  8.  
    },
  9.  
    watch: {
  10.  
    myStart:function(newVal){
  11.  
    if(newVal){
  12.  
    this.startTime=newVal
  13.  
    }
  14.  
    },
  15.  
    myEnd:function(newVal){
  16.  
    if(newVal){
  17.  
    this.endTime=newVal
  18.  
    }
  19.  
    },
  20.  

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

什么是前端安全性(front-end security)?列举一些前端安全性的最佳实践

前端达人

前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一个系统而又亲切的学习平台。在这个专栏中,我们将以问答形式每天更新,为大家呈现精选的前端知识点和常见问题解答。通过问答形式,我们希望能够更直接地回应读者们对于前端技术方面的疑问,并且帮助大家逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是各种常用框架和工具,我们将深入浅出地解释概念,并提供实际案例和练习来巩固所学内容。同时,我们也会分享一些实用技巧和最佳实践,帮助你更好地理解并运用前端开发中的各种技术。

无论你是寻找职业转型、提升技能还是满足个人兴趣,我们都将全力以赴,为你提供最优质的学习资源和支持。让我们一起探索Web开发的奇妙世界吧!加入前端入门之旅,成为一名出色的前端开发者! 让我们启航前端之旅!!!


前端安全性概述及最佳实践

前端安全性是指在前端开发中采取的一系列措施,旨在保护应用程序、用户数据以及用户隐私免受各种安全威胁。以下是一些前端安全性的最佳实践:

  1. HTTPS 使用:

    • 使用HTTPS协议确保数据在传输过程中的加密,防止中间人攻击。
  2. 内容安全策略(CSP):

    • 使用CSP来限制浏览器加载页面中的资源,防止恶意脚本注入。
  3. 跨站脚本攻击(XSS)防护:

    • 对用户输入和动态生成的内容进行合适的转义或编码。
    • 使用HTTP Only 标记来防止脚本操作 cookie。
  4. 跨站请求伪造(CSRF)防护:

    • 使用合适的令牌(CSRF Token)来验证请求的合法性。
  5. 安全的跨域资源共享(CORS)配置:

    • 限制允许访问资源的域,防止不受信任的域发起请求。
  6. 安全的第三方库和框架:

    • 使用官方版本的库和框架,避免使用已知的有安全漏洞的版本。
  7. 安全的存储和传输:

    • 避免在前端存储敏感信息,如密码,而应交由后端进行处理。
    • 在数据传输时使用加密算法,确保数据在传输过程中的保密性。
  8. 用户身份验证和授权:

    • 使用安全的身份验证方法,如OAuth或OpenID Connect。
    • 仅在有必要的情况下授予用户特定的权限。
  9. 不使用过期或不安全的特性:

    • 避免使用已经过时或不再维护的前端框架和库。
    • 避免使用不安全的浏览器特性,如弃用的插件。
  10. 前端路由安全:

    • 使用前端路由时,确保路由的访问权限得到合理管理,防止越权访问。
  11. 监测和报告安全事件:

    • 集成日志记录和监控机制,及时发现异常行为。
    • 实现安全事件报告,以便及时采取措施应对攻击。
  12. 教育和培训:

    • 对开发团队进行安全性培训,提高对潜在威胁的认识。
    • 定期进行代码审查,确保代码符合最佳安全实践。
  13. 安全头部的使用:

    • 使用HTTP头部来加强安全性,如Strict-Transport-Security(HSTS)。
  14. 定期进行安全性测试:

    • 进行定期的安全性测试,包括静态代码分析和渗透测试,以确保发现和修复潜在的安全漏洞。

这些最佳实践有助于构建更加安全、可靠的前端应用程序,减少潜在的攻击风险。前端安全性是一个不断演变的领域,开发者应该时刻关注新的安全威胁和最佳实践。


 

本专栏适用读者比较广泛,适用于前端初学者;或者没有学过前端对前端有兴趣的伙伴,亦或者是后端同学想在面试过程中能够更好的展示自己拓展一些前端小知识点,所以如果你具备了前端的基础跟着本专栏学习,也是可以很大程度帮助你查漏补缺,由于博主本人是自己再做内容输出,如果文中出现有瑕疵的地方各位可以通过主页的左侧联系我,我们一起进步,与此同时也推荐大家几份专栏,有兴趣的伙伴可以订阅一下:除了下方的专栏外大家也可以到我的主页能看到其他的专栏;

前端小游戏(免费)这份专栏将带你进入一个充满创意和乐趣的世界,通过利用HTML、CSS和JavaScript的基础知识,我们将一起搭建各种有趣的页面小游戏。无论你是初学者还是有一些前端开发经验,这个专栏都适合你。我们会从最基础的知识开始,循序渐进地引导你掌握构建页面游戏所需的技能。通过实际案例和练习,你将学会如何运用HTML来构建页面结构,使用CSS来美化游戏界面,并利用JavaScript为游戏添加交互和动态效果。在这个专栏中,我们将涵盖各种类型的小游戏,包括迷宫游戏、打砖块、贪吃蛇、扫雷、计算器、飞机大战、井字游戏、拼图、迷宫等等。每个项目都会以简洁明了的步骤指导你完成搭建过程,并提供详细解释和代码示例。同时,我们也会分享一些优化技巧和最佳实践,帮助你提升页面性能和用户体验。无论你是想寻找一个有趣的项目来锻炼自己的前端技能,还是对页面游戏开发感兴趣,前端小游戏专栏都会成为你的最佳选择

Vue3通透教程【从零到一】(付费) 欢迎来到Vue3通透教程!这个专栏旨在为大家提供全面的Vue3相关技术知识。如果你有一些Vue2经验,这个专栏都能帮助你掌握Vue3的核心概念和使用方法。我们将从零开始,循序渐进地引导你构建一个完整的Vue应用程序。通过实际案例和练习,你将学会如何使用Vue3的模板语法、组件化开发、状态管理、路由等功能。我们还会介绍一些高级特性,如Composition API和Teleport等,帮助你更好地理解和应用Vue3的新特性。在这个专栏中,我们将以简洁明了的步骤指导你完成每个项目,并提供详细解释和示例代码。同时,我们也会分享一些Vue3开发中常见的问题和解决方案,帮助你克服困难并提升开发效率。无论你是想深入学习Vue3或者需要一个全面的指南来构建前端项目,Vue3通透教程专栏都会成为你不可或缺的资源。

TypeScript入门指南(免费) 是一个旨在帮助大家快速入门并掌握TypeScript相关技术的专栏。通过简洁明了的语言和丰富的示例代码,我们将深入讲解TypeScript的基本概念、语法和特性。无论您是初学者还是有一定经验的开发者,都能在这里找到适合自己的学习路径。从类型注解、接口、类等核心特性到模块化开发、工具配置以及与常见前端框架的集成,我们将全面覆盖各个方面。通过阅读本专栏,您将能够提升JavaScript代码的可靠性和可维护性,并为自己的项目提供更好的代码质量和开发效率。让我们一起踏上这个精彩而富有挑战性的TypeScript之旅吧!

 

蓝蓝设计(www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的大数据可视化界面设计B端界面设计桌面端界面设计APP界面设计图标定制用户体验设计交互设计UI咨询高端网站设计平面设计,以及相关的软件开发服务,咨询电话:01063334945。

关键词:UI咨询UI设计服务公司软件界面设计公司、界面设计公司、UI设计公司UI交互设计公司数据可视化设计公司用户体验公司高端网站设计公司

银行金融软件UI界面设计能源及监控软件UI界面设计气象行业UI界面设计轨道交通界面设计地理信息系统GIS UI界面设计航天军工软件UI界面设计医疗行业软件UI界面设计教育行业软件UI界面设计企业信息化UI界面设计、软件qt开发软件wpf开发软件vue开发

日历

链接

个人资料

蓝蓝设计的小编 http://www.lanlanwork.com

存档