Vue2开发插件并发布到npm

2023-11-16

 Vue3+TS+Vite开发插件并发布到npm

目标:创建vue-amazing-selector下拉框组件,并发布到npm,效果如下图:

默认时样式:

禁用时样式:

①创建vue项目:

vue create vue-amazing-selector

②项目目录结构截图如下:

③在项目根目录新建 packages/ 文件夹用于存放组件,由于 packages/ 是新增的,webpack无法获取编译,因此需要在webpack配置文件里加上相关配置

④在项目根目录新建 vue.config.js 配置文件,并写入一下配置:

module.exports = {
  css: { // 是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码)。
    extract: false, // 生产环境下是 true,开发环境下是 false
  },
  // 扩展 webpack 配置,使 packages 加入编译
  // chainWebpack 是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改
  chainWebpack: config => {
    config.module
      .rule('js')
      .include
      .add(__dirname + 'packages') // 注意这里需要绝对路径,所以要拼接__dirname
      .end()
      .use('babel')
      .loader('babel-loader')
      .tap(options => {
        // 修改它的选项...
        return options
      })
  }
}

⑤在 packages/ 文件夹下创建组件,新建 vue-amazing-selector/ 文件夹和 index.js 文件,截图如下: 

 ⑥在 vue-amazing-selector/ 文件加下新建 VueAmazingSelector.vue 组件文件和 index.js 文件,截图如下:

 ⑦在 VueAmazingSelector.vue 中编写组件代码:

<template>
  <div class="m-amazing-select" :style="`height: ${height}px;`">
    <div
      :class="['m-select-wrap', {'hover': !disabled, 'focus': showOptions, 'disabled': disabled}]"
      :style="`width: ${width - 2}px; height: ${height - 2}px;`"
      tabindex="0"
      @mouseenter="onInputEnter"
      @mouseleave="onInputLeave"
      @blur="activeBlur && !disabled ? onBlur() : e => e.preventDefault()"
      @click="disabled ? e => e.preventDefault() : openSelect()">
      <div
        :class="['u-select-input', {'placeholder': !selectedName}]"
        :style="`line-height: ${height - 2}px;width: ${width - 37}px; height: ${height - 2}px;`"
        :title="selectedName"
      >{{ selectedName || placeholder }}</div>
      <svg :class="['triangle', {'rotate': showOptions, 'show': !showClose}]" viewBox="64 64 896 896" data-icon="down" aria-hidden="true" focusable="false"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg>
      <svg @click.stop="onClear" :class="['close', {'show': showClose}]" focusable="false" data-icon="close-circle" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg>
    </div>
    <transition name="fade">
      <div
        v-show="showOptions"
        class="m-options-panel"
        @mouseenter="onEnter"
        @mouseleave="onLeave"
        :style="`top: ${height + 6}px; line-height: ${height - 12}px; max-height: ${ num * (height - 2) }px; width: ${width}px;`">
        <p
          v-for="(option, index) in options" :key="index"
          :class="['u-option', {'option-selected': option[label]===selectedName, 'option-hover': !option.disabled&&option[value]===hoverValue, 'option-disabled': option.disabled }]"
          :title="option[label]"
          @mouseenter="onHover(option[value])"
          @click="option.disabled ? e => e.preventDefault() : onChange(option[value], option[label], index)">
          {{ option[label] }}
        </p>
      </div>
    </transition>
  </div>
</template>
<script>
export default {
  name: 'VueAmazingSelector',
  model: {
    prop: 'selectedValue',
    event: 'model'
  },
  props: {
    options: { // 选项数据
      type: Array,
      default: () => []
    },
    label: { // 选择器字典项的文本字段名
      type: String,
      default: 'label'
    },
    value: { // 选择器字典项的值字段名
      type: String,
      default: 'value'
    },
    placeholder: { // 选择框默认文字
      type: String,
      default: '请选择'
    },
    disabled: { // 是否禁用下拉
      type: Boolean,
      default: false
    },
    allowClear: { // 是否支持清除
      type: Boolean,
      default: false
    },
    width: { // 选择框宽度
      type: Number,
      default: 200
    },
    height: { // 选择框高度
      type: Number,
      default: 36
    },
    num: { // 下拉面板最多能展示的下拉项数,超过后滚动显示
      type: Number,
      default: 6
    },
    selectedValue: { // 当前选中的option条目(v-model)
      type: [Number, String],
      default: null
    }
  },
  data () {
    return {
      selectedName: null,
      hoverValue: null, // 鼠标悬浮项的value值
      activeBlur: true, // 是否激活blur事件
      showClose: false, // 清除按钮显隐
      showOptions: false // options面板
    }
  },
  watch: {
    options () {
      this.initSelector()
      console.log('options')
    },
    selectedValue () {
      this.initSelector()
      console.log('selectedValue')
    }
  },
  mounted () {
    this.initSelector()
  },
  methods: {
    initSelector () {
      if (this.selectedValue) {
        const target = this.options.find(option => option[this.value] === this.selectedValue)
        if (target) {
          this.selectedName = target[this.label]
          this.hoverValue = target[this.value]
        } else {
          this.selectedName = this.selectedValue
          this.hoverValue = null
        }
      } else {
        this.selectedName = null
        this.hoverValue = null
      }
    },
    onBlur () {
      if (this.showOptions) {
        this.showOptions = false
      }
    },
    onInputEnter () {
  // console.log('input enter')
      if (this.allowClear && this.selectedName) {
        this.showClose = true
      }
    },
    onInputLeave () {
      // console.log('input leave')
      if (this.allowClear && this.showClose) {
        this.showClose = false
      }
    },
    onHover (value) {
      this.hoverValue = value
    },
    onEnter () {
      this.activeBlur = false
    },
    onLeave () {
      this.hoverValue = null
      this.activeBlur = true
    },
    openSelect () {
      this.showOptions = !this.showOptions
      if (!this.hoverValue && this.selectedName) {
        const target = this.options.find(option => option[this.label] === this.selectedName)
        this.hoverValue = target ? target[this.value] : null
      }
    },
    onClear () {
      this.showClose = false
      this.selectedName = null
      this.hoverValue = null
    },
    onChange (value, label, index) { // 选中下拉项后的回调
      if (this.selectedValue !== value) {
        this.selectedName = label
        this.hoverValue = value
        this.$emit('model', value)
        this.$emit('change', value, label, index)
      }
      this.showOptions = false
    }
  }
}
</script>
<style lang="less" scoped>
@themeColor: #1890ff; // 自定义主题色
P {
  margin: 0;
}
.m-amazing-select {
  position: relative;
  display: inline-block;
  font-size: 14px;
  font-weight: 400;
  color: rgba(0,0,0,.65);
}
.fade-enter-active, .fade-leave-active {
  transform: scaleY(1);
  transform-origin: 0% 0%;
  opacity: 1;
  transition: all .3s;
}
.fade-enter {
  transform: scaleY(0.8);
  transform-origin: 0% 0%;
  opacity: 0;
}
.fade-leave-to {
  transform: scaleY(1);
  opacity: 0;
}
.m-select-wrap {
  position: relative;
  display: inline-block;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  cursor: pointer;
  transition: all .3s cubic-bezier(.645,.045,.355,1);
  .u-select-input {
    display: block;
    text-align: left;
    margin-left: 11px;
    margin-right: 24px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .placeholder {
    color: #bfbfbf;
  }
  .triangle {
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto 0;
    right: 12px;
    width: 12px;
    height: 12px;
    fill: rgba(0,0,0,.25);
    opacity: 0;
    pointer-events: none;
    transition: all 0.3s ease-in-out;
  }
  .rotate {
    transform: rotate(180deg);
    -webkit-transform: rotate(180deg);
  }
  .close {
    opacity: 0;
    pointer-events: none;
    transition: all 0.3s ease-in-out;
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto 0;
    right: 12px;
    width: 12px;
    height: 12px;
    fill: rgba(140, 140, 140, 0.6);
    &:hover {
      fill: rgba(100, 100, 100,.8);
    }
  }
  .show {
    opacity: 1;
    pointer-events: auto;
  }
}
.hover { // 悬浮时样式
  &:hover {
    border-color: @themeColor;
  }
}
.focus { // 激活时样式
  border-color: @themeColor;
  box-shadow: 0 0 0 2px fade(@themeColor, 20%);
}
.disabled { // 下拉禁用样式
  color: rgba(0,0,0,.25);
  background: #f5f5f5;
  user-select: none;
  cursor: not-allowed;
}
.m-options-panel {
  position: absolute;
  z-index: 999;
  overflow: auto;
  background: #FFF;
  padding: 4px 0;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,15%);
  .u-option { // 下拉项默认样式
    text-align: left;
    position: relative;
    display: block;
    padding: 5px 12px;
    font-weight: 400;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background .3s ease;
  }
  .option-selected { // 被选中的下拉项样式
    font-weight: 600;
    background: #fafafa;
  }
  .option-hover { // 悬浮时的下拉项样式
    background: #e6f7ff;
    // background: saturate(fade(@themeColor, 12%), 30%);
  }
  .option-disabled { // 禁用某个下拉选项时的样式
    color: rgba(0,0,0,.25);
    user-select: none;
    cursor: not-allowed;
  }
}
</style>

⑧在 vue-amazing-selector/index.js 中导出组件

// 引入组件
import VueAmazingSelector from './VueAmazingSelector.vue'

// 为组件提供 install 安装方法,供按需引入
VueAmazingSelector.install = (Vue) => {
  Vue.component(VueAmazingSelector.name, VueAmazingSelector)
}

// 导出组件
export default VueAmazingSelector

⑨在 packages/index.js 文件中对整个组件库进行导出

import VueAmazingSelector from './vue-amazing-selector'
// 存储组件列表
const components = [
  VueAmazingSelector
]
/* 
  定义install 方法,接收Vue作为参数,如果使用use注册插件,则所有的组件都将被注册
*/
const install = function (Vue) {
  // 判断是否安装
  if (install.installed) { return }
  // 遍历所有组件
  components.map(component => {
    Vue.component(component.name, component)
  })
}
// 判断是否引入文件
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue)
}
export {
  VueAmazingSelector
}
export default {
  install
}

⑩在 src/main.js 中导入刚创建的组件,检测是否正常可用

import VueAmazingSelector from '../packages'
Vue.use(VueAmazingSelector)
// 在 App.vue 中引用,并启动项目查看

⑪在 package.json 的 scripts 中添加一条编译命令

--target: 构建目标,默认为应用模式。这里修改为 lib 启用库模式。
--dest : 输出目录,默认 dist。这里我们改成 lib
[entry]: 最后一个参数为入口文件,默认为 src/App.vue。这里我们指定编译 packages/ 组件库目录。

"scripts": {
	"lib": "vue-cli-service build --target lib --name selector --dest lib packages/index.js"
}

⑫执行编译命令

yarn lib(或num run lib)

执行结果如下图:

然后在项目根目录会生成如下图所示文件夹:

⑬在终端执行 npm init 初始化包配置文件package.json

package.json部分截图如下:

name: 包名,该名字是唯一的。可在 npm 官网搜索名字,不可重复。

version: 版本号,每次发布至 npm 需要修改版本号,不能和历史版本号相同。

description: 关于包的描述。

main: 入口文件,需指向最终编译后的包文件。

keyword:关键字,以空格分离希望用户最终搜索的词。

author:作者

private:是否私有,需要修改为 false 才能发布到 npm

license: 开源协议

 ⑭在项目根目录创建 .npmignore 文件,设置忽略发布的文件,类似 .gitignore 文件

只有编译后的 lib 目录、package.json、README.md是需要被发布的

# 忽略目录

.DS_Store

node_modules

packages/

public/

src/

# 忽略指定文件

.eslintrc.cjs

.gitignore

.npmignore

.npmrc

babel.config.js

vue.config.js

yarn.lock

*.map

⑮编写README.md文件(使用markdown格式)

参考文档: http://markdown.p2hp.com/index.html
# vue-amazing-selector

## An Amazing Select Component For Vue2

## Install & Use

```sh
npm install vue-amazing-selector
#or
yarn add vue-amazing-selector
```

Import and register component

**Global**

```js
import Vue from 'vue'
import VueAmazingSelector from 'vue-amazing-selector'

Vue.use(VueAmazingSelector)
```

**Local**

```vue
<template>
  <VueAmazingSelector
    :options="options"
    label="label"
    value="value"
    placeholder="请选择"
    :disabled="false"
    :width="160"
    :height="36"
    :num="6"
    v-model="selectedValue"
    @change="onChange" />
</template>
<script>
import { VueAmazingSelector } from 'vue-amazing-selector'

export default {
  components: {
    VueAmazingSelector
  }
}
</script>
```

## Props

| 属性 | 说明 | 类型 | 默认值 |
| :--- | :--- | :--- | :--- |
options | 选项数据 | Array | []
label | 选择器字典项的文本字段名 | String | label
value | 选择器字典项的值字段名 | String | value
placeholder | 选择框默认文字 | String | 请选择
disabled | 是否禁用下拉 | Boolean | false
allowClear | 是否支持清除 | Boolean | false
width | 选择框宽度 | Number | 200
height | 选择框高度 | Number | 36
num | 下拉面板最多能展示的下拉项数,超过后滚动显示 | Number | 6
selectedValue | (v-model)当前选中的option条目 | /Number/String | null

## Events

事件名 | 说明 | 返回值
:--- | :--- | :---
change | 选择某项下拉后的回调函数 | value, label, index(value值,label文本值,index索引值)

⑯登录npm

如果没有npm账号,可以去npm官网( npm) 注册一个账号

注册成功后在本地查看npm镜像:

npm config get registry

输出:https://registry.npmjs.org 即可

如果不是则需要设置为npm镜像:

npm config set registry https://registry.npmjs.org

然后在终端执行:

npm login

依次输入用户名,密码,邮箱

输出Logged in as…即可

npm whoami // 查看当前用户是否已登录

⑰发布组件到npm

在终端执行:npm publish

发布成功后即可在npm官网搜索到该组件,如下图;并可以通过 npm install vue-amazing-selector(或yarn add vue-amazing-selector)进行安装

⑱在要使用的项目中安装并注册插件

yarn add vue-amazing-selector

// 在 main.js 文件中引入并注册:
import Vue from 'vue'
import VueAmazingSelector from 'vue-amazing-selector'
Vue.use(VueAmazingSelector)

在要使用组件的页面直接使用即可:

<template>
  <VueAmazingSelector
    :options="options"
    label="label"
    value="value"
    placeholder="请选择"
    :disabled="false"
    :width="160"
    :height="36"
    :num="6"
    v-model="selectedValue"
    @change="onChange" />
</template>
<script>
export default {
  name: 'App',
  data () {
    return {
      options: [
        {
          label: '北京市',
          value: 1
        },
        {
          label: '上海市上海市上海市上海市',
          value: 2,
          disabled: true
        },
        {
          label: '郑州市',
          value: 3
        },
        {
          label: '纽约市纽约市纽约市纽约市',
          value: 4
        },
        {
          label: '旧金山',
          value: 5
        },
        {
          label: '悉尼市',
          value: 6
        },
        {
          label: '伦敦市',
          value: 7
        },
        {
          label: '巴黎市',
          value: 8
        }
      ],
      selectedValue: 1
    }
  },
  watch: {
    selectedValue (to) {
      console.log('selectedValue:', to)
    }
  },
  mounted () {
    setTimeout(() => { // 模拟接口调用
      this.selectedValue = 3
    }, 1000)
  },
  methods: {
    onChange (value, label, index) {
      console.log('item:', value, label, index)
    }
  }
}
</script>

less-loader版本过高问题:

yarn add less-loader安装版本过高,报错如图

解决:yarn add less-loader@6.0.0

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue2开发插件并发布到npm 的相关文章

  • 开玩笑错误意外的令牌...(ES6)

    每当我在命令行中运行 jest 时 都会收到以下错误 Test suite failed to run Users
  • Javascript 函数指针,以参数作为函数中的参数

    不确定标题的措辞是否正确 或者是否有更好的表达方式 但我认为还可以 无论如何 到目前为止我了解以下内容 a b a b c foo 其中 foo 是在其他地方定义的函数 不接受任何参数 只会导致函数 a b 使用上述参数运行 然后可以在函数
  • 节点异步循环 - 如何使该代码按顺序运行?

    我知道有几个关于此的帖子 但根据我发现的那些帖子 这应该可以正常工作 我想在循环中发出 http 请求 并且不希望循环迭代 直到触发请求回调 我正在使用异步库 如下所示 const async require async const req
  • 在设置后用 Javascript 替换 'var' css 属性

    我有一个元素 其上设置了 var 属性 如下所示 div class divwithbackground div CSS divwithbackground after background image var page header se
  • 如何将 scala 列表转换为 javascript 数组?

    有更简单的方法吗 document ready function var jsArray if scalaList null for id lt scalaList jsArray push id 很简单 如下所示 import play
  • Sequelize 关联 - 请改用 Promise 风格

    我正在尝试将 3 张桌子连接在一起Products Suppliers and Categories然后排SupplierID 13 我读过了如何在sequelize中实现多对多关联 https stackoverflow com a 25
  • 当key未知时如何获取js对象中的属性值

    我有一个对象数组 a 81 25 p 81 25 81 26 p 81 26 我想循环遍历数组并获取值p在每个元素中 for var key in a console log a key outputs 81 25 Object How d
  • Jquery:排除元素

    我有以下代码 document ready function a rel each function this qtip content text img class middle src i icon processing gif alt
  • 如何使用javascript将视频文件转换为字符串?

    我在 signalR 工作 我想通过将视频文件拆分为不同部分来将视频文件从一个客户端发送到另一个客户端 我已经通过分割图像源数据发送图像并在另一个客户端上接收该图像 document getElementById fileUpload ad
  • AngularJS 服务并承诺最佳实践

    我有一个 AngularJS 应用程序services 调用 http资源并返回promise我在控制器中解决了这个问题 这是我正在做的事情的示例 app service Blog function http q var deferred
  • 如何使用 javascript 将我的域名字母大写?

    假设我的域名是www hello com 如何使用 jQuery JavaScript 使浏览器的 URL 栏看起来像 www HELLO com 您无法更改浏览器地址栏中显示的内容 这是一项基本的安全功能 您可以使您的域名全部大写 并将页
  • 如何将值从孩子的孩子传递给父母?

    我有一个父组件 有一个子组件 它也有一个子组件 Parent Child One child of parent Child Two child of child 当在子二中定义一个值时 我使用回调将该值传递给子一 但我也想将相同的值传递回
  • 如何在没有 jQuery 或延迟加载的情况下推迟背景图像

    根据帕特里克 塞克斯顿tutorial https varvy com pagespeed defer images html 我想以与这里相同的方式推迟背景图像img img src data image png base64 R0lGO
  • 反转比例函数

    这对我来说很有趣 看下面的D3代码 var scale d3 scale linear domain 100 500 range 10 350 scale 100 Returns 10 scale 300 Returns 180 scale
  • 如何在 getStaticPaths 内添加 params 值数组

    我有一个页面 其结构如下 read slug number 我想要得到slug每个对应的值number in the getStaticPaths这是代码 export async function getStaticPaths const
  • JS - 如何将图像对象变成灰度并显示它

    基本上 当单击按钮时 它会告诉移动设备转到相机 一旦相机拍照 它就会给我图像数据 它被称为数据 URL 吗 这是我处理它的代码 var imagesrc data image jpeg base64 imageData var myimag
  • 如何加载Jquery Tiny滚动条

    所以我想自定义一个滚动条 我发现了一个很小的滚动条 这是一个jquery插件 http baijs nl tinyscrollbar http baijs nl tinyscrollbar 问题是 无论如何我都无法让它工作 我将 Jquer
  • 数组长度未定义[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我试图按如
  • 如何在控制台中隐藏日志消息的来源?

    当将消息输出到控制台时 还会显示源代码 在 Chrome 开发者工具中 它位于右侧 console log Foo Source Foo test js 1 Output 但是 在某些网站上 会显示消息without正在显示的源 例如Fac
  • gjs 如何使用 g_data_input_stream_read_line_async 在 Gnome Shell 扩展中读取套接字流

    我正在尝试编写一个 Gnome Shell 扩展 通过 Socket 服务器与 Arduino 进行通信 服务器和 Arduino 运行良好 但我陷入了监听传入服务器消息的扩展代码 因为我需要一种非阻塞方法 所以使用异步读取行 https

随机推荐

  • Linux脚本练习之script092- 判断输入的是否为IP地址

    script092 题目 注 题目来源于 SHELL16 判断输入的是否为IP地址 写一个脚本统计文件nowcoder txt中的每一行是否是正确的IP地址 如果是正确的IP地址输出 yes 如果是错误的IP地址 四段号码的话输出 no 否
  • SPECjbb 分析与使用

    SPECjbb 分析与使用 一 目的 二 SPECjbb 简介 2 1 是什么 2 2 三层客户 服务器模型结构 2 3 特性 三 环境说明 四 TPC C 简介 4 1 是什么 4 2 TPC C模型 4 3 TPC C指标 4 4 TP
  • dword ptr指令讲解

    dword ptr指令讲解 8086CPU的指令 可以处理两种尺寸的数据 byte和word 所以在机器指令中要指明 指令进行的是字操作还是字节操作 对于这个问题 汇编语言中用一下方法处理 1 通过寄存器名指明要处理的数据的尺寸 例如 下面
  • linux配置交换内存(虚拟内存)

    虚拟内存 Virtual Memory 是操作系统内存管理的一种技术 它将主存虚拟化 使得程序可以获得更大的可用内存空间 虚拟内存的主要优点有 提高内存利用率 可以加载更大的程序到内存中执行 提供了内存保护 避免程序间相互干扰 实现了懒加载
  • 【FPGA多周期约束】

    多周期约束及语法 一 什么时候需要用到多周期约束 Vivado TimeQuest等时序引擎默认是按照单周期关系分析数据关系的 即数据在发起沿发送 在捕获被捕获 发起沿和捕获沿相差一个周期 但是很多情况是 数据路径逻辑较为复杂 导致延时较大
  • 朴素贝叶斯基本原理和预测过程、先验概率、后验概率、似然概率概念

    贝叶斯原理是英国数学家托马斯 贝叶斯提出的 贝叶斯原理 建立在主观判断的基础上 在我们不了解所有客观事实的情况下 同样可以先估计一个值 然后根据实际结果不断进行修正 举例 一个袋子里有10个球 其中6个黑球 4个白球 那么随机抓一个黑球的概
  • 关于电商秒杀系统中防超卖、以及高性能下单的处理方案简述

    秒杀抢购系统的成功平稳运行 有一些需要注意的知识点 1 高并发 以及刷接口等黑客请求对服务端的负载冲击 2 高并发时带来的超卖 即商品数量的控制 3 高负载下 下单的速度和成功率的保证 4 其他 以秒杀单品为例 如抢小米手机 解决方案探讨
  • 大型网站架构核心要素之可用性:高可用架构

    前言 上节我们讲了网站核心要素之性能 这节我们接着讲第二个核心要素可用性 网站的可用性 描述的是一个网站是否可以正常使用的特性 这个特性是比较关键的 直接影响公司形象和利益 因此也有很多大公司把这点作为技术人员的绩效考核之一 既然那么重要
  • Springboot毕设项目地铁站自动售票系统77x9w(java+VUE+Mybatis+Maven+Mysql)

    项目运行 环境配置 Jdk1 8 Tomcat8 5 Mysql HBuilderX Webstorm也行 Eclispe IntelliJ IDEA Eclispe MyEclispe Sts都支持 项目技术 Springboot myb
  • Plotly Express 详细使用指南,20组案例从入门到进阶(附源代码)

    作者 阳哥 出品 Python数据之道 ID PyDataLab 大家好 我是阳哥 今天跟大家分享的是 Plotly Express 的详细使用教程 Plotly Express 是 Python 交互式可视化库 Plotly 的高级组件
  • 【Deepin-15.11】下【Datax】使用【插件】进行【csv文件读写】

    接上 1 将Downloads目录下的压缩包放到指定文件夹下 题目要求 2 按照要求创建文件夹 题目要求 3 Github Datax txtfilereader模板官网将模板copy下来 写入文本文档并修改后缀名 复制到job 题目指定
  • Android Studio 中如何添加ViewModelProviders依赖?

    我的做法是在class类中直接导入文件 import androidx lifecycle ViewModelProvidels 一个小白 就当是记录一下啦
  • 86-信号和槽-信号与槽的参数

    信号与槽的参数 上节介绍了信号与槽的基本使用方法 本节介绍其参数传递的情况 通过为槽函数传递特定的参数 可以实现更复杂的功能 既可以传递 Qt 的内置参数 也可以传递自定义参数 当然 内置参数和自定义参数也可以放在一起传递 自定义参数既可以
  • 不习惯的 Vue3 起步六 の Echarts绘制下钻地图

    序 看过一些可视化大屏展示地图的例子 准备动手做做 既然要开始比制作 那么先把目标定好 做一个展示中国城市的下钻地图 使用 Vue3 Vite Typescript echarts 实现效果 准备工作 创建项目 因为准备使用Vue3 Vit
  • Vue——自定义指令

    自定义全局指令 注 使用指令时必须在指名名称前加前缀v 即v 指令名称 Vue directive hello bind 常用 alert 指令第一次绑定到元素上时调用 只调用一次 可执行初始化操作 inserted alert 被绑定元素
  • 【上位机】通过QTCreator编写WIFI上位机与网络调试助手通信绘制曲线

    文章目录 前言 一 使用QT Creator编写上位机 二 上位机与网络调试助手联调 三 总结 前言 17年电赛H题中要求编写WIFI上位机实现远程幅频特性曲线显示 以下是本人在近期摸索出来的一些心得及体会 一 使用QT Creator编写
  • 目前有哪些好用的测试管理工具?

    PingCode Testhub Zephyr for jira 禅道等都是当下不错的测试管理工具 其实就测试用例管理工具或Bug管理工具来说 当前市场上种类并不少 功能也各有特色 我们在工具选型过程中最大的问题并不是不知道有哪些好的工具
  • FastDFS单机部署安装

    FastDFS单机部署安装 文章目录 FastDFS单机部署安装 前言 1 服务器规划 2 安装包 3 所有tracker和storage节点都执行如下操作 3 1 安装所需的依赖包 3 2 安装libfatscommon 3 3 安装Fa
  • mac电脑屏幕录制Berrycast Mac屏幕录制软件

    Berrycast是一款为Mac设计的优秀屏幕录制软件 它让屏幕录制变得简单而高效 以下是Berrycast的一些主要特点 简单的用户界面 Berrycast拥有直观和简洁的用户界面 使得用户可以轻松上手 高质量的视频输出 Berrycas
  • Vue2开发插件并发布到npm

    Vue3 TS Vite开发插件并发布到npm 目标 创建vue amazing selector下拉框组件 并发布到npm 效果如下图 默认时样式 禁用时样式 创建vue项目 vue create vue amazing selector