priv-note 开发笔记

p-note是一个比较完善的前后端项目,也算是对最近WEB相关知识学习交的一次作业。页面内容还不尽完善,已经转入了迭代维护的模式,这里先贴一下项目的链接。可以感受一下。

https://p-note.12ms.xyz/

功能介绍呢?就是一个实现了阅后即焚的站点。这个项目是仿写的,原项目 vua.sh。模仿了UI设计,方案和后段内容是自己设计。

技术简介

技术栈

这个项目目前使用到的技术,以及技术栈,都向最新看齐,来实现快速学习和快速成长。
使用的技术栈:

  1. Serverless 函数服务部署
  2. git integration 实现push 后的自动部署
  3. 基于 Vue 的 Element 实现前端页面设计
  4. Nodejs 的 Koa 后端
  5. Mongo Altas 数据库API服务

设计原理

前端通过 RSAnode 库来生成 RAS 密钥对,通过公钥来进行内容加密。加密内容通过 POST 传递到后端(注,后端不做解密操作),后端直接以 key:cipher的方式来进行入库。直到内容再被请求的时候,查库得到结果之后删除数据,返回加密数据,前端使用 密钥来进行解密。得到原始数据,完成阅后即焚。

前端设计

前端使用的是 vur + element ui 这套常见的方案来实现的开发,这里主要对其中的一些点来进行总结。

个人理解的vue

这里先从总的触发器说说自己理解中的VUE和 MVVM 模型。VUE 较比之前写的一些前端的内容,其最大的优势,目前感觉就是 MVVM 的方式(当然,可能是我目前接触较浅)。 与之前使用 JQuery 不同的是,JQuery 需要不断的去查询数据,和写数据来写或者读DOM的值。
但是这些在 VUE中已经使用了 VM层(viewmodel)层来把数据进行了双向的绑定:JS中的变量改变会使得DOM更新,反正JS中的变量值也会更新。实例代码如下所示:

<el-card shadow="never">
<p style="overflow-wrap:break-word">{{host}}</p>
</el-card>

<script>
 data() { return {
        get origin() {return location.origin; },
        get host() {return location.origin + "/#/" + this.cipherB64;}
}}
</script>

view 与 components

view 可以理解为页面内容,而Component是在各个vue中复用的。
APP.vue 中引用各个 view 可以根据 vue-router来SPA来达到多页面的效果。
view 中 可以复用各个 Component 来避免重复造轮子。
在vue 中,两个东西引入的方式很类似,引入代码如下:

<template>
  <div id="app">
     <!-- 这里引入了插件 -->
    <Pnote />
  </div>
</template>

<script>
import Pnote from "@/views/Pnote.vue";
export default {
  name: "app",
  components: {
    Pnote
  }
};
</script>

条件渲染

VUE 可以通过 v-if 的语句来实现动态的条件渲染,来决定渲染那些内容,在v-if 块里面支持 js 的条件语句

 <div v-if="sentStatus == Status.EDIT">
    <el-button type="primary" style="width:100%; height:70px" v-on:click="postData">Submit it</el-button>
</div>
<div v-else-if="sentStatus == Status.MSG">
    <el-button type="primary" style="width:100%; height:70px" v-on:click="goHome">Delete it</el-button>
</div>
<div v-else>
<el-button  type="primary"  style="width:100%; height:70px" v-clipboard:success="copy2board"  v-clipboard:copy="host">Copy it</el-button>
</div>

容器布局

element ui 可以使用 容器布局 来进行快速的常规布局。

<el-container>
  <el-header>Header</el-header>
  <el-main>Main</el-main>
  <el-footer>Footer</el-footer>
</el-container>

mount 只执行一次

mount 在页面渲染的时候会执行,但是当页面dom 发生变化的时候,mount 也会被调用。所以就需要设置一个标志位,使得这一段只执行一次。

data() { return { firstPlayFlag: true };},
mounted() {
    if(this.firstPlayFlag) {
        this.showMsg();
        this.firstPlayFlag = false;
    }
}

VueClipboard

点击快速的复制vue变量的值到剪切板,success 里面的是回调函数,copy 是vue的namespace 的host。

<div v-else><el-button  type="primary"  style="width:100%; height:70px" v-clipboard:success="copy2board"  v-clipboard:copy="host">Copy it</el-button>

element 通知框

element UI 可以快速的使用预置的通知框,具体的弹出代码如下

that.$notify({ type: 'success', title: 'success', message: 'Submit Successfully'});
that.$notify.error({title: 'error', message: 'Submit failed'});

RSA 密钥对生成

使用 RSAnode 来实现密钥生成,以及加解密函数。

    rsa: function() {
      const key = new NodeRSA({ b: 512 });
      let publicKey = key.exportKey("pkcs1-public-pem"); //公钥
      let privateKey = key.exportKey("pkcs1-private-pem"); //私钥
      return {
        RSAencrypt: function(pas) {
          console.log("encrypt user data");
          console.log(this.GetPrivateKeyB64());
          return key.encrypt(pas, "base64");
        },
        importPrivateKeyB64: function(privateKeyB64) {
          const privateKey = new Buffer(privateKeyB64, "base64").toString(
            "ascii"
          );
          key.importKey(privateKey, "pkcs1-private-pem");
        },
        //解密方法
        RSAdecrypt: function(pas) {
          return key.decrypt(pas, "utf-8");
        },
        GetPrivateKey: function() {
          return privateKey;
        },
        GetPubilcKey: function() {
          return privateKey;
        },
        GetPubilcKeyB64: function() {
          let publicKeyB64 = new Buffer(publicKey).toString("base64");
          return publicKeyB64;
        },
        GetPrivateKeyB64: function() {
          let privateKeyB64 = new Buffer(privateKey).toString("base64");
          return privateKeyB64;
        }
      };

后端设计

留下点什么吧