基于Vue3和element-plus实现一个完整的登录功能

news2024/12/27 10:56:19

先看一下最终要实现的效果:

登录页面:

注册页面:

(1)引入element-plus组件库

引入组件库的方式有好多种,在这里我就在main.js全局引入了.

npm i element-plus -S

main.js中代码:

import { createApp } from "vue";
//element-plus
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import App from "./App.vue";
import router from "./router";
import axios from "axios";
import store from "./store";
//创建实例
const app = createApp(App);
//全局应用配置
app.config.globalProperties.$axios = axios;

app.use(ElementPlus).use(store).use(router).mount("#app");

引入之后自己可以用几个按钮测试一下是否引入成功.

(2)登录及注册页面

  1. html部分

views/account/Login.vue

<template>
  <div id="login">
    <div>
      <div class="form-wrap">
        <ul class="menu-tab">
          <li
            :class="{ current: current_menu === item.type }"
            v-for="item in data.tab_menu"
            :key="item.type"
            @click="toggleMenu(item.type)"
          >
            {{ item.label }}
          </li>
        </ul>
        <el-form
          :model="data.form"
          ref="account_form"
          :rules="data.form_rules"
          label-width="80px"
        >
          <el-form-item prop="username">
            <label class="form-label">用户名</label>
            <el-input type="password" v-model="data.form.username" />
          </el-form-item>
          <el-form-item prop="password">
            <label class="form-label">密码</label>
            <el-input type="password" v-model="data.form.password" />
          </el-form-item>
          <el-form-item v-show="current_menu === 'register'" prop="passwords ">
            <label class="form-label">确认密码</label>
            <el-input type="password" v-model="data.form.passwords" />
          </el-form-item>
          <el-form-item prop="code">
            <label class="form-label">验证码</label>
            <el-row :gutter="10">
              <el-col :span="14">
                <el-input v-model="data.form.code"></el-input>
              </el-col>
              <el-col :span="10">
                <el-button
                  type="success"
                  class="el-button-block"
                  @click="handleGetCode"
                  >获取验证码</el-button
                ></el-col
              >
            </el-row>
          </el-form-item>
          <el-form-item>
            <el-button
              type="danger"
              class="el-button-block"
              :disabled="data.submit_button_disabled"
              :loading="data.submit_button_loading"
              @click="submitForm"
              >{{ current_menu === "login" ? "登录" : "注册" }}</el-button
            >
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>
  1. js部分

<script>
import { reactive, ref, getCurrentInstance, onBeforeUnmount } from "vue";
import {
  validate_email,
  validate_password,
  validate_code,
} from "@/utils/validate";
import { GetCode } from "@/api/common";
import { Register, Login } from "@/api/account";
import sha1 from "js-sha1"; //密码加密
// ErrorHttp
export default {
  setup() {
    const instance = getCurrentInstance();
    const { proxy } = getCurrentInstance();
    console.log("instance", instance);
    // console.log("proxy", proxy);
    // 用户名校验
    const validate_name_rules = (rule, value, callback) => {
      let regEmail = validate_email(value);
      if (value === "") {
        callback(new Error("请输入邮箱"));
      } else if (!regEmail) {
        callback(new Error("邮箱格式不正确"));
      } else {
        callback();
      }
    };

    //获取验证码
    const handleGetCode = () => {
      const username = data.form.username;
      const password = data.form.password;
      const passwords = data.form.passwords;
      //校验用户名
      if (!validate_email(username)) {
        proxy.$message({
          message: "用户名不能为空 或 格式不正确",
          type: "error",
        });
        return false;
      }

      //校验密码
      if (!validate_password(password)) {
        proxy.$message({
          message: "密码不能为空 或 格式不正确",
          type: "error",
        });
        return false;
      }

      //判断为注册时,校验两次密码
      if (data.current_menu === "redister" ** (password !== passwords)) {
        proxy.$message({
          message: "两次密码不一致",
          type: "error",
        });
        return false;
      }
      //获取验证码接口
      const requestData = {
        username: data.form.username,
        module: "register",
      };

      data.code_button_loading = true;
      data.code_button_text = "发送中";
      GetCode(requestData)
        .then((res) => {
          // console.log("123", res.data);验证码
          // const data=res.resCode

          const data = res;
          if (data.resCode === 1024) {
            proxy.$message.error(data.message);
            return false;
          }
          // 成功 Elementui 提示
          proxy.$message({
            message: data.message,
            type: "success",
          });
          //执行倒计时
          countdown();
        })
        .catch((err) => {
          console.log(err);
          data.code_button_loading = false;
          data.code_button_text = "发送验证码";
        });

      // ErrorHttp(requestData)
      //   .then((res) => {
      //     console.log(res.data);
      //     // const data=res.resCode
      //     const data = res.data;
      //     if (data.resCode === 1024) {
      //       proxy.$message.error(data.message);
      //       return false;
      //     }
      //     // 成功 Elementui 提示
      //     proxy.$message({
      //       message: data.message,
      //       type: "success",
      //     });
      //     //执行倒计时
      //     countdown();
      //   })
      //   .catch((err) => {
      //     console.log(err);
      //     data.code_button_loading = false;
      //     data.code_button_text = "发送验证码";
      //   });
    };

    /** 倒计时 */
    const countdown = (time) => {
      if (time && typeof time !== "number") {
        return false;
      }
      let second = time || 60; // 默认时间
      data.code_button_loading = false; // 取消加载
      data.code_button_disabled = true; // 禁用按钮
      data.code_button_text = `倒计进${second}秒`; // 按钮文本
      // 判断是否存在定时器,存在则先清除
      if (data.code_button_timer) {
        clearInterval(data.code_button_timer);
      }
      // 开启定时器
      data.code_button_timer = setInterval(() => {
        second--;
        data.code_button_text = `倒计进${second}秒`; // 按钮文本
        if (second <= 0) {
          data.code_button_text = `重新获取`; // 按钮文本
          data.code_button_disabled = false; // 启用按钮
          clearInterval(data.code_button_timer); // 清除倒计时
        }
      }, 1000);
    };

    // 组件销毁之前 - 生命周期
    onBeforeUnmount(() => {
      clearInterval(data.code_button_timer); // 清除倒计时
    });

    // 校验确认密码
    const validate_password_rules = (rule, value, callback) => {
      let regPassword = validate_password(value);
      if (value === "") {
        callback(new Error("请输入密码"));
      } else if (!regPassword) {
        callback(new Error("请输入>=6并且<=20位的密码,包含数字、字母"));
      } else {
        callback();
      }
    };

    // 校验确认密码
    const validate_passwords_rules = (rule, value, callback) => {
      // 如果是登录,不需要校验确认密码,默认通过
      if (data.current_menu === "login") {
        callback();
      }
      let regPassword = validate_password(value);
      // 获取“密码”
      const passwordValue = data.form.password;
      if (value === "") {
        callback(new Error("请输入密码"));
      } else if (!regPassword) {
        callback(new Error("请输入>=6并且<=20位的密码,包含数字、字母"));
      } else if (passwordValue && passwordValue !== value) {
        callback(new Error("两次密码不一致"));
      } else {
        callback();
      }
    };

    const validate_code_rules = (rule, value, callback) => {
      let regCode = validate_code(value);
      // 激活提交按钮
      data.submit_button_disabled = false;
      if (value === "") {
        callback(new Error("请输入验证码"));
      } else if (!regCode) {
        callback(new Error("请输入6位的验证码"));
      } else {
        callback();
      }
    };

    // 提交表单
    const submitForm = () => {
      // let res = proxy.$refs.account_form;
      proxy.$refs.account_form.validate((valid) => {
        if (valid) {
          console.log("提交表单", current_menu.value);
          current_menu.value === "login" ? login() : register();
          // register();
        } else {
          alert("error submit!");
          return false;
        }
      });
      // console.log(" 提交表单", res);
    };
    /** 登录 */
    const login = () => {
      const requestData = {
        username: data.form.username,
        password: sha1(data.form.password),
        code: data.form.code,
      };
      data.submit_button_loading = true;
      Login(requestData)
        .then((response) => {
          console.log("login", response);
          data.submit_button_loading = false;
          proxy.$message({
            message: response.message,
            type: "success",
          });

          reset();
        })
        .catch((error) => {
          console.log("登录失败", error);
          data.submit_button_loading = false;
        });
    };
    //注册
    const register = () => {
      const requestData = {
        username: data.form.username,
        password: sha1(data.form.password),
        code: data.form.code,
      };
      data.submit_button_loading = true;
      Register(requestData)
        .then((res) => {
          proxy.$message({
            message: res.message,
            type: "success",
          });
        })
        .catch((error) => {
          console.log("注册错误", error);
          data.submit_button_loading = false;
        });
    };

    /** 重置 */
    const reset = () => {
      // 重置表单
      proxy.$refs.form.resetFields();
      // 切回登录模式
      data.current_menu = "login";
      // 清除定时器
      data.code_button_timer && clearInterval(data.code_button_timer);
      // 获取验证码重置文本
      data.code_button_text = "获取验证码";
      // 获取验证码激活
      data.code_button_disabled = false;
      // 禁用提交按钮
      data.submit_button_disabled = true;
      // 取消提交按钮加载
      data.submit_button_loading = false;
    };

    const data = reactive({
      form_rules: {
        username: [{ validator: validate_name_rules, trigger: "change" }],
        password: [{ validator: validate_password_rules, trigger: "change" }],
        passwords: [{ validator: validate_passwords_rules, trigger: "change" }],
        code: [{ validator: validate_code_rules, trigger: "change" }],
      },
      form: {
        username: "", // 用户名
        password: "", // 密码
        passwords: "", // 确认密码
        code: "", // 验证码
      },
      tab_menu: [
        { type: "login", label: "登录" },
        { type: "register", label: "注册" },
      ],
      /**
       * 获取验证码按钮交互
       */
      code_button_disabled: false,
      code_button_loading: false,
      code_button_text: "获取验证码",
      code_button_timer: null,
      // 提交按钮
      submit_button_disabled: true,
    });

    const toggleMenu = (type) => {
      current_menu.value = type;
    };
    let current_menu = ref(data.tab_menu[0].type);
    // const dataItem = toRefs(data);
    return {
      // ...dataItem,
      data,
      current_menu,
      toggleMenu,
      handleGetCode,
      submitForm,
      register,
      reset,
      login,
    };
  },
};
</script>
  1. css部分(使用了scss)

<style lang="scss" scoped>
#login {
  height: 100vh;
  background-color: #344a5f;
}
.form-wrap {
  width: 320px;
  padding-top: 100px;
  margin: auto;
}
.menu-tab {
  text-align: center;
  li {
    display: inline-block;
    padding: 10px 24px;
    margin: 0 10px;
    color: #fff;
    font-size: 14px;
    border-radius: 5px;
    cursor: pointer;
    &.current {
      background-color: rgba(0, 0, 0, 0.1);
    }
  }
}
.form-label {
  display: block;
  color: #fff;
  font-size: 14px;
}
</style>

(3)封装一些公共方法及样式

新建styles文件夹,然后新建几个样式文件:

  1. normalize.scss

/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */
 /* div的默认样式不存在padding和margin为0的情况*/
 html, body, span, applet, object, iframe,
 h1, h2, h3, h4, h5, h6, p, blockquote, pre,
 a, abbr, acronym, address, big, cite, code,
 del, dfn, em, img, ins, kbd, q, s, samp,
 small, strike, strong, sub, sup, tt, var,
 b, u, i, center,
 dl, dt, dd, ol, ul,
 fieldset, form, legend,
 table, caption, tbody, tfoot, thead, tr, th, td,
 article, aside, canvas, details, embed, 
 figure, figcaption, footer, header, hgroup, 
 menu, nav, output, ruby, section, summary,
 time, mark, audio, video {
   margin: 0;
   padding: 0;
   font-size: 100%;
   font: inherit;
   vertical-align: baseline;
 }
 /* HTML5 display-role reset for older browsers */
 article, aside, details, figcaption, figure, 
 footer, header, hgroup, menu, nav, section {
   display: block;
 }
 html {
    line-height: 1.15; /* 1 */
    -webkit-text-size-adjust: 100%; /* 2 */
  }
  
  /* Sections
     ========================================================================== */
  
  /**
   * Remove the margin in all browsers.
   */
  
  body {
    margin: 0;
    font-family: 'Microsoft YaHei';
    font-size: 14px;
  }
  
  /**
   * Render the `main` element consistently in IE.
   */
  
  main {
    display: block;
  }
  
  /**
   * Correct the font size and margin on `h1` elements within `section` and
   * `article` contexts in Chrome, Firefox, and Safari.
   */
  
  
  /* Grouping content
     ========================================================================== */
  
  /**
   * 1. Add the correct box sizing in Firefox.
   * 2. Show the overflow in Edge and IE.
   */
  
  hr {
    box-sizing: content-box; /* 1 */
    height: 0; /* 1 */
    overflow: visible; /* 2 */
  }
  
  /**
   * 1. Correct the inheritance and scaling of font size in all browsers.
   * 2. Correct the odd `em` font sizing in all browsers.
   */
  
  pre {
    font-family: monospace, monospace; /* 1 */
    font-size: 1em; /* 2 */
  }
  
  /* Text-level semantics
     ========================================================================== */
  
  /**
   * Remove the gray background on active links in IE 10.
   */
  
  a {
    background-color: transparent;
    text-decoration: none;
  }

  
  /**
   * 1. Remove the bottom border in Chrome 57-
   * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
   */
  
  abbr[title] {
    border-bottom: none; /* 1 */
    text-decoration: underline; /* 2 */
    text-decoration: underline dotted; /* 2 */
  }
  
  /**
   * Add the correct font weight in Chrome, Edge, and Safari.
   */
  
  b,
  strong {
    font-weight: bolder;
  }
  
  /**
   * 1. Correct the inheritance and scaling of font size in all browsers.
   * 2. Correct the odd `em` font sizing in all browsers.
   */
  
  code,
  kbd,
  samp {
    font-family: monospace, monospace; /* 1 */
    font-size: 1em; /* 2 */
  }
  
  /**
   * Add the correct font size in all browsers.
   */
  
  small {
    font-size: 80%;
  }
  
  /**
   * Prevent `sub` and `sup` elements from affecting the line height in
   * all browsers.
   */
  
  sub,
  sup {
    font-size: 75%;
    line-height: 0;
    position: relative;
    vertical-align: baseline;
  }
  
  sub {
    bottom: -0.25em;
  }
  
  sup {
    top: -0.5em;
  }
  
  /* Embedded content
     ========================================================================== */
  
  /**
   * Remove the border on images inside links in IE 10.
   */
  
  img {
    display: block;
    border-style: none;
  }
  
  /* Forms
     ========================================================================== */
  
  /**
   * 1. Change the font styles in all browsers.
   * 2. Remove the margin in Firefox and Safari.
   */
  
  button,
  input,
  optgroup,
  select,
  textarea {
    font-family: inherit; /* 1 */
    font-size: 100%; /* 1 */
    margin: 0; /* 2 */
  }
  
  /**
   * Show the overflow in IE.
   * 1. Show the overflow in Edge.
   */
  
  button,
  input { /* 1 */
    overflow: visible;
  }
  
  /**
   * Remove the inheritance of text transform in Edge, Firefox, and IE.
   * 1. Remove the inheritance of text transform in Firefox.
   */
  
  button,
  select { /* 1 */
    text-transform: none;
  }
  
  /**
   * Correct the inability to style clickable types in iOS and Safari.
   */
  
  button,
  [type="button"],
  [type="reset"],
  [type="submit"] {
    -webkit-appearance: button;
  }
  
  /**
   * Remove the inner border and padding in Firefox.
   */
  
  button::-moz-focus-inner,
  [type="button"]::-moz-focus-inner,
  [type="reset"]::-moz-focus-inner,
  [type="submit"]::-moz-focus-inner {
    border-style: none;
    padding: 0;
  }
  
  /**
   * Restore the focus styles unset by the previous rule.
   */
  
  button:-moz-focusring,
  [type="button"]:-moz-focusring,
  [type="reset"]:-moz-focusring,
  [type="submit"]:-moz-focusring {
    outline: 1px dotted ButtonText;
  }
  
  /**
   * Correct the padding in Firefox.
   */
  
  fieldset {
    padding: 0.35em 0.75em 0.625em;
  }
  
  /**
   * 1. Correct the text wrapping in Edge and IE.
   * 2. Correct the color inheritance from `fieldset` elements in IE.
   * 3. Remove the padding so developers are not caught out when they zero out
   *    `fieldset` elements in all browsers.
   */
  
  legend {
    box-sizing: border-box; /* 1 */
    color: inherit; /* 2 */
    display: table; /* 1 */
    max-width: 100%; /* 1 */
    padding: 0; /* 3 */
    white-space: normal; /* 1 */
  }
  
  /**
   * Add the correct vertical alignment in Chrome, Firefox, and Opera.
   */
  
  progress {
    vertical-align: baseline;
  }
  
  /**
   * Remove the default vertical scrollbar in IE 10+.
   */
  
  textarea {
    overflow: auto;
  }
  
  /**
   * 1. Add the correct box sizing in IE 10.
   * 2. Remove the padding in IE 10.
   */
  
  [type="checkbox"],
  [type="radio"] {
    box-sizing: border-box; /* 1 */
    padding: 0; /* 2 */
  }
  
  /**
   * Correct the cursor style of increment and decrement buttons in Chrome.
   */
  
  [type="number"]::-webkit-inner-spin-button,
  [type="number"]::-webkit-outer-spin-button {
    height: auto;
  }
  
  /**
   * 1. Correct the odd appearance in Chrome and Safari.
   * 2. Correct the outline style in Safari.
   */
  
  [type="search"] {
    -webkit-appearance: textfield; /* 1 */
    outline-offset: -2px; /* 2 */
  }
  
  /**
   * Remove the inner padding in Chrome and Safari on macOS.
   */
  
  [type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
  }
  
  /**
   * 1. Correct the inability to style clickable types in iOS and Safari.
   * 2. Change font properties to `inherit` in Safari.
   */
  
  ::-webkit-file-upload-button {
    -webkit-appearance: button; /* 1 */
    font: inherit; /* 2 */
  }
  
  /* Interactive
     ========================================================================== */
  
  /*
   * Add the correct display in Edge, IE 10+, and Firefox.
   */
  
  details {
    display: block;
  }
  
  /*
   * Add the correct display in all browsers.
   */
  
  summary {
    display: list-item;
  }
  
  /* Misc
     ========================================================================== */
  
  /**
   * Add the correct display in IE 10+.
   */
  
  template {
    display: none;
  }
  
  /**
   * Add the correct display in IE 10.
   */
  
  [hidden] {
    display: none;
  }

  ul, li { list-style: none; }
  1. elementui.scss(当时测试时用的)

.el-button-block{
    display: block;
    width: 100%;
}
  1. 新建main.scss(引入上方两个样式文件)

@import "./normalize.scss";
@import './elementui.scss'
  1. vue.config.js配置一下样式文件

  css: {
    // 是否使用css分离插件 ExtractTextPlugin
    extract: true,
    // 开启 CSS source maps?
    sourceMap: false,
    // css预设器配置项
    loaderOptions: {
      scss: {
        additionalData: `@import "./src/styles/main.scss";`,
      },
    },
    // requireModuleExtension: true,
  },
  1. 登录中封装的校验方法

新建utils文件夹,

a.validate.js

// 校验邮箱
export function validate_email(value) {
  let regEmail = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
  return regEmail.test(value);
}

// 校验密码
export function validate_password(value) {
  let regPassword = /^(?!\D+$)(?![^a-zA-Z]+$)\S{6,20}$/;
  return regPassword.test(value);
}

// 校验验证码
export function validate_code(value) {
  let regCode = /^[a-z0-9]{6}$/;
  return regCode.test(value);
}
  1. 封装请求方法

npm i axios -S

记得先在main.js中引入axios

import axios from "axios";

utils中新建request.js

import axios from "axios";
//引入element-plus
import { ElMessage } from "element-plus";
console.log("11", process.env.VUE_APP_API); //undefined??

//创建实例
const service = axios.create({
  baseURL: "/devApi", //请求地址
  timeout: 5000, //超时
});

//添加请求拦截器
service.interceptors.request.use(
  function (config) {
    //在发送请求之前做些什么
    return config;
  },
  function (error) {
    console.log(error.request);
    const errorData = JSON.parse(error.request.response);
    if (errorData.message) {
      //判断是否具有message属性
      ElMessage({
        message: errorData.message,
        type: "error",
      });
    }
    //对请求错误做些什么
    return Promise.reject(errorData);
  }
);

//添加响  应拦截器
service.interceptors.response.use(
  function (response) {
    //对响应数据做些什么
    console.log("响应数据", response);
    const data = response.data;
    if (data.resCode === 0) {
      return Promise.resolve(data);
    } else {
      ElMessage({
        message: data.message,
        type: "error",
      });
      return Promise.reject(data);
    }
  },
  function (error) {
    //对响应错误做些什么
    const errorData = JSON.parse(error.request.response);
    if (errorData.message) {
      //判断是否具有message属性
      ElMessage({
        message: errorData.message,
        type: "error",
      });
    }

    return Promise.reject(errorData);
  }
);

//暴露service
export default service;

(4)配置环境变量

和项目根路径同级,新建几个文件:

  1. .env.development

VUE_APP_API = '/devApi'

可以自定义,但是必须是VUE_APP_XXX的格式

  1. .env.production

VUE_APP_API = '/production'
  1. .env.test

VUE_APP_API = '/test'

配置完后记得在axios文件中打印一下,看下能输出自己配置的环境变量吗.

(5)配置代理(跨域)

基本大同小异,代理地址改成自己的就可以了.

  devServer: {
    open: false, //编译完成是否自动打开网页
    host: "0.0.0.0", //指定使用地址,默认是localhost,0.0.0.0代表可以被外界访问
    port: 8080,
    proxy: {
      "/devApi": {
        target: "http://v3.web-jshtml.cn/api", //(必选)API服务器的地址
        changeOrigin: true, //(必选) 是否允许跨域
        ws: false, //(可选) 是否启用websockets
        secure: false, //(可选) 是否启用https接口
        pathRewrite: {
          "^/devApi": "", //匹配开头为/devApi的字符串,并替换成空字符串
        },
      },
    },
  },

登录基本上是完成了,还有优化的点,比如说登录放在vuex中,这个我先不实现了,各位小伙伴觉得还不错的话,动手点个赞喽!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/390226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux基础篇(七)-- 用户管理

1 创建普通用户 1、创建用户 在 Linux 系统里&#xff0c;root 账户&#xff08;超级管理员&#xff09;拥有整个系统至高无上的权限&#xff0c;比如新建和添加用户。一般我们登录系统时都是以普通账户的身份登录的&#xff0c;要创建用户需要 root 权限&#xff0c;…

项目:手把手实现高并发内存池

一.前言&#xff08;一&#xff09;.项目简介高并发内存池&#xff08;ConCurrentMemoryPool&#xff09;&#xff0c;其原型是google的开源项目tcmalloc。全称是thread-cache-malloc&#xff0c;即线程缓存malloc。应用场景是多线程环境下管理内存&#xff0c;相较于malloc库函…

Mysql数据库的(超详细)安装及环境变量的配置

一、 下载MySQL Mysql官网下载地址&#xff1a;https://downloads.mysql.com/archives/installer/ 1. 选择需要的版本点击Download进行下载 本篇文章选择的8.0.26版本 二、 安装MySQL 1. 选择设置类型 双击运行mysql-installer-community-8.0.26.msi&#xff0c;这里选择是…

GoldenGate(OGG)高可用XAG介绍

XAG介绍: Oracle Grid Infrastructure提供了高可用组件去管理实现集群上面服务的高可用&#xff0c;Oracle Grid Infrastructure agent&#xff08;XAG&#xff09;是Oracle Grid Infrastructure的一个管理组件&#xff0c;通过接口AGCTL在Oracle RAC集群上为应用程序(GoldenG…

【14】linux命令每日分享——userdel删除账号

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…

Visual Studio 高级调试-企业版三大特性

前言前面两篇博客主要介绍了Visual Studio 高级调试-代码调试和Visual Studio 高级调试-Dump分析&#xff0c;这几篇博客的目的都是为了帮助大家更好的认识和使用Visual Studio&#xff0c;Visual Studio企业版订阅价格为每月250美元&#xff0c;很多同学想知道企业版有哪些特别…

IsADirectoryError: [Errno 21] Is a directory: ‘.‘

项目场景&#xff1a; 基于YOLOv5的室内场景识别 工具&#xff1a;colab 问题描述 Traceback (most recent call last): File “train.py”, line 630, in main(opt) File “train.py”, line 494, in main d torch.load(last, map_location‘cpu’)[‘opt’] File “/usr/…

docker(三)仓库的搭建、官方私有仓库的加密和认证

文章目录一、docker仓库二、仓库Registry工作原理三、搭建本地私有仓库四、配置镜像加速器五、私有仓库的加密认证1.非加密下上传拉取2.insecure registry3.仓库加密4.仓库认证一、docker仓库 什么是仓库 Docker 仓库是用来包含镜像的位置&#xff0c;Docker提供一个注册服务器…

QML集成JavaScript

在QML中可以使用现有的QML元素来创建页面&#xff0c;但QML紧密的集成了必要的JavaScript。 但QML中使用JavaScript比较严格&#xff0c;在QML中不可以添加或修改JavaScript全局对象成员&#xff0c;这样可能会使用一个未经声明的变量。 内联JavaScript 一些小型的JavaScript函…

动态规划 背包问题

动态规划 背包问题 问题描述&#xff1a; 有一个背包&#xff0c;总容量为12。有6件物品&#xff0c;每件物品的重量和价值不同&#xff0c;求在背包总容量12的前提下&#xff0c;装进物品的最大价值以及装进物品的编号 单个物品重量和价值&#xff1a; 为方便进行思考&#…

06、Eclipse 中使用 SVN

Eclipse 中使用 SVN1 在 Eclipse 中安装 SVN 客户端插件1.1 在线安装1.2 离线安装2 SVN 在 Eclipse 分享3 检出提交更新3.1 检出3.2 提交3.3 更新4 Eclipse 中 SVN 图标及其含义4.1 &#xff1f;图标4.2 图标4.3 金色圆柱图标4.4 * 图标5 恢复历史版本5.1 恢复步骤5.2 权限控制…

ks通过恶意低绩效来变相裁员(二)对cy的反套路怎么做

目录 你被cy的概率有多大 反套路1&#xff1a;直接接受&#xff0c;并拿补偿走人 反套路2&#xff1a;继续留在公司 反套路3&#xff1a;直接仲裁公司 仲裁诉求要一次性写全全部诉求 你被cy的概率有多大 既然&#xff0c;互联网寒冬下人人都可能无法幸免于cy(当然了&#…

A Simple Framework for Contrastive Learning of Visual Representations阅读笔记

论文地址&#xff1a;https://arxiv.org/pdf/2002.05709.pdf 目前流行的无监督学范式。通过训练&#xff0c;使模型拥有比较的能力。即&#xff0c;模型能够区别两个数据&#xff08;instance&#xff09;是否是相同的。这在 深度聚类 领域受到广泛的关注。&#xff08;在有监…

总线(四)Modbus总线 协议

文章目录Modbus技术背景Modbus OSI分布Moudbus分类通讯过程Moudbus协议通信过程以及报文解析RTU 与 ASCII 收发数据区别Modbus技术背景 Modbus是一种串行通信协议。 1971年&#xff0c;Modicon公司首次退出Modbus协议&#xff0c;ModbusRTU和Modbus ASCII诞生于此。 后来施耐德…

图像处理特征可视化方法总结(特征图、卷积核、类可视化CAM)(附代码)

一、前言众所周知&#xff0c;深度学习是一个"黑盒"系统。它通过“end-to-end”的方式来工作&#xff0c;输入数据例如RGB图像&#xff0c;输出目标例如类别标签、回归值等&#xff0c;中间过程不可得知。如何才能打开“黑盒”&#xff0c;一探究竟&#xff0c;让“黑…

[神经网络]Transfomer架构

一、概述 Transfomer架构与传统CNN和RNN最大的区别在于其仅依赖自注意力机制&#xff0c;而没有卷积/循环操作。其相较于RNN&#xff0c;不需要进行时序运算&#xff0c;可以更好的进行并行&#xff1b;相较于CNN&#xff0c;其一次可以关注全图而不局限于感受野尺寸。 二、模…

充电协议: 快充协议,如何选充电宝?

快充协议(存在两种&#xff1a;电压; 电流) 目前市面上的快充技术大多遵循2个技术方向&#xff1a; 以高通QC、联发科PEP、华为FCP为首的高压低电流快充技术&#xff1b; 另一种就是以OPPO的VOOC以及华为SCP为首的低电压大电流快充技术。 目前常见的快充标准还有三星AFC、联发…

Fluent自定义物理场

1 概述场&#xff08;field&#xff09;是物理的基础概念之一&#xff0c;表明了物理量在空间的分布。根据物理量的类型&#xff0c;可分为标量场&#xff08;scalar field&#xff09;、向量场&#xff08;vector field&#xff09;、张量场&#xff08;tensor field&#xff…

linux环境下安装mariadb

采用yum的形式&#xff0c;linux发行版为Rocky Linux9.1&#xff0c;安装用户为有sudo权限的用户&#xff0c;非root用户 1.查询是否已经安装过 yum list installed|grep mariadb2.安装mariadb 如果使用非root用户&#xff0c;请记得加sudo yum install mariadb sudo yum in…

SQLI-Labs(3)8-14关【布尔盲注和时间盲注】

目录 第八关 第九关&#xff1a; 第十关 第十一关 第十二关 第十三关 第十四关 第八关 我们用测试语句来测试是否为注入点 从上图中得知存在注入点&#xff0c;那么接下来就是爆列 一共有三列&#xff0c;接下来用union select 和报错注入都试一下发现没有回显点&…