vuejs怎样封装一个插件(以封装vue-toast为例扩展)
插件介绍
插件通常会为 Vue 添加全局功能。插件的范围没有限制——一般有下面几种:
- 1.添加全局方法或者属性,如: vue-custom-element
- 2.添加全局资源:指令/过滤器/过渡等,如 vue-touch
- 3.通过全局 mixin 方法添加一些组件选项,如: vue-router
- 4.添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
- 5.一个库,提供自己的 API,同时提供上面提到的一个或多个功能,如 vue-router
Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
// 逻辑...
}
// 2. 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
// 3. 注入组件
Vue.mixin({
created: function () {
// 逻辑...
}
...
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}
}
使用方式很简单,通过全局方法Vue.use()来使用插件。
下面开发一个简单的在控制台打印消息插件,新建一个toast.js:
var Toast = {};
Toast.install = function (Vue, options) {
Vue.prototype.$msg = 'Hello World';
}
export default Toast;
在main.js中引入该toast.js并使用vue.use()安装该toast插件:
import Vue from 'vue';
import Toast from './toast.js';
Vue.use(Toast);
然后我们在任意vue页面就可以调用:
export default {
mounted(){
console.log(this.$msg); // Hello World
}
}
开发vue-toast插件
该插件实现的效果:
- 1.提示内容可以显示在不同的位置(顶部、底部、中间),调用方式this.$toast.top('填写的提示内容')、this.$toast.center('填写的提示内容')、this.$toast.bottom('填写的提示内容');
- 2.通过this.$toast('填写的提示内容')调用该插件,默认展示在底部;
- 3.toast有默认的展示持续时间,也可配置toast展示的持续时间。
toast.js实现代码如下:
let Toast = {};
Toast.install = function(Vue,options) {
let opts = {
type: 'bottom', // 显示位置
duration: 2500 // 持续时间
}
for(let prop in options) {
if(options.hasOwnProperty(prop)) {
opts[prop] = options[prop];
}
}
Vue.prototype.$toast = (tips,type) => {
if(type) {
opts.type = type;
}
if(document.getElementsByClassName('vue-toast').length) {
return false;
}
let ToastEl = Vue.extend({
template: `<div class="vue-toast vue-toast__${opts.type}">${tips}</div>`
})
let toastElement = new ToastEl().$mount().$el;
document.body.append(toastElement);
setTimeout(() => {
document.body.removeChild(toastElement);
},opts.duration);
}
['top','center','bottom'].forEach((type) => {
Vue.prototype.$toast[type] = (tips) => {
return Vue.prototype.$toast(tips,type)
}
})
}
export default Toast;
优化vue-toast
调用方式更通用,如下所示:
this.toast = this.$toast({
message: '这是一段信息',
position: 'top',
duration: 0
});
可以手动关闭弹框
this.toast.close();
实现方式就是封装成一个构造函数,整体代码如下:
function Toast() {
this.toastTimer = false; // toastTimer:toast定时器
this.toastVM = null; // toastVM:存储toast VM
this.install = function(Vue,options) {
let opts = {
message: '', // 文本内容
position: 'bottom', // 显示位置
duration: 2500, // 展示时长(ms),值为 0 时,toast 不会消失
className: '' // 自定义类名
}
/** toast提示方法
* @params {Object|String} config 配置,如果为字符串=message
* */
Vue.prototype.$toast = (config) => {
let option = {};
let self = this;
Object.assign(option,opts,options);
if(typeof config === 'object') {
Object.assign(option,config)
} else { // 如果是字符串,传递的是message文本内容
option.message = config;
}
if(this.toastTimer) { // 如果toast还在,则取消上次消失时间
clearTimeout(this.toastTimer);
this.toastVM.show = false;
}
if(!this.toastVM) {
let ToastEl = Vue.extend({
data() {
return {
show: false,
message: option.message,
className: option.className
}
},
methods: {
// 关闭toast
close() {
self.toastVM.show = false;
}
},
render(createElement) {
if(!this.show) {
return false;
}
return createElement(
'div',
{
class: ['lx-toast',`lx-toast-${option.position}`,this.className],
show: this.show,
domProps: {
innerHTML: this.message
}
},
)
}
})
this.toastVM = new ToastEl();
document.body.append(this.toastVM.$mount().$el);
}
this.toastVM.show = true;
this.toastVM.message = option.message;
this.toastVM.className = option.className;
this.toastVM.position = option.position;
if(option.duration != 0) {// 为0的时候一直显示
this.toastTimer = setTimeout(() => {
this.toastVM.show = this.toastTimer = false;
},option.duration)
}
return this.toastVM;
}
}
}
export default new Toast();
使用方式:
<template>
<div class="test">
<button @click="open">开启弹框</button>
<button @click="close">关闭弹框</button>
</div>
</template> <script>
export default {
data () {
return {
toast: null
}
}, methods: {
open() {
this.toast = this.$toast({
message: '这是一段信息',
position: 'top',
duration: 0
});
},
close() {
this.toast.close();
}
}
}
</script>
添加loading方法
完整代码:
function Toast() {
this.toastTimer = false; // toastTimer:toast定时器
this.toastVM = null; // toastVM:存储toast VM
this.showLoad = false; // 存储loading显示状态
this.loadNode = null; // 存储loading节点元素
this.install = function(Vue,options) {
let opts = {
message: '', // 文本内容
position: 'bottom', // 显示位置
duration: 2500, // 展示时长(ms),值为 0 时,toast 不会消失
className: '' // 自定义类名
}
/** toast提示方法
* @params {Object|String} config 配置,如果为字符串=message
* */
Vue.prototype.$toast = (config) => {
let option = {};
let self = this;
Object.assign(option,opts,options);
if(typeof config === 'object') {
Object.assign(option,config)
} else { // 如果是字符串,传递的是message文本内容
option.message = config;
}
if(this.toastTimer) { // 如果toast还在,则取消上次消失时间
clearTimeout(this.toastTimer);
this.toastVM.show = false;
}
if(!this.toastVM) {
let ToastEl = Vue.extend({
data() {
return {
show: false,
message: option.message,
className: option.className
}
},
methods: {
// 关闭toast
close() {
self.toastVM.show = false;
}
},
render(createElement) {
if(!this.show) {
return false;
}
return createElement(
'div',
{
class: ['lx-toast',`lx-toast-${option.position}`,this.className],
show: this.show,
domProps: {
innerHTML: this.message
}
},
)
}
})
this.toastVM = new ToastEl();
document.body.append(this.toastVM.$mount().$el);
}
this.toastVM.show = true;
this.toastVM.message = option.message;
this.toastVM.className = option.className;
this.toastVM.position = option.position;
if(option.duration != 0) {// 为0的时候一直显示
this.toastTimer = setTimeout(() => {
this.toastVM.show = this.toastTimer = false;
},option.duration)
}
return this.toastVM;
}
/** $loading加载
* @params {Object|String} config 配置,如果为字符串=message
* */
Vue.prototype.$loading = (config) => {
let option = {};
let self = this;
if(typeof config === 'object') {
Object.assign(option,config)
} else { // 传递的字符串
option.message = config;
}
if(option.type == 'close') {
if(this.loadNode) {
this.loadNode.show = this.showLoad = false;
}
} else {
if(this.showLoad && this.loadNode) {
this.loadNode.message = option.message;
return false;
}
const loadEl = Vue.extend({
data() {
return {
show: false,
message: option.message
}
},
methods: {
close() {
self.loadNode.show = self.showLoad = false;
}
},
render(h) {
if(!this.show) {
return false;
}
return h('div',{
class: 'lx-load-mark',
show: this.show
},[
h('div',{
class: 'lx-load-box'
},[
h('div',{
class: this.message ? 'lx-loading':'lx-loading-nocontent'
},Array.apply(null,{length: 12}).map((value,index) => {
return h('div',{
class: ['loading_leaf',`loading_leaf_${index}`]
})
})),
h('div',{
class: 'lx-load-content',
domProps: {
innerHTML: this.message
}
})
])
])
}
})
this.loadNode = new loadEl();
document.body.appendChild(this.loadNode.$mount().$el);
this.loadNode.show = this.showLoad = true;
}
return this.loadNode;
}
['open','close'].forEach(type => {
Vue.prototype.$loading[type] = (message) => {
return Vue.prototype.$loading({type,message})
}
})
}
}
export default new Toast();
完整的调用方式:
<template>
<div class="test">
<button @click="open">开启弹框</button>
<button @click="close">关闭弹框</button>
</div>
</template> <script>
export default {
data () {
return {
toast: null
}
}, mounted() {
let loading = this.$loading({
message: '这是loading文字'
}) setTimeout(() => { // 5s 后关闭弹框
loading.close();
},5000);
}, methods: {
open() {
this.toast = this.$toast({
message: '这是一段信息',
position: 'top',
duration: 0
});
},
close() {
this.toast.close();
}
}
}
</script>
toast.css代码:
.lx-toast {
position: fixed;
bottom: 100px;
left: 50%;
-webkit-box-sizing: border-box;
box-sizing: border-box;
max-width: 80%;
height: 40px;
line-height: 20px;
padding: 10px 20px;
transform: translateX(-50%);
-webkit-transform: translateX(-50%);
text-align: center;
z-index: 9999;
font-size: 14px;
color: #fff;
border-radius: 5px;
background: rgba(0, 0, 0, 0.7);
animation: show-toast .5s;
-webkit-animation: show-toast .5s;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.lx-toast.lx-word-wrap {
width: 80%;
white-space: inherit;
height: auto;
}
.lx-toast.lx-toast-top {
top: 50px;
bottom: inherit;
}
.lx-toast.lx-toast-center {
top: 50%;
margin-top: -20px;
bottom: inherit;
}
@-webkit-keyframes show-toast {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes show-toast {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.lx-load-mark {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 9999;
}
.lx-load-box {
position: fixed;
z-index: 3;
width: 7.6em;
min-height: 7.6em;
top: 180px;
left: 50%;
margin-left: -3.8em;
background: rgba(0, 0, 0, 0.7);
text-align: center;
border-radius: 5px;
color: #FFFFFF;
}
.lx-load-content {
margin-top: 64%;
font-size: 14px;
}
.lx-loading, .lx-loading-nocontent {
position: absolute;
width: 0px;
left: 50%;
top: 38%;
}
.lx-loading-nocontent {
top: 50%;
}
.loading_leaf {
position: absolute;
top: -1px;
opacity: 0.25;
}
.loading_leaf:before {
content: " ";
position: absolute;
width: 9.14px;
height: 3.08px;
background: #d1d1d5;
-webkit-box-shadow: rgba(0, 0, 0, 0.0980392) 0px 0px 1px;
box-shadow: rgba(0, 0, 0, 0.0980392) 0px 0px 1px;
border-radius: 1px;
-webkit-transform-origin: left 50% 0px;
transform-origin: left 50% 0px;
}
.loading_leaf_0 {
-webkit-animation: opacity-0 1.25s linear infinite;
animation: opacity-0 1.25s linear infinite;
}
.loading_leaf_0:before {
-webkit-transform: rotate(0deg) translate(7.92px, 0px);
transform: rotate(0deg) translate(7.92px, 0px);
}
.loading_leaf_1 {
-webkit-animation: opacity-1 1.25s linear infinite;
animation: opacity-1 1.25s linear infinite;
}
.loading_leaf_1:before {
-webkit-transform: rotate(30deg) translate(7.92px, 0px);
transform: rotate(30deg) translate(7.92px, 0px);
}
.loading_leaf_2 {
-webkit-animation: opacity-2 1.25s linear infinite;
animation: opacity-2 1.25s linear infinite;
}
.loading_leaf_2:before {
-webkit-transform: rotate(60deg) translate(7.92px, 0px);
transform: rotate(60deg) translate(7.92px, 0px);
}
.loading_leaf_3 {
-webkit-animation: opacity-3 1.25s linear infinite;
animation: opacity-3 1.25s linear infinite;
}
.loading_leaf_3:before {
-webkit-transform: rotate(90deg) translate(7.92px, 0px);
transform: rotate(90deg) translate(7.92px, 0px);
}
.loading_leaf_4 {
-webkit-animation: opacity-4 1.25s linear infinite;
animation: opacity-4 1.25s linear infinite;
}
.loading_leaf_4:before {
-webkit-transform: rotate(120deg) translate(7.92px, 0px);
transform: rotate(120deg) translate(7.92px, 0px);
}
.loading_leaf_5 {
-webkit-animation: opacity-5 1.25s linear infinite;
animation: opacity-5 1.25s linear infinite;
}
.loading_leaf_5:before {
-webkit-transform: rotate(150deg) translate(7.92px, 0px);
transform: rotate(150deg) translate(7.92px, 0px);
}
.loading_leaf_6 {
-webkit-animation: opacity-6 1.25s linear infinite;
animation: opacity-6 1.25s linear infinite;
}
.loading_leaf_6:before {
-webkit-transform: rotate(180deg) translate(7.92px, 0px);
transform: rotate(180deg) translate(7.92px, 0px);
}
.loading_leaf_7 {
-webkit-animation: opacity-7 1.25s linear infinite;
animation: opacity-7 1.25s linear infinite;
}
.loading_leaf_7:before {
-webkit-transform: rotate(210deg) translate(7.92px, 0px);
transform: rotate(210deg) translate(7.92px, 0px);
}
.loading_leaf_8 {
-webkit-animation: opacity-8 1.25s linear infinite;
animation: opacity-8 1.25s linear infinite;
}
.loading_leaf_8:before {
-webkit-transform: rotate(240deg) translate(7.92px, 0px);
transform: rotate(240deg) translate(7.92px, 0px);
}
.loading_leaf_9 {
-webkit-animation: opacity-9 1.25s linear infinite;
animation: opacity-9 1.25s linear infinite;
}
.loading_leaf_9:before {
-webkit-transform: rotate(270deg) translate(7.92px, 0px);
transform: rotate(270deg) translate(7.92px, 0px);
}
.loading_leaf_10 {
-webkit-animation: opacity-10 1.25s linear infinite;
animation: opacity-10 1.25s linear infinite;
}
.loading_leaf_10:before {
-webkit-transform: rotate(300deg) translate(7.92px, 0px);
transform: rotate(300deg) translate(7.92px, 0px);
}
.loading_leaf_11 {
-webkit-animation: opacity-11 1.25s linear infinite;
animation: opacity-11 1.25s linear infinite;
}
.loading_leaf_11:before {
-webkit-transform: rotate(330deg) translate(7.92px, 0px);
transform: rotate(330deg) translate(7.92px, 0px);
}
@-webkit-keyframes opacity-0 {
0% {
opacity: 0.25;
}
0.01% {
opacity: 0.25;
}
0.02% {
opacity: 1;
}
60.01% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@keyframes opacity-0 {
0% {
opacity: 0.25;
}
0.01% {
opacity: 0.25;
}
0.02% {
opacity: 1;
}
60.01% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-1 {
0% {
opacity: 0.25;
}
8.34333% {
opacity: 0.25;
}
8.35333% {
opacity: 1;
}
68.3433% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@keyframes opacity-1 {
0% {
opacity: 0.25;
}
8.34333% {
opacity: 0.25;
}
8.35333% {
opacity: 1;
}
68.3433% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-2 {
0% {
opacity: 0.25;
}
16.6767% {
opacity: 0.25;
}
16.6867% {
opacity: 1;
}
76.6767% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@keyframes opacity-2 {
0% {
opacity: 0.25;
}
16.6767% {
opacity: 0.25;
}
16.6867% {
opacity: 1;
}
76.6767% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-3 {
0% {
opacity: 0.25;
}
25.01% {
opacity: 0.25;
}
25.02% {
opacity: 1;
}
85.01% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@keyframes opacity-3 {
0% {
opacity: 0.25;
}
25.01% {
opacity: 0.25;
}
25.02% {
opacity: 1;
}
85.01% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-4 {
0% {
opacity: 0.25;
}
33.3433% {
opacity: 0.25;
}
33.3533% {
opacity: 1;
}
93.3433% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@keyframes opacity-4 {
0% {
opacity: 0.25;
}
33.3433% {
opacity: 0.25;
}
33.3533% {
opacity: 1;
}
93.3433% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-5 {
0% {
opacity: 0.270958333333333;
}
41.6767% {
opacity: 0.25;
}
41.6867% {
opacity: 1;
}
1.67667% {
opacity: 0.25;
}
100% {
opacity: 0.270958333333333;
}
}
@keyframes opacity-5 {
0% {
opacity: 0.270958333333333;
}
41.6767% {
opacity: 0.25;
}
41.6867% {
opacity: 1;
}
1.67667% {
opacity: 0.25;
}
100% {
opacity: 0.270958333333333;
}
}
@-webkit-keyframes opacity-6 {
0% {
opacity: 0.375125;
}
50.01% {
opacity: 0.25;
}
50.02% {
opacity: 1;
}
10.01% {
opacity: 0.25;
}
100% {
opacity: 0.375125;
}
}
@keyframes opacity-6 {
0% {
opacity: 0.375125;
}
50.01% {
opacity: 0.25;
}
50.02% {
opacity: 1;
}
10.01% {
opacity: 0.25;
}
100% {
opacity: 0.375125;
}
}
@-webkit-keyframes opacity-7 {
0% {
opacity: 0.479291666666667;
}
58.3433% {
opacity: 0.25;
}
58.3533% {
opacity: 1;
}
18.3433% {
opacity: 0.25;
}
100% {
opacity: 0.479291666666667;
}
}
@keyframes opacity-7 {
0% {
opacity: 0.479291666666667;
}
58.3433% {
opacity: 0.25;
}
58.3533% {
opacity: 1;
}
18.3433% {
opacity: 0.25;
}
100% {
opacity: 0.479291666666667;
}
}
@-webkit-keyframes opacity-8 {
0% {
opacity: 0.583458333333333;
}
66.6767% {
opacity: 0.25;
}
66.6867% {
opacity: 1;
}
26.6767% {
opacity: 0.25;
}
100% {
opacity: 0.583458333333333;
}
}
@keyframes opacity-8 {
0% {
opacity: 0.583458333333333;
}
66.6767% {
opacity: 0.25;
}
66.6867% {
opacity: 1;
}
26.6767% {
opacity: 0.25;
}
100% {
opacity: 0.583458333333333;
}
}
@-webkit-keyframes opacity-9 {
0% {
opacity: 0.687625;
}
75.01% {
opacity: 0.25;
}
75.02% {
opacity: 1;
}
35.01% {
opacity: 0.25;
}
100% {
opacity: 0.687625;
}
}
@keyframes opacity-9 {
0% {
opacity: 0.687625;
}
75.01% {
opacity: 0.25;
}
75.02% {
opacity: 1;
}
35.01% {
opacity: 0.25;
}
100% {
opacity: 0.687625;
}
}
@-webkit-keyframes opacity-10 {
0% {
opacity: 0.791791666666667;
}
83.3433% {
opacity: 0.25;
}
83.3533% {
opacity: 1;
}
43.3433% {
opacity: 0.25;
}
100% {
opacity: 0.791791666666667;
}
}
@keyframes opacity-10 {
0% {
opacity: 0.791791666666667;
}
83.3433% {
opacity: 0.25;
}
83.3533% {
opacity: 1;
}
43.3433% {
opacity: 0.25;
}
100% {
opacity: 0.791791666666667;
}
}
@-webkit-keyframes opacity-11 {
0% {
opacity: 0.895958333333333;
}
91.6767% {
opacity: 0.25;
}
91.6867% {
opacity: 1;
}
51.6767% {
opacity: 0.25;
}
100% {
opacity: 0.895958333333333;
}
}
@keyframes opacity-11 {
0% {
opacity: 0.895958333333333;
}
91.6767% {
opacity: 0.25;
}
91.6867% {
opacity: 1;
}
51.6767% {
opacity: 0.25;
}
100% {
opacity: 0.895958333333333;
}
}
参考
vuejs怎样封装一个插件(以封装vue-toast为例扩展)的更多相关文章
- 浅析vue封装自定义插件
在使用vue的过程中,经常会用到Vue.use,但是大部分对它一知半解,不了解在调用的时候具体做了什么,因此,本文简要概述下在vue中,如何封装自定义插件. 在开始之前,先补充一句,其实利用vue封装 ...
- 基于iview 封装一个vue 表格分页组件
iview 是一个支持中大型项目的后台管理系统ui组件库,相对于一个后台管理系统的表格来说分页十分常见的 iview是一个基于vue的ui组件库,其中的iview-admin是一个已经为我们搭好的后天 ...
- vue从入门到进阶:自定义指令directive,插件的封装以及混合mixins(七)
一.自定义指令directive 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令.注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件.然而,有的 ...
- vue封装第三方插件并发布到npm
前言 写此文前特意google了一下,因为有较详细的开发教程我再写意义不大,有把插件封装成组件的教程,有把自己的组件封住成插件的教程,本文主要说明如何把第三方的插件封装成vue插件,简化配置,一键安装 ...
- Vue.use源码分析(转)+如何封装一个组件
封装一个组件:https://www.jianshu.com/p/89a05706917a 我想有过vue开发经验的,对于vue.use并不陌生.当使用vue-resource或vue-router等 ...
- 使用vue.js封装一个包含图片的跑马灯组件
初衷: 学习完Vuejs后,来准备练习仿写一下老东家的门户页面,主要是为了熟悉一下常用插件的使用,比如video.js,wow.js,swiper等等:而其中涉及到一个包含图片跑马灯组件,大概长这样( ...
- 手把手从零开始---封装一个vue视频播放器组件
现在,在网页上播放视频已经越来越流行,但是网上的资料鱼龙混杂,很难找到自己想要的,今天小编就自己的亲身开发体验,手把手从零开始---封装一个vue视频播放器组件. 作为一个老道的前端搬砖师,怎么可能会 ...
- 封装一个的toast弹出框(vue项目)
逆风的方向,更适合飞翔 实现效果 实现步骤 先写出一个toast组件 // Toast.vue <template> <div id="toast" :class ...
- 封装一个简单的原生js焦点轮播图插件
轮播图实现的效果为,鼠标移入左右箭头会出现,可以点击切换图片,下面的小圆点会跟随,可以循环播放(为了方便理解,没有补2张图做无缝轮播).本篇文章的主要目的是分享封装插件的思路. 轮播图我一开始是写成非 ...
- 基于jQuery封装一个瀑布流插件
/*封装一个瀑布流插件*/ (function($){ $.fn.WaterFall = function(){ /*这是你初始化 调用这个方法的时候的 那个jquery选着到的dom对象 this* ...
随机推荐
- MQ和RabbitMQ
一.微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应. 异步通讯:就像发邮件,不需要马上回复. Feign调用就属于同步方式,虽然调用可以实时得到结果,但存在下面的问题: 1.耦 ...
- 深度解读昇腾CANN模型下沉技术,提升模型调度性能
本文分享自华为云社区<深度解读昇腾CANN模型下沉技术,提升模型调度性能>,作者:昇腾CANN. AI模型的运行通常情况下需要CPU和NPU(昇腾AI处理器)等AI专用处理器协同工作,CP ...
- SQL查询语句汇总
SQL查询语句汇总 students表 id class_id name gender score 1 1 小明 M 90 2 1 小红 F 95 class表 id name 1 一班 2 二班 3 ...
- 论如何直接用EF Core实现创建更新时间、用户审计,自动化乐观并发、软删除和树形查询(上)
前言 数据库并发,数据审计和软删除一直是数据持久化方面的经典问题.早些时候,这些工作需要手写复杂的SQL或者通过存储过程和触发器实现.手写复杂SQL对软件可维护性构成了相当大的挑战,随着SQL字数的变 ...
- [rCore学习笔记 010]基于 SBI 服务完成输出和关机
RustSBI的两个职责 它会在计算机启动时进行它所负责的环境初始化工作,并将计算机控制权移交给内核 在内核运行时响应内核的请求为内核提供服务 这里用不太确切的话表述一下,RustSBI作为介于内核和 ...
- Django 解决跨域访问API失败问题
解决跨域访问API失败问题 By:授客 QQ:103355122 实践环境 Win 10 Python 3.5.4 Django-2.0.13.tar.gz 官方下载地址: https://w ...
- Scratch植物大战僵尸全套素材包免费下载
scratch植物大战僵尸全套素材包,包含227个丰富多样的素材,涵盖角色.背景.动态gif.为Scratch创作者提供丰富资源,助力创作精彩作品. 免费下载地址:www.xiaohujing.com ...
- docker centos8 java8 mysql8 部署springboot项目
docker centos8 java8 mysql8 部署springboot项目 一,用idea将springboot项目打成jar包 二,将打的jar包用xshell的rz上传到docker的c ...
- 解决004--Loading local data is disabled; this must be enabled on both the client and server sides问题及解决
因为下载了SQLyog的ultimate版本,现在就可以导入外部的数据了.有着之前使用insert into插入语句来添加近50条有着大概10个字段的记录的经历之后,本着能够导入现成的数据就导入的想法 ...
- 为baselines算法库安装mujoco环境支持——ubuntu 20.04安装MuJoCo2.1.1
下载开源版本的mujoco二进制文件: wget https://github.com/deepmind/mujoco/releases/download/2.1.1/mujoco-2.1.1-lin ...