使用脚手架创建项目,使用组件开发

news2025/1/15 9:27:37

单文件组件

单文件组件就是一个文件对应一个组件, 单文件组件的名字通常是xxx.vue(命名规范和组件名的命名规范相同),这个文件是Vue框架规定的只有它能够认识,浏览器无法直接打开运行

  • Vue框架可以将xxx.vue文件进行编译为浏览器能识别的html js css的代码

xxx.vue文件的内容包括结构HTML代码(template标签),交互JS代码(script标签),样式CSS代码(style)三大类

  • VSCode工具插件:vetur在编写xxx.vue文件的时候代码有高亮提示,并且也可以通过输入 <v 生成代码,Auto Rename Tag插件方便同时修改标签名

export和import

export用于暴露数据(属性和方法以及对象): 常见的暴露方式有分别暴露,统一暴漏,默认暴露

// m1.js文件中使用分别暴露属性和方法
export let school = '尚硅谷';

export function teach() {
    console.log("我们可以教给你开发技能");
}

// m2.js文件中使用对象的方式统一暴露
let school = '尚硅谷';
function findJob(){
    console.log("我们可以帮助你找工作!!");
}
export {school, findJob};

// m3.js文件中使用默认暴露(可以暴露任意类型,一般是个对象)
export default {
    school: 'ATGUIGU',
    change: function(){
        console.log("我们可以改变你!!");
    }
}	

import用于导入js文件中暴露的数据(属性,方法,对象)

<body>
    <script type="module">
        // 通用的导入方式,m1,m2,m3分别存储了暴露的数据
        import * as m1 from "./src/js/m1.js";
        import * as m2 from "./src/js/m2.js";
        import * as m3 from "./src/js/m3.js";
 
        // 解构赋值形式即通过对象的形式使用暴露的数据,属性方法重名时使用as关键字
        // import {a, b} from ‘模块标识符'
        import {school, teach} from "./src/js/m1.js";
        import {school as guigu, findJob} from "./src/js/m2.js";
        // default是个关键字不能直接使用,需要使用别名机制
        import {default as m3} from "./src/js/m3.js";

        // 导入的简便形式但是只能针对默认暴露,m3是别名存储了暴露的数据和方法
        // import 任意名称 from ‘模块标识符’
        import m3 from "./src/js/m3.js";
        // 访问暴露的属性和方法需要加一层default结构
        console.log(m3.default.school);
    </script>
</body>

将所有模块的引入单独写到一个js文件中,在index,html中使用script标签,类型是module直接引入这个js文件即可

//模块引入的入口文件
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";
 <body>
    <!--引入js文件,类型是module-->
    <script src="./src/js/app.js" type="module"></script>
</body>

组件嵌套之单文件组件

组件化开发的流程: 浏览器不认识.vue文件并且也不认识 ES6 的模块化语法, 需要安装Vue脚手架

第一步: 创建xxx.vue文件创建组件可以嵌套使用其他组件

<!--App.vue-->
<template>
    <div>
        <h1>App组件</h1>
        <!-- 使用组件 -->
        <X></X>
        <Y></Y>
    </div>
</template>
<script>
    import X from './X.vue'
    import Y from './Y.vue'
    // 把组件暴露出去
    export default {
        // 注册组件
        components : {X, Y}
    }
</script>

<!--X.vue-->
<template>
    <div>
        <h2>X组件</h2>
        <!-- 使用组件 -->
        <X1></X1>
    </div>
</template>
<script>
    import X1 from './X1.vue'
    export default {
        // 注册组件
        components : {X1}
    }
</script>
<!--X1.vue-->
<template>
    <div>
        <h3>X1组件</h3>
    </div>
</template>
<script>
    export default {
        // 暴露X1组件
    }
</script>

<!--Y.vue-->
<template>
    <div>
        <h2>Y组件</h2>
        <!-- 使用组件 -->
        <Y1></Y1>
    </div>
</template>
<script>
    // 导入组件Y1(Y1可以使用其它名字)
    import Y1 from './Y1.vue'
    export default {
        // 注册组件
        components : {Y1}
    }
</script>

<!--Y1.vue-->
<template>
    <div>
        <h3>Y1组件</h3>
    </div>
</template>

<script>
    export default {
        // 暴露Y1组件
    }
</script>

第二步: 使用js代码导入根组件App.vue文件,创建vm实例并注册App组件,最后将这段代码写到一个main.js入口文件中即可

import App from './App.vue'
new Vue({
    el : '#root',
    // 使用组件
    template : `<App></App>`,
    // 注册App组件
    components : {App}
})

第三步: 引入vue.js文件和main.js文件,在index.html文件中创建vm实例要挂载的元素

第四步: 打开index.html页面,浏览器加载vue.js和main.js文件后会创建Vue实例vm,完成所有组件及其子组件的创建和注册,最后编译模板语句然后渲染页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单文件组件</title>
</head>
<body>
    <div id="root"></div>
    <script src="../js/vue.js"></script>
    <script src="./main.js"></script>
</body>
</html>

使用脚手架组件开发

安装Vue CLI(脚手架)

Vue 的脚手架(Command Line Interface)是Vue官方为方便开发者而提供的标准化开发平台,Vue CLI 4.x需要Node.js v8.9及以上版本(推荐v10以上)

第一步:执行npm install -g @vue/cli命令安装脚手架,-g 表示全局安装即只需要安装一次,使用vue命令测试是否安装成功

第二步: 在指定目录下执行 vue creat vue_pro命令, 表示创建一个vue_pro项目(内置Hello Word案例),自带脚手架环境且内置了webpack loader

在这里插入图片描述

第三步: 在vue_pro项目的根目录下执行 npm run serve命令编译Vue程序,此时会自动将项目中的xxx.vue文件转成html css js代码

在这里插入图片描述

认识脚手架项目结构

在这里插入图片描述

index.html文件

脚手架项目中的index.html文件中只有一个容器,并且没有看到引入vue.js文件和main.js文件,因为Vue脚手架会自动找到main.js文件,前提是文件名称和位置固定

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <!--让IE浏览器启用最高渲染标准,IE8是不支持Vue的-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- 开启移动端虚拟窗口(理想视口),可以设置虚拟窗口的宽高以及初始化比例,达到手机端浏览网页时缩放和移动的效果-->
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <!--设置页签图标,BASE_URL是Vue模仿Jsp语法设置的绝对路径,绝对路径比相对路径更加稳定-->
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <!--webpack会去package.json中找name作为标题,也可以自己手动设置-->
    <title><%= htmlWebpackPlugin.options.title %></title>
    <title>欢迎使用本系统</title>
  </head>
  <body>
    <!--当浏览器不支持JS语言的时候,显示如下的提示信息-->
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <!-- 容器 -->
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

配置文件vue.config.js

vue.config.js文件是脚手架默认的配置文件,具体配置项可以参考Vue CLI官网手册

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  // 保存时是否进行语法检查(如组件的名字应该由多单词组成), 默认值true表示检查,false表示不检查
  lintOnSave : false,
  // 配置入口文件的位置和名称
  pages: {
    index: {
      entry: 'src/main.js',
    }
  },

入口文件main.js

Vue包含两部分: 一部分是Vue的核心,一部分是模板编译器(占整个vue.js文件体积的三分之一)

  • 由于最终使用webpack打包的时候代码肯定是已经编译好了, 这时候Vue中的模板编译器就没有存在的必要了,所以为了缩小体积Vue脚手架中默认直接引入的就是一个缺失模板编译器的vue.js文件即Vue的仅运行时版本

在这里插入图片描述

由于Vue引入的是缺失了模板编译器的vue.js文件,所以在main.js文件创建Vue实例时无法编译template配置项中的模板语句, 但xxx.Vue文件template标签中的模板语句可以正常编译,因为Vue在package.json文件中进行了配置

  • 第一种方式: 引入一个完整的vue.js, import Vue from 'vue/dist/vue.js'
  • 第二种方式: 使用render函数代替template配置项,这个函数由vue自动调用,并且会传递过来一个函数createElemen可以用来创建元素(创建完必须返回)
// 这里默认引入的是dist/vue.runtime.esm.js(esm版本是ES6模块化版本)
import Vue from 'vue'
// 导入App组件(根组件)
import App from './App.vue'

// 关闭生产提示信息
Vue.config.productionTip = false

// 创建Vue实例
new Vue({
  el : '#app',
  // 完整写法
  render(createElement){ 
    // 创建了一个div元素
    //return createElement('div', 'render函数')
    return createElement(App)
  } 
	
  // 箭头函数的简写形式,参数只有一个省略括号,函数体只有一条语句可以省略{}和retuen
  render : h => h(App)
  
})

App根组件和其他组件

<!--App.vue-->
<template>
    <div>
        <h1>App组件</h1>
        <!-- 使用组件 -->
        <X></X>
        <Y></Y>
    </div>
</template>

<script>
    // 确定组件引入时的路径
    import X from './components/X.vue'
    import Y from './components/Y.vue'
    export default {
        // 注册组件
        components : {X, Y}
    }
</script>
<!--剩下的和组件嵌套的内容相同-->

组件间的数据传递

发送组件(父组件)通过给子组件标签属性赋值的形式传递数据, 接收组件(子组件)使用props配置项声明属性接收父组件传过来的数据

  • 简单接收: props : [‘brand’,‘color’,‘price’]
  • 接收时添加类型限制(非必要): props : { brand : String,color : String,price : Number}
  • 接收时添加类型限制(必要)和默认值: props : {name : {type : Number, required : true}, age : {type : Number, default : 10}}

创建一个子组件Car接收父组件传递过来的数据,每当父组件重新渲染时,子组件中使用props中的属性接收到的值会被重新赋值,有默认值是默认值

  • 使用props接收到的数据不建议直接修改,因为父组件下次重新渲染时又会给子组件中使用prop配置项接收到的属性重新赋值
  • 一般通过间接修改一个中间变量的值避免父组件重新渲染时子组件修改后的值被覆盖的问题
<template>
    <div>
        <h3>品牌:{{brand}}</h3>
        
        <h3>价格:{{cprice}}</h3>
        <h3>颜色:{{color}}</h3>
        <button @click="add">价格加1</button>
    </div>
</template>
<script>
export default {
    name : 'Car',
    data() {
        return {
            // 将接收到的price属性的值赋值给一个中间变量
            cprice : this.price
        }
    },
    methods : {
        add(){
            // 修改中间变量的值,即使父组件重新渲染时子组件修改后的值也不会被覆盖
            this.cprice++
        }
    },
    // 在Car这个子组件当中使用props配置项动态的接收其他组件传递过来的数据,不再使用自己配置项data中的静态数据
    data() {
        return {
            brand : '宝马520',
            price : 10,
            color : '黑色'
        }
    }, 
    // 第一种:简单的接收方式,直接采用数组接收
    props : ['brand','color','price']
   
    // 第二种:接收的时候添加类型限制(类型不符合会报错)
    props : {
        brand : String,
        color : String,
        price : Number
    } 
    
    // 第三种:接收的时候添加类型的必要性限制和默认值
    props : {
        brand : {
            type : String,
            required : true
        },
        color : {
            type : String,
            default : '红色'
        },
        price : {
            type : Number,
            required : true
        }
    }

}
</script>

在父组件中获取子组件及其属性,在子组件标签上或者Dom元素上使用ref属性进行标识

  • 获取某个子组件及其属性: 在当前组件中使用$refs来获取当前组件的所有子组件, 然后通过组件的标识获取具体的某一个组件及其属性
  • 获取子组件时支持嵌套的形式: this.$refs.组件标识.$refs.name表示访问子组件的子组件属性
<template>
    <div>
        <!--普通的HTML标签上也可以使用HTML标签进行标识-->
        <h1 ref="hh">{{msg}}</h1>
        <!--price="10"表示传递过去的数据是字符串"10",:price="10"表示传递过去的数据是数字10(属性绑定,""内的10被看作常量)-->
        <Car brand="宝马520" color="黑色" :price="10" ref="car1"></Car>
        <Car brand="比亚迪汉" color="红色" :price="20" ref="car2"></Car>
        <button @click="printCarInfo">打印汽车信息</button>
    </div>
</template>

<script>
    import Car from './components/Car.vue'
    export default {
        name : 'App',
        data() {
            return {
                msg : '汽车信息'
            }
        },
         methods : {
            printCarInfo(){
                // 使用$refs属性获取子组件
                console.log(this.$refs.car1)
                console.log(this.$refs.car2)
				
                // 访问子组件的属性
                console.log(this.$refs.car1.brand)
                console.log(this.$refs.car1.color)
                console.log(this.$refs.car1.price)

                // 使用$refs属性也可以获取普通的DOM元素的值,替代原生Dom的操作
                console.log(this.$refs.hh.innerText)
            }
        },
        components : {Car}
    }
</script>

mixins配置项(混入)

如果多个xxx.vue文件的配置项代码相同(配置项没有限制如methods),此时为了复用可以使用mixins配置项进行混入

  • 第一步: 提取相同的配置项并单独定义到一个mixin.js文件,一般和main.js在同级目录
  • 第二步: 在对应的xxx.vue文件中导入mixin.js文件,然后在mixins配置项中使用暴露的配置

混入时配置项的冲突问题

  • 对于普通的配置项采取就近原则: 即只执行组件自身的配置不会执行混入的配置,因为混入的意思就是不破坏
  • 对于生命周期周期钩子函数采用叠加方式: 即先执行混入的再执行自己的

混入的方式分为局部混入全局混入两种

// 分别暴露
export const mix1 = {
    methods: {
        printInfo(){
           console.log(this.name, ',' , this.age) 
        }
    }
}


// 普通的配置
export const mix2 = {
    methods: {
        a(){
            console.log('mixin.js a.....')
        }
    },
}
// 生命周期函数
export const mix3 = {
    mounted() {
        console.log('mixin.js mounted...')
    }
}

对于普通的配置项采取就近原则: 即只执行组件自身的配置不会执行混入的配置,因为混入的意思就是不破坏

<template>
    <div>
        <h1>{{msg}}</h1>
        <h3>姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
        <button @click="printInfo">执行printInfo方法打印用户信息</button>
        <button @click="a">执行a方法</button>
    </div>
</template>

<script>
    // 导入mixin配置项
    import {mix1} from '../mixin.js'
    import {mix2} from '../mixin.js'
    export default {
        name : 'Vip',
        data() {
            return {
                msg : '会员信息',
                name : '李四2',
                age : 21
            }
        },
     	// 局部混入,数组接收表示可以混入多个
        mixins : [mix1,mix2],
        // 这里只调用自身的a方法,不会执行混入的a方法
        methods: {
            a(){
                console.log('vip a....')
            }
        },
    }
</script>

对于生命周期周期钩子函数采用叠加方式: 即先执行混入的钩子函数再执行自己的钩子函数

<template>
    <div>
        <h1>{{msg}}</h1>
        <h3>姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
        <button @click="printInfo">执行printInfo方法打印用户信息</button>
        <button @click="a">执行a方法</button>
    </div>
</template>

<script>
    // 导入mixin.js文件中的mixin配置项
    import {mix1} from '../mixin.js'
    import {mix2} from '../mixin.js'
    import {mix3} from '../mixin.js'
    export default {
        name : 'User',
        // 这里先执行混入的mounted函数,再执行自身的mounted函数
        mounted() {
            console.log('User mounted...')
        },
        data() {
            return {
                msg : '用户信息',
                name : '张三2',
                age : 20
            }
        },
        // 局部混入,数组接收表示可以混入多个
        mixins : [mix1,mix2, mix3],
    }
</script>

main.js文件中全局混入的配置项会在所有的组件包括根组件root即vm中自动导入混入的配置项并按照规则执行

// 等同于引入vue.js文件
import Vue from 'vue'
// 导入App组件(根组件)
import App from './App.vue'

// 导入mixin配置项
import {mix1} from './mixin.js'
import {mix2} from './mixin.js'
import {mix3} from './mixin.js'

// 全局混入
Vue.mixin(mix1)
Vue.mixin(mix2)
Vue.mixin(mix3)

// 关闭生产提示信息
Vue.config.productionTip = false

// 创建Vue实例
new Vue({
  el : '#app',
  render : h => h(App)
})

plugins配置(插件)

插件是一个对象: 是给用来Vue做功能增强的(可插拔), 一个插件一般对应一个独立的功能,插件一般都放到一个plugins.js文件中(一般和main.js在同级目录)

插件对象中必须有install方法,这个方法有两个参数并且会被自动调用

  • 第一个参数:Vue构造函数
  • 第二个参数:用户在使用这个插件时传过来的数据,参数个数无限制

第一步: 定义插件对象并暴露,如我们这里可以定义一个插件,功能是给Vue的原型对象扩展一个counter属性(通过vm和vc都可以访问)

export const p1 = {
    install(Vue, a, b, c, d){
        console.log('这个插件正在显示一个可爱的封面')
        console.log(Vue)
        console.log(a,b,c,d)
        // 获取Vue的原型对象,给Vue的原型对象扩展一个counter属性,通过vm和vc都可以访问
        Vue.prototype.counter = 1000
    }
}

第二步: 在main.js文件中导入创建的插件对象,然后使用导入的插件

// 等同于引入vue.js文件
import Vue from 'vue'
// 导入App组件(根组件)
import App from './App.vue'

// 导入插件
import {p1} from './plugins.js'


// 插上插件(删除就是拔下插件),通常放在创建Vue实例之前
Vue.use(p1, 1,2,3,4)

// 关闭生产提示信息
Vue.config.productionTip = false

// 创建Vue实例
new Vue({
  el : '#app',
  render : h => h(App)
  
})

第三步: 访问我们定义的插件对象给Vue原型对象扩展的一个counter属性

<template>
    <div>
        <button @click="a">执行a方法</button>
    </div>
</template>

<script>
    export default {       
        methods: {
            a(){
                console.log('vip a....')
                // 访问插件对象给Vue原型对象扩展的一个counter属性
                console.log('通过插件扩展的一个counter:', this.counter)
            }
        },
    }
</script>

局部样式 scoped

默认情况下所有组件中的style标签中定义的样式最终会汇总到一块,如果样式名一致会导致冲突,此时会采取就近原则即以后来加载的组件样式为准

  • 组件中的style样式支持多种样式语言(如css、less、sass), 使用less语法需要执行npm i less-loader命令安装less-loader

给组件的style标签加入scoped属性后,Vue底层会给标签加上属性,这样即使样式汇到一块也不会发生冲突了

<template>
    <div class="s">
        <h1>{{msg}}</h1>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                msg : '用户信息',
            }
        }
    }
</script>
<!--给组件的style标签加入scoped属性后,Vue底层会给标签加上属性,这样即使样式汇到一块也不会发生冲突了-->
<style scoped>
   .s {
    background-color: aquamarine;
   } 
</style>
<template>
    <div class="s">
        <h1>{{msg}}</h1>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                msg : '会员信息',
            }
        }
    }
</script>
<!--给组件的style标签加入scoped属性后,Vue底层会给标签加上属性,这样即使样式汇到一块也不会发生冲突了-->
<style scoped>
   .s {
    background-color:bisque
   } 
</style>

App根组件中的样式style一般采用全局的方式不建议添加scoped属性,子组件的样式style一般添加scoped属性

<template>
    <div>
        <User></User>
        <Vip></Vip>
    </div>
</template>

<script>
    // 先导入Vip,由于样式冲突那么User组件的样式会覆盖掉Vip组件的样式
    import Vip from './components/Vip.vue'
    import User from './components/User.vue'
    export default {
        name : 'App',
        components : {User, Vip}
    }
</script>

<style>
    /* 一般在App根组件当中样式不会添加scoped,因为根组件的样式还是希望采用全局的方式处理*/
</style>

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

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

相关文章

【Python基础知识一】基本语法、常用数据类型等

Python基础知识&#xff1a; 1 标识符&#xff08;Identifier&#xff09;2 关键字/保留字&#xff08;Keyword&#xff09;3 引号4 编码5 输入输出6 行与缩进7 多行语句8 注释9 数据类型9.1 数字(Number)类型9.2 变量&#xff08;variate&#xff09;9.3 字符串&#xff08;St…

【漏洞复现】Apache_HTTPD_多后缀解析漏洞

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞复现1、基础环境2、漏洞验证 1.3、深度利用GetShell 1.4、修复建议 1.1、漏洞描述 Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执…

你了解SonarQube 吗

你了解SonarQube 吗 文章目录 你了解SonarQube 吗一、介绍二、idea代码检测工具SonarLint安装方法使用方法 三、常见的Sonar解决方法Unused "private" fields should be removedSections of code should not be "commented out"Useless imports should be …

异星工场入门笔记-02-一个重要地学习方法

编程学习地整个过程&#xff0c;最重要的工具就是电脑&#xff0c;其中有一个重点就是可以无成本的重复测试&#xff0c;这大大降低了难度&#xff0c;节约了时间。真正难以学习的不是技术本身&#xff0c;而是材料成本和时间成本&#xff0c;降低这两个因素平地起高楼根本不是…

go语言 | grpc原理介绍(二)

gRPC gRPC 是一个高性能、通用的开源 RPC 框架&#xff0c;其由 Google 2015 年主要面向移动应用开发并基于 HTTP/2 协议标准而设计&#xff0c;基于 ProtoBuf 序列化协议开发&#xff0c;且支持众多开发语言。 由于是开源框架&#xff0c;通信的双方可以进行二次开发&#x…

Canoe UDS诊断技术

Canoe UDS诊断 汽车诊断技术概述诊断术语OBD诊断CAN诊断协议诊断周期UDS诊断服务Diagnostic Request和Response诊断服务介绍 诊断文件CDD介绍诊断安全访问服务(security Access)介绍 如何在Canoe UDS诊断实战CANoe 开启诊断功能Canoe 诊断实战 汽车诊断技术概述 汽车诊断技术是…

让SOME/IP运转起来——SOME/IP系统设计(上)

什么是SOME/IP&#xff1f; SOME/IP&#xff08;Scalable service-Oriented MiddlewarE over IP&#xff09;是AUTOSAR应用层的协议&#xff0c;是基于IP协议的面向服务的可拓展性的中间件。 SOME/IP中主要定义了&#xff1a; 数据的序列化&#xff1a;SOME/IP支持的数据类型…

DirectX3D 虚拟现实项目 三维物体的光照及着色(五个不同着色效果的旋转茶壶)

文章目录 任务要求原始代码CPP文件代码着色器文件代码 效果展示 任务要求 本篇文章是中国农业大学虚拟现实课程的一次作业内容&#xff0c;需要对五个茶壶模型使用不同的光照进行着色和渲染&#xff0c;然后旋转展示。 本人的代码也是在其他人的代码的基础上修改来的&#xf…

学习网络安全有哪些误区?学习之前要做哪些准备?如何系统的学习黑客技术/网络安全?

如果你想学习网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;什么是黑客&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防御技术&#xff08;WAF&am…

CVE-2023-34040 Kafka 反序列化RCE

漏洞描述 Spring Kafka 是 Spring Framework 生态系统中的一个模块&#xff0c;用于简化在 Spring 应用程序中集成 Apache Kafka 的过程&#xff0c;记录 (record) 指 Kafka 消息中的一条记录。 受影响版本中默认未对记录配置 ErrorHandlingDeserializer&#xff0c;当用户将容…

MATLAB 绘制 SISO 和 MIMO 线性系统的时间和频率响应图

系列文章目录 文章目录 系列文章目录前言一、时间响应二、频率响应三、极点/零点图和根节点四、响应特性五、分析 MIMO 系统六、系统比较七、修改时间轴或频率轴数值如果觉得内容不错&#xff0c;请点赞、收藏、关注 前言 本例演示如何绘制 SISO 和 MIMO 线性系统的时间和频率…

YOLOv8改进:检测头结构全新创新篇 | S_improve_Detect结构创新

🚀🚀🚀本文改进:S_improve_Detect 全新的结构头创新,适配各个YOLO 🚀🚀🚀S_improve_Detect 在各个场景都能够有效涨点 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; 1. S_improve_Detect介

Gradle笔记 一 Gradle的安装与入门

文章目录 Gradle 入门Gradle 简介学习Gradle 的原因&#xff1a; 常见的项目构建工具Gradle 安装Gradle 安装说明安装JDK 下载并解压到指定目录配置环境变量检测是否安装成功 Gradle 项目目录结构Gradle 创建第一个项目Gradle 中的常用指令修改maven 下载源Wrapper 包装器使用教…

CleanMyMac2024破解版如何下载?

CleanMyMac作为一款专业的苹果电脑清理软件&#xff0c;它不仅仅能单纯的卸载不用、少用的应用&#xff0c;同时还支持&#xff1a;1、清理应用程序的数据文件&#xff0c;将应用重置回初始状态&#xff0c;减少空间占用&#xff1b;2、自动检查应用更新&#xff0c;保持应用的…

Android系统Launcher启动流程学习(二)launcher启动

Zygote&#xff08;孵化器&#xff09;进程启动 在init进程中有解析.rc文件&#xff0c;在这个rc文件中配置了一个重要的服务service–zygote&#xff0c;这是app程序的鼻祖 zygote进程主要负责创建Java虚拟机&#xff0c;加载系统资源&#xff0c;启动SystemServer进程&#…

C语言switch语句

文章目录 前言一、switch语句二、switch语句中的break三、switch语句中的defaultswitch语句中的case和default的顺序问题: 总结 前言 本文将详细介绍switch语句&#xff0c;break和defualt的用法 一、switch语句 switch语句的表达式&#xff1a; switch (expression){case va…

由于flutter_app依赖于flutter_swiper>=0.0.2,不支持零安全,版本解决失败。

参考 dart3.0使用flutter_swiper报错记录 flutter_swiper package - All Versions从官网的信息可以看到 Dart3版本不兼容 最小兼容的Dart SDK版本需要2.0 Flutter SDK 版本列表Flutter SDK 版本列表 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 说明&#xff1a;因…

从物理磁盘到数据库 —— 存储IO链路访问图

原图来自&#xff1a;数据库IO链路访问图 – OracleBlog 由于很复杂&#xff0c;为了加深理解自己重新画了一次&#xff0c;另外参考其他文档补充了各部分的插图和介绍。 一、 存储服务器 1. 物理磁盘 外层的壳子称为硬盘笼 cage 2. chunklet Chunklet 是一个虚拟概念而不是实…

分布式锁在Redis集群中的实践与探讨

分布式锁的基本概念 分布式锁是在分布式计算环境下&#xff0c;用来确保多个进程或线程在访问某些共享资源时能够避免冲突的一种同步机制。其主要目的是为了保持数据的一致性和完整性。为了达到这个目的&#xff0c;分布式锁需要满足互斥性、无死锁和容错性三个基本条件。 互…

SystemC入门之测试平台编写完整示例:全加器

导读: 本文将完整演示基于systemC编写一个全加器的测试平台。具体内容包括&#xff1a;激励平台&#xff0c;监控平台&#xff0c;待测单元的编写&#xff0c;波形文件读取。 1&#xff0c;main函数模块 搭建一个测试平台主要由&#xff1a;Driver, Monitor, DUT(design under …