Vue2高级用法

news2024/11/15 11:41:12

Vue2高级用法

  • 1、mixin复用【vue不会用了,了解一下】
    • 1.1 基础使用
    • 1.2 选项合并
    • 1.3 全局混入
    • 1.4 细数 mixin 存在的问题
  • 2、vue.js 动画特效& 常见组件库介绍
    • 2.1 进入/离开基础使用示例
    • 2.2 进入/离开自定义过度类名
    • 2.3 进入/离开动画钩子
    • 2.4 多组件过渡与列表过渡
    • 2.5 状态过渡
    • 2.6 常用动画相关库
  • 3、 插槽
    • 3.1 插槽的三种使用方法
  • 4、插件
    • 4.1 定义插件
    • 4.2 使用插件
    • 4.3 插件化机制原理
    • 4.4 具体实践
  • 5、过滤器
    • 5.1 使用过滤器
    • 5.2 定义过滤器
    • 5.3 串联过滤器

1、mixin复用【vue不会用了,了解一下】

mixin实现复用的同时带来了很多问题,例如:命名污染依赖不透明
Vue3 用 Composition API替代

1.1 基础使用

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。
例子:

// 定义一个混入对象
var myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    }
  }
}

// 定义一个使用混入对象的组件
var Component = Vue.extend({
  mixins: [myMixin]
})

var component = new Component() // => "hello from mixin!"

1.2 选项合并

当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。

  • 值为对象的选项:合并成一个对象,同名的话,组件的值会覆盖混入对象
  • 钩子函数:合并成一个数组,都执行,混入对象的钩子先执行,组件后执行(组件的函数覆盖混入的)

比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。

var mixin = {
  data: function () {
    return {
      message: 'hello',
      foo: 'abc'
    }
  }
}

new Vue({
  mixins: [mixin],
  data: function () {
    return {
      message: 'goodbye',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
    // => { message: "goodbye", foo: "abc", bar: "def" }
  }
})

同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

var mixin = {
  created: function () {
    console.log('混入对象的钩子被调用')
  }
}

new Vue({
  mixins: [mixin],
  created: function () {
    console.log('组件钩子被调用')
  }
})

// => "混入对象的钩子被调用"
// => "组件钩子被调用"

值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

var mixin = {
  methods: {
    foo: function () {
      console.log('foo')
    },
    conflicting: function () {
      console.log('from mixin')
    }
  }
}

var vm = new Vue({
  mixins: [mixin],
  methods: {
    bar: function () {
      console.log('bar')
    },
    conflicting: function () {
      console.log('from self')
    }
  }
})

vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

注意:Vue.extend() 也使用同样的策略进行合并。

1.3 全局混入

混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。

// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})

new Vue({
  myOption: 'hello!'
})
// => "hello!"

1.4 细数 mixin 存在的问题

  1. 命名冲突:vue组件的值会覆盖mixin选项,相同类型的生命周期钩子添加到同一个数组里依次执行
  2. 依赖不透明:mixin 和使用它的组件之间没有层次关系。组件可以用mixin的数据,mixin可以用设定在vue里的数据(如上文的this.$options.myOption)。这样要是修改mixin,就比较复杂。

2、vue.js 动画特效& 常见组件库介绍

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。包括以下工具:

  • 在 CSS 过渡和动画中自动应用 class
  • 可以配合使用第三方 CSS 动画库,如 Animate.css
  • 在过渡钩子函数中使用 JavaScript 直接操作 DOM
  • 可以配合使用第三方 JavaScript 动画库,如 Velocity.js;

Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡

  • 条件渲染 (使用 v-if)
  • 条件展示 (使用 v-show)
  • 动态组件
  • 组件根节点

2.1 进入/离开基础使用示例

<div id="demo">
  <button v-on:click="show = !show">
    Toggle
  </button>
  <transition name="fade">
    <p v-if="show">hello</p>
  </transition>
</div>
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
export default {
  data() {
    show: true
  }
}

在这里插入图片描述

2.2 进入/离开自定义过度类名

<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<div id="example-3">
  <button @click="show = !show">
    Toggle render
  </button>
  <transition
    name="custom-classes-transition"
    enter-active-class="animated tada"
    leave-active-class="animated bounceOutRight"
  >
    <p v-if="show">hello</p>
  </transition>
</div>

2.3 进入/离开动画钩子

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

2.4 多组件过渡与列表过渡

<div id="list-demo" class="demo">
  <button v-on:click="add">Add</button>
  <button v-on:click="remove">Remove</button>
  <transition-group name="list" tag="p">
    <span v-for="item in items" v-bind:key="item" class="list-item">
      {{ item }}
    </span>
  </transition-group>
</div>
{
  data: {
    items: [1,2,3,4,5,6,7,8,9],
    nextNum: 10
  },
  methods: {
    randomIndex: function () {
      return Math.floor(Math.random() * this.items.length)
    },
    add: function () {
      this.items.splice(this.randomIndex(), 0, this.nextNum++)
    },
    remove: function () {
      this.items.splice(this.randomIndex(), 1)
    },
  }
}
.list-item {
  display: inline-block;
  margin-right: 10px;
}
.list-enter-active, .list-leave-active {
  transition: all 1s;
}
.list-enter, .list-leave-to
/* .list-leave-active for below version 2.1.8 */ {
  opacity: 0;
  transform: translateY(30px);
}

2.5 状态过渡

通过状态去驱动视图更新从而实现动画过渡

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>

<div id="animated-number-demo">
  <input v-model.number="number" type="number" step="20">
  <p>{{ animatedNumber }}</p>
</div>
{
  data: {
    number: 0,
    tweenedNumber: 0
  },
  computed: {
    animatedNumber: function() {
      return this.tweenedNumber.toFixed(0);
    }
  },
  watch: {
    number: function(newValue) {
      gsap.to(this.$data, { duration: 0.5, tweenedNumber: newValue });
      //gsap js动画库, gsap.to('要变化的对象,数据对象或者dom对象',{对象里变化的参数},)
    }
  }
}

2.6 常用动画相关库

  • gsap
  • animated.css
  • tween.js

3、 插槽

插槽 slot 是写在子组件的代码中,供父组件使用的占位符

3.1 插槽的三种使用方法

  • 默认插槽:没有名字,普通的
  • 具名插槽:带名字,父组件可以根据名字插入子组件的对应的位置(多个,区分占位符位置)<slot name='‘header’>(区分位置)
  • 作用域插槽:父组件可以使用子组件插槽传过来的games数据(传值)

ps: vue 2.6.0版本之后的slot插槽: 用v-slot:default=‘ctx’ 替代slot=‘’。

默认和具名案例:

<template>
  <div class="parent">
   我是父组件
    <Child></Child>
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  name: 'app',
  components: {
    Child
  }
}
</script>

<style>
.parent {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  padding:10px;
  background-color:#eee;
}
</style>
<template>
  <div class="hello">
     我是子组件
   
<!-- 如果父组件没有填充内容,就显示slot里的默认内容,
	 如果父组件填充内容,显示父组件的内容 -->
   <div>
	   <!-- 具名插槽 -->
     <slot name="header">把头放这里</slot> 
   </div>
   <div>
	 <!-- 默认插槽 -->
     <slot>这里是默认插槽</slot> 
   </div>
   <div>
	 <!-- 具名插槽 -->
     <slot name="footer">把尾巴放这里</slot>
   </div>

  </div>
</template>

<script>
export default {
  name: 'Child',
  
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

.hello{
	background-color: #097493;
	color: #fff;
	padding:20px;
}
.hello>div{
	padding:10px;
	border: 1px solid red;
	margin: 5px;
}
</style>

当父组件什么都没传时,子组件按自己默认的显示
在这里插入图片描述
当父组件填入对应内容,将会替换子组件的默认占位(子组件也可以不设置默认内容)
父组件改为

<template>
  <div class="parent">
   我是父组件
    <Child>
		<div slot="header"> 
		  替换头部内容
		</div>
		<div slot="header">
		  替换头部内容2
		</div>
		<div slot="footer">
		  替换底部内容
		</div>
		<div>
		  没有定义slot='',默认放默认插槽
		</div>
		<div>
		  如果再来一个默认插槽呢,都会进入默认插槽里
		</div>
	</Child>
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  name: 'app',
  components: {
    Child
  }
}
</script>

<style>
.parent {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  padding:10px;
  background-color:#eee;
}
</style>

显示:
在这里插入图片描述
作用域插槽:子组件定义数据,传出去,在父组件用slot-scope接收并使用,就是作用域插槽的功能

<template>
  <div class="parent">
   我是父组件
    <Child>
		<div slot="header" > 
		  替换头部内容
		  
		</div>
	
		<div slot="footer" slot-scope="user">
		  替换底部内容
		    {{user.games}}
		</div>
		<div slot-scope="{games}">
		  没有定义slot='',默认放默认插槽
		  {{games}}
		</div>

	</Child>
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  name: 'app',
  components: {
    Child
  }
}
</script>

<style>
.parent {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  padding:10px;
  background-color:#eee;
}
</style>
<template>
  <div class="hello">
     我是子组件
   
<!-- 如果父组件没有填充内容,就显示slot里的默认内容,
	 如果父组件填充内容,显示父组件的内容 -->
   <div>
	   <!-- 具名插槽 -->
     <slot :games="games" name="header">把头放这里</slot> 
   </div>
   <div>
	 <!-- 默认插槽 -->
     <slot :games="games">这里是默认插槽</slot> 
   </div>
   <div>
	 <!-- 具名插槽 -->
     <slot :games="games" name="footer">把尾巴放这里</slot>
   </div>

  </div>
</template>

<script>
export default {
  name: 'Child',
  data() {
  	return {
  		games:['王者荣耀','吃鸡','斗地主']
  	}
  },
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

.hello{
	background-color: #097493;
	color: #fff;
	padding:20px;
}
.hello>div{
	padding:10px;
	border: 1px solid red;
	margin: 5px;
}
</style>

显示:
在这里插入图片描述

4、插件

插件可以是对象,或者是一个函数。如果是对象,那么对象中需要提供 install 函数,如果是函数,形态需要跟前面提到的 install 函数保持一致。
install 是组件安装的一个方法,跟 npm install 完全不一样,npm install 是一个命令

4.1 定义插件

const MyPlugin = {
    install(Vue, options) {
      // 1. 添加全局方法或 property
      Vue.myGlobalMethod = function () {
        // 逻辑...
      }
    
      // 2. 添加全局资源
      Vue.directive('my-directive', {
        bind (el, binding, vnode, oldVnode) {
          // 逻辑...
        }
        ...
      })
    
      // 3. 注入组件选项
      Vue.mixin({
        created: function () {
          // 逻辑...
        }
        ...
      })
    
      // 4. 添加实例方法
      Vue.prototype.$myMethod = function (methodOptions) {
        // 逻辑...
      }
    }
};

4.2 使用插件

Vue.use(MyPlugin);

{{ $myMethod }}

4.3 插件化机制原理

export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    // 获取已经安装的插件
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    // 看看插件是否已经安装,如果安装了直接返回
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // toArray(arguments, 1)实现的功能就是,获取Vue.use(plugin,xx,xx)中的其他参数。
    // 比如 Vue.use(plugin,{size:'mini', theme:'black'}),就会回去到plugin意外的参数
    const args = toArray(arguments, 1)
    // 在参数中第一位插入Vue,从而保证第一个参数是Vue实例
    args.unshift(this)
    // 插件要么是一个函数,要么是一个对象(对象包含install方法)
    if (typeof plugin.install === 'function') {
      // 调用插件的install方法,并传入Vue实例
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    // 在已经安装的插件数组中,放进去
    installedPlugins.push(plugin)
    return this
  }
}

4.4 具体实践

Vue-Router
for Vue2

import View from './components/view'
import Link from './components/link'

export let _Vue

export function install (Vue) {
  if (install.installed && _Vue === Vue) return
  install.installed = true

  _Vue = Vue

  const isDef = v => v !== undefined

  const registerInstance = (vm, callVal) => {
    let i = vm.$options._parentVnode
    if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
      i(vm, callVal)
    }
  }

  Vue.mixin({
    beforeCreate () {
      if (isDef(this.$options.router)) {
        this._routerRoot = this
        this._router = this.$options.router
        this._router.init(this)
        Vue.util.defineReactive(this, '_route', this._router.history.current)
      } else {
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
      }
      registerInstance(this, this)
    },
    destroyed () {
      registerInstance(this)
    }
  })

  Object.defineProperty(Vue.prototype, '$router', {
    get () { return this._routerRoot._router }
  })

  Object.defineProperty(Vue.prototype, '$route', {
    get () { return this._routerRoot._route }
  })

  Vue.component('RouterView', View)
  Vue.component('RouterLink', Link)

  const strats = Vue.config.optionMergeStrategies
  // use the same hook merging strategy for route hooks
  strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
}

for Vue3

 
    install(app: App) {
      const router = this
      app.component('RouterLink', RouterLink)
      app.component('RouterView', RouterView)

      app.config.globalProperties.$router = router
      Object.defineProperty(app.config.globalProperties, '$route', {
        enumerable: true,
        get: () => unref(currentRoute),
      })

      // this initial navigation is only necessary on client, on server it doesn't
      // make sense because it will create an extra unnecessary navigation and could
      // lead to problems
      if (
        isBrowser &&
        // used for the initial navigation client side to avoid pushing
        // multiple times when the router is used in multiple apps
        !started &&
        currentRoute.value === START_LOCATION_NORMALIZED
      ) {
        // see above
        started = true
        push(routerHistory.location).catch(err => {
          if (__DEV__) warn('Unexpected error when starting the router:', err)
        })
      }

      const reactiveRoute = {} as {
        [k in keyof RouteLocationNormalizedLoaded]: ComputedRef<
          RouteLocationNormalizedLoaded[k]
        >
      }
      for (const key in START_LOCATION_NORMALIZED) {
        // @ts-expect-error: the key matches
        reactiveRoute[key] = computed(() => currentRoute.value[key])
      }

      app.provide(routerKey, router)
      app.provide(routeLocationKey, reactive(reactiveRoute))
      app.provide(routerViewLocationKey, currentRoute)

      const unmountApp = app.unmount
      installedApps.add(app)
      app.unmount = function () {
        installedApps.delete(app)
        // the router is not attached to an app anymore
        if (installedApps.size < 1) {
          // invalidate the current navigation
          pendingLocation = START_LOCATION_NORMALIZED
          removeHistoryListener && removeHistoryListener()
          removeHistoryListener = null
          currentRoute.value = START_LOCATION_NORMALIZED
          started = false
          ready = false
        }
        unmountApp()
      }

      // TODO: this probably needs to be updated so it can be used by vue-termui
      if ((__DEV__ || __FEATURE_PROD_DEVTOOLS__) && isBrowser) {
        addDevtools(app, router, matcher)
      }
    },
  }

5、过滤器

Vue.js允许我们自定义过滤器,对数据进行格式化。过滤器应该放在JS表达式的尾部,由管道符号连接。过滤器可以用在两个地方:双花括号差值和v-bind表达式。

5.1 使用过滤器

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!--`v-bind`-->
<div v-bind:id="message | capitalize"></div>

5.2 定义过滤器

组件中定义过滤器:

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

全局中定义过滤器:

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

new Vue({
  // ...
})

5.3 串联过滤器

我们可以同时使用多个过滤器,过滤器函数总接收表达式的值 (上一个过滤器的结果) 作为第一个参数。

{{ message | filterA | filterB }}

过滤器是 JavaScript 函数,因此可以接收参数:
ps:没有传参时候,默认传入当前值filterA等价于filterA(message)

{{ message | filterA('arg1', 'arg2') }}

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

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

相关文章

pdf2image:将PDF文档转化为图像的Python魔法

标题&#xff1a;探索pdf2image&#xff1a;将PDF文档转化为图 像的Python魔法 背景 在数字时代&#xff0c;我们经常需要处理各种格式的文档&#xff0c;尤其是PDF文件。PDF以其跨平台的可读性和稳定性而广受欢迎。然而&#xff0c;有时我们需要将PDF文件转换成图像格式&am…

AI大模型学习笔记-gpt

多模态&#xff08;Multimodal&#xff09;技术指的是处理和整合来自多种不同类型数据&#xff08;模态&#xff09;的信息和方法。在计算机科学和人工智能领域&#xff0c;这种技术可以应用于多个方面&#xff0c;比如图像、文字、语音、视频等。这种技术的主要目标是通过整合…

Java中包,final,权限修饰符,代码块学习

&#xff08;这一小节我看的是面向对象进阶-13-包和final_哔哩哔哩_bilibili&#xff09; 包&#xff1a; final: Ctriln可以搜索包 细节&#xff1a;引用是记录的地址值&#xff0c;实际上final修饰的基本类型&#xff0c;引用类型实际上的数据都是不发生改变的。 权限修饰符…

什么是图纸加密软件,图纸加密软件推荐

图纸加密软件是一类专门用于保护CAD图纸和其他设计文件安全的工具。随着技术的发展&#xff0c;工程设计和制造业中的图纸和设计文件越来越多地以数字化形式存储和传输&#xff0c;这使得这些数据容易成为潜在的攻击目标。图纸加密软件通过对图纸文件进行加密保护&#xff0c;确…

AI学习记录 - 图像识别的基础入门

代码实现&#xff0c;图像识别入门其实非常简单&#xff0c;这里使用的是js&#xff0c;其实就是把二维数组进行公式化处理&#xff0c;处理方式如上图&#xff0c;不同的公式代表的不同的意义&#xff0c;这些意义网上其实非常多&#xff0c;这里就不细讲了。 const getSpecif…

python黑马笔记

运算符&#xff1a; 算术运算符&#xff1a; 加 - 减 * 乘 / 除 // 整除 % 取余 ** 求平方 除法计算得出的结果都是小数 赋值运算符&#xff1a; 标准赋值&#xff1a; 复合赋值&#xff1a; 、 - 、 * 、 / 、// 、 ** 字符串&#xff1a; 字符串拓展内容&#xf…

前端开发知识(三)-javascript

javascript是一门跨平台、面向对象的脚本语言。 一、引入方式 1.内部脚本&#xff1a;使用<script> &#xff0c;可以放在任意位置&#xff0c;也可以有多个&#xff0c;一般是放在<body></body>的下方。 2.外部脚本&#xff1a;单独编写.js文件&#xff…

十、SpringBoot 统⼀功能处理【拦截器、统一数据返回格式、统一异常处理】

十、SpringBoot 统⼀功能处理 1. 拦截器【HandlerInterceptor、WebMvcConfig】1.1 拦截器快速⼊⻔⾃定义拦截器&#xff1a;实现HandlerInterceptor接⼝&#xff0c;并重写其所有⽅法注册配置拦截器&#xff1a;实现WebMvcConfigurer接⼝&#xff0c;并重写addInterceptors⽅法…

从C到C++入门篇(三)引用;引用的本质

Reference & 引用 变量名&#xff0c;本身是一段内存的引用&#xff0c;即别名(alias)。此处引入的引用&#xff0c;是为己有变 量起一个别名。 int a 500; //变量名.实质是一段内存空间的别名 (int)0x0002345500; 引用的规则 引用&#xff0c;是一种关系型声明&#xff0…

【电路笔记】-D类放大器

D类放大器 文章目录 D类放大器1、概述2、D类放大器介绍3、调制4、放大5、滤波6、效率7、总结1、概述 在之前的文章中,放大器的导通角与其效率之间建立了重要的联系。 事实上,基于高导通角的放大器提供非常好的线性度,例如 A 类放大器,但效率非常有限,通常约为 20% 至 30%…

MATLAB基础:数据和变量

今天我们开始学习MATLAB基础知识 1、常用非运算符及其作用 1、“,” 作为程序运行的分隔符&#xff0c;起到分隔语句的作用 2、“;” 同样作为分隔符&#xff0c;与“,”不同的是“;”会在程序运行时隐藏该行语句 如下图&#xff1a; 3、“...” 三个英文句点表示续行符…

深入解析食堂采购系统源码开发:从零开始构建供应链采购管理APP

今天&#xff0c;笔者将与大家共同探讨食堂采购系统源码开发&#xff0c;从零开始构建一个高效的供应链采购管理APP。 一、需求分析 在开始开发之前&#xff0c;首先需要进行详细的需求分析。这一步至关重要&#xff0c;因为它直接影响到系统的功能和架构设计。对于食堂采购系…

达梦数据库系列—30. DTS迁移Mysql到DM

目录 1.MySQL 源端信息 2.DM 目的端信息 3.迁移评估 4.数据库迁移 4.1源端 MySQL 准备 4.2目的端达梦准备 初始化参数设置 兼容性参数设置 创建迁移用户和表空间 4.3迁移步骤 创建迁移 配置迁移对象及策略 开始迁移 对象补迁 5.数据校验 统计 MySQL 端对象及数…

BUG与测试用例设计

一.软件测试的生命周期 需求分析→测试计划→测试设计,测试开发→测试执行→测试评估→上线→运行维护 二.BUG 1.bug的概念 (1)当且仅当规格说明(需求文档)是存在的并且正确,程序与规格说明之间的不匹配才是错误. (2)当需求规格说明书没有提到的功能,判断标准以最终用户为准…

vscode调试nextjs前端后端程序、nextjs api接口

最近有一个项目使用了nextjs框架&#xff0c;并且使用nextjs同时实现了前后端&#xff0c;由于之前前后端都是分离的&#xff0c;前端的调试可以通过在代码种添加debugger或者直接在浏览器中打断点实现&#xff0c;现在想调试后端接口&#xff0c;前面的方式就不适用了。故研究…

【RaspberryPi】树莓派Matlab/Simulink支持包安装与使用

官网支持与兼容性 Raspberry Pi Support from MATLAB - Hardware Support - MATLAB & Simulink Raspberry Pi Support from Simulink - Hardware Support - MATLAB & Simulink Matlab与树莓派兼容性 Simulink与树莓派兼容性 树莓派Matlab&Simulink RaspberryPi支…

项目实战1(30小时精通C++和外挂实战)

项目实战1&#xff08;30小时精通C和外挂实战&#xff09; 01-MFC1-图标02-MFC2-按钮、调试、打开网页05-MFC5-checkbox及按钮绑定对象06--文件格式、OD序列号08-暴力破解09-CE10-秒杀僵尸 01-MFC1-图标 这个外挂只针对植物大战僵尸游戏 开发这个外挂&#xff0c;首先要将界面…

RK3399 Linux 系统,接i2c外设,时好时坏(三)其中一个解决问题方法

在 RK3399 平台上,连接 I2C 设备时,有时可能会遇到时好时坏的问题。这种情况往往与引脚的配置有关。在本文中,我们将讨论如何通过调整引脚的上下拉配置来解决这个问题。 目前瑞芯微芯片,需要调节i2c驱动电流能力的,有以下芯片: 具体来说,我们将把 I2C1 的引脚配置中的…

SpringSecurity专题

目录 一&#xff1a;认证授权 什么是认证授权&#xff1a; 二&#xff1a;权限数据模型 RBAC权限数据模型 2.1基于角色访问权限控制 2.2基于资源访问权限控制 常见的认证方式 1.Cookie-Session 2.jwt令牌无状态认证 三&#xff1a;JWT 1.JWT的组成 2.JWT的使用 四&…

【STC32G12K128开发板】第3-7讲:声音探测传感器

第3-7讲&#xff1a;声音探测传感器 学习目的了解声音探测传感器模块的作用。掌握单片机编程读取声音探测传感器模块引脚输出状态&#xff0c;从而判断周围环境声音强度有没有达到设置的阈值。 声音探测传感器简介 声音探测传感器模块对环境声音强度敏感&#xff0c;常用来检测…