当前位置: 首页 > news >正文

第四章:前端框架Vue基础入门

文章目录

  • 一、Vue框架概述
    • 1.1 声明响应式的数据
  • 二、Vue内置指令
    • 2.1、条件渲染指令v-if/v-show
    • 2.2 v-for: 列表渲染
    • 2.3、v-text/v-html 模板指令
    • 2.4 v-on:事件监听器
    • 2.6 动态绑定v-bind
    • 2.7 v-model表单元素值绑定
  • 三、计算属性与监视
    • 3.1 计算属性computed
    • 3.2 watch侦听器
    • 3.3 watch、watchEffect、computed区别
  • 四、高级特性
    • 4.1 组件
      • 4.1.1 创建组件
      • 4.1.2 组件通信
    • 4.2 生命周期
  • 六、脚手架案例
    • 6.1 vue-router:前端路由
    • 6.2 axios:接口请求

本章学习目标:

  • 了解Vue框架架构思想
  • 掌握Vue核心指令
  • 掌握计算属性与监视
  • 掌握组件化开发模式

一、Vue框架概述

  • 官方文档:https://cn.vuejs.org/guide/introduction.html.
  • 文档可选择使用optionsAPI(选项式API)阅读,或者CompositionApi(组合式API)阅读。选项式API更适合平滑从vue2过渡,以下示例均以Compositions API方式编写。
  • 如何使用compositions API? : 在.vue文件的script标签上,添加setup属性则被识别为使用compositionsAPI。不添加则默认为optionsAPI方式
    在这里插入图片描述
<script setup>
// 组合式API写法
</script><script>
// 选项式写法
export default {components:{},data(){ return {}},methods:{},
}
</script>

1、VUE的优势:

  • 渐进式框架,没有强主张。
  • 只是个轻量视图,只做了自己该做的事。
  • 渐进式:数据绑定——》路由控制——》组件开发——》数据共享

2、Vue是什么?

  • Vue.js (读音 /vju:/,类似于view) 是一套构建用户界面的渐进式框架。
  • 与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计
  • 轻量级MVVM框架
  • 通过简单的API,提供高效的数据绑定和灵活的组件系统

3、VUE的引入步骤(三种方式)

  1. 直接下载vue.js的库文件,使用script标记引入到页面中。
  2. 使用cdn进行引入,网络上的vue。
  3. 使用npm进行安装。

4、创建一个vue应用

  • 本节以vue官方脚架方式来进行demo演示。
  • vue3推荐使用create-vue来创建基于 Vite 的新项目。
  • 脚手架地址:https://github.com/vuejs/create-vue
# 1、安装项目模板
npm create vue@latest
# 2、demo用,对话内容都选No
# 3、进入创建好的文件
cd vue-project
# 4、安装依赖
npm install
# 5、启动项目
npm run dev   
  • 脚手架安装自定义选项
    在这里插入图片描述

  • 创建后生成项目目录结构如下:
    在这里插入图片描述

  • 成功启动后,以浏览器中访问:http://127.0.0.1:5173/
    在这里插入图片描述

打开项目后

  • 打开App .vue(入口模板文件)
  • 打开components目录,里面的所有.vue文件即为组件
  • .vue文件即为vue模板组件,主要分为三大块script(交互脚本), template(HTML),style(样式)
  • 清除内容,只留下script,template,style标签,看页面如何变化
<template>
<h1>hello world!</h1>
</template><script setup>
console.log("hello world!")
</script><style scoped>
h1{color:red;
}
</style>

1.1 声明响应式的数据

  • 在vue3中,新增了ref,reactive函数来定义一个响应式数据
  • ref(): 接收参数作为初始值,并将参数包装为具有响应性的ref对象返回,通过返回的ref对象的.value属性来取值,在选项式API的setup()函数或在带setup属性的script标签中定义使用
  • reactive() : 直接定义一个具有响应性的对象(ref是将数据包装为特殊ref对象)
    • reactive:只能用于定义对象类型 (对象、数组和如 Map、Set 这样的集合类型)。不支持原始类型
    • 不能替换整个被定义的对象,这样会导致响应性连接丢失
    • reactive定义的响应式对象,不能使用解构取值,也会导致响应性连接丢失
<template><div><p>定义的ref值:{{ refVal }}</p><p>定义的reactive值:{{ obj.count }}</p></div>
</template><script setup>
import {ref,reactive} from 'vue'
let refVal = ref("hello")
// 在template模板中会用ref对象的值时不需要.value,但在script中需要
console.log(refVal.value)let obj = reactive({count:1
})
</script><style scoped>
</style>

二、Vue内置指令

以下demo以vue3的composition API为例使用

2.1、条件渲染指令v-if/v-show

  • v-if: 条件渲染,显示与隐藏(布尔值)
    • v-if: 基于表达式值的真假性,来条件性地渲染元素或者模板片段
    • v-if-else:与v-if搭配使用,实现链式调用
    • v-else:与v-if搭配使用,实现链式调用
    • 注意:当 v-if 元素被触发,元素及其所包含的指令/组件都会销毁和重构。如果初始条件是假,那么其内部的内容根本都不会被渲染。
  • v-show:条件渲染
    • 原理:v-show 通过设置内联样式的 display CSS 属性来工作,当元素可见时将使用初始 display 值。

v-if与v-show的区别?
v-if通过值的真假来控制元素是否被渲染来实现显隐,而v-show通过css的display属性来控制实现显示与隐藏。v-if元素每一次触发都会引起重构。

<template><div><div v-if="type === 'A'">A</div><div v-else-if="type === 'B'">B</div><div v-else-if="type === 'C'">C</div><div v-else>Not A/B/C</div></div>
</template><script setup>
// 声明一个变量
let type ='B'
</script>
<style scoped>
</style>

2.2 v-for: 列表渲染

  • 基于原始数据多次渲染元素或模板块
  • 支持遍历的原始数据可以是:Array | Object | number | string | Iterable
<template><div><!-- 遍历数组 --><div><span v-for="(item,index) in arr" :key="index">{{item}},</span></div><!-- 遍历对象 --><div><span v-for="(value,key) in obj" :key="key">{{key}}-{{value}},</span></div></div>
</template><script setup>let arr = ['apple','banana','peach','cherry']let obj={"name":"张三","age":"18","sex":"男"}
</script>
<style scoped>
</style>

2.3、v-text/v-html 模板指令

  • v-text: 更新元素的文本内容(类似DOM API中的innerText)
  • v-html:更新元素的 innerHTML。(类似innerHTML)
<template><div><div v-text="textStr"></div><div v-html="htmlStr"></div></div>
</template><script setup>let textStr = "这是一段文本,html内容不会被解析为html.如<h1>h1标签</h1>"let htmlStr = "<h1>这是html内容,可以被解析</h1>"
</script>
<style scoped>
</style>

2.4 v-on:事件监听器

  • 给元素绑定事件监听器,简写为"@"
  • 参数:event对象
  • 修饰符:
    • .stop - 阻止冒泡,调用 event.stopPropagation()。
    • .prevent - 阻止默认行为,调用 event.preventDefault()。
    • .capture - 在捕获模式添加事件监听器。
    • .self - 只有事件从元素本身发出才触发处理函数。
    • .{keyAlias} - 只在某些按键下触发处理函数。
    • .once - 最多触发一次处理函数。
    • .left - 只在鼠标左键事件触发处理函数。
    • .right - 只在鼠标右键事件触发处理函数。
    • .middle - 只在鼠标中键事件触发处理函数。
    • .passive - 通过 { passive: true } 附加一个 DOM 事件。
<template><div><button v-on:click="onclick1">普通点击</button><div v-on:click="testPropogation">防止冒泡点击,使用@别名绑定<button @click.stop="onclick2">防冒泡点击</button></div><div @click.capture="captureHandler">captureHandler:捕获触发click,点button,先触发captureHandler,再必testCapture<button @click="testCapture">testCapture</button></div><a href="https://www.baidu.com" @click.prevent="preventHandler">点击不跳转</a><button @click.once="onceHandler">只响应一次,再点没用</button><div>按下enter触发<input @keyup.enter="onEnter" /></div></div>
</template><script setup>function onclick1(){alert("普通点击")}
//  冒泡测试function onclick2(){alert("防冒泡点击")}function testPropogation(){alert("点击div或冒泡触发")}
//  捕获测试
function captureHandler(){alert("点了外层div")
}
function testCapture(){alert("捕获触发,或者直接点击按钮触发")
}
// prevent测试
function preventHandler(){alert("preventHandler")
}
// .once测试
function onceHandler(){alert("once事件触发,再点没用")
}
// .{keyAlias}测试
function onEnter(){alert("按下enter键")
}
</script>
<style scoped>
</style>

2.6 动态绑定v-bind

  • 用于绑定 class 或 style
  • 用于绑定组件prop
  • 简写
<template><div><!-- 绑定DOM属性 --><img style="width:100px" v-bind:src="imgSrc"/><!-- 绑定style --><img :style="{width:'200px',height:'100px',marginLeft:'20px'}" v-bind:src="imgSrc"/><!-- 绑定class --><div :class="classArr" >绑定class数组</div></div>
</template><script setup>
let imgSrc = "http://imgsrc.baidu.com/baike/pic/item/ac345982b2b7d0a25cd01174cbef76094b369a39.jpg"
// 绑定class
let classArr = ['w100','bg-blue']
</script><style >
.w100{width: 100px;height: 100px;
}
.bg-blue{background: blue;
}
</style>

2.7 v-model表单元素值绑定

  • 在表单输入元素或组件上创建双向绑定
  • 支持标签:input,select,textarea或者vue components
  • 修饰符:
    • .lazy - 监听 change 事件而不是 input
    • .number - 将输入的合法字符串转为数字
    • .trim - 移除输入内容两端空格
<template><div>输入--------》<input type="text" v-model="inputVal">双向绑定显示--------》<div>inputVal: {{inputVal}}</div></div>
</template>
<script setup>
// 使用 ref() 函数来声明响应式状态
import {ref,reactive} from "vue"
let inputVal=ref("aaa")
// ref对象通过.value来获取其值
console.log(inputVal.value)
</script>
<style></style>

三、计算属性与监视

3.1 计算属性computed

  • 对于复杂的变量值(需要进一步通过逻辑处理返回的值)推荐通过计算属性来定义
  • 返回值:一个计算属性 ref,但计算属性 ref 也会在模板中自动解包,因此在模板表达式中引用时无需添加 .value
  • 计算属性会自动追踪响应式依赖
  • computed函数参数:默认为一个getter函数,函数返回值即为想要的计算结果。传入包括get,set函数的对象可设置读写操作
<template><div>计算属性1(默认只可读):{{ authorMsg }}</div><div>计算属性2:{{fullName}}</div>
</template>
<script setup>
// ref() 函数来声明响应式状态
// computed() 函数来声明计算属性
import { ref,computed } from "vue";
let author = {name:"张三",fruits:["apple","banana","peach","cherry"]
}
// 示例1:默认传入一个getter函数
let authorMsg = computed(()=>{let authorName = author.namelet fruitsStr = author.fruits.map(item=>item+',')return `${authorName}喜欢吃的水果有:${fruitsStr}`
})const firstName = ref('张')
const lastName = ref('三')const fullName = computed({// getterget() {return firstName.value + ' ' + lastName.value},// setterset(newValue) {// 注意:我们这里使用的是解构赋值语法let [first, last] = newValue.split("")firstName.value=firstlastName.value =last}
})
setTimeout(() => {fullName.value="王五"
}, 2000);
</script>
<style>
</style>

3.2 watch侦听器

  • 概述:侦听器,在侦听的某个响应式状态发生变化时,触发其回调函数
  • 应用场景:根据异步操作的结果去修改另一处的状态
  • 语法:watch(数据源, 回调函数)
  • 数据源: ref (包括计算属性)、一个响应式对象(reactive)、一个 getter 函数、或多个数据源组成的数组
  • 深层侦听属性:deep: true
  • 立即回调属性:immediate: true
  • 回调触发时间: 默认情况下,回调会在vue组件更新之前调用,因此若在回调中访问DOM会是更新前的状态,所以尽量避免在watch回调中访问dom。如果想在回调中访问Vue更新之后 的DOM,需要添加属性 {flush: ‘post’}
  • 属性语法
watch(source, callback, {deep: true, // 深层侦听immediate: true, // 立即执行一次回调flush: 'post', // 访问Vue更新之后的DOM
})
  • 示例
<template><div><div @click="randomChange('x')">触发x变化</div><div @click="randomChange('y')">触发y变化</div><div @click="() => (obj.count = 10)">reactive值变化</div></div>
</template>
<script setup>
import { ref, watch, reactive } from "vue";
const x = ref(0);
const y = ref(0);// 触发变化函数
function randomChange(name) {let randomNum = Math.random() * 10;if (name == "x") {x.value = randomNum;}if (name == "y") {y.value = randomNum;}
}// 1、监听单个 ref
watch(x, (newX) => {console.log(`例1:监听单个ref,x is ${newX}`);
});// 2、监听getter 函数,x,y的变化都会触发
watch(() => x.value + y.value,(sum) => {console.log(`例2:getter函数监听变化,sum of x + y is: ${sum}`);}
);// 3、多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {console.log(`例3:多来源数组监听,x is ${newX} and y is ${newY}`);
});// 4、监听响应式对象
const obj = reactive({ count: 0 });// 错误写法,因为 watch() 得到的参数是一个 number
// watch(obj.count, (count) => {
//   console.log(`count is: ${count}`)
// })
// 正确写法
watch(() => obj.count,(count) => {console.log(`例4、监听reactive响应式对象,count is: ${count}`);}
);
</script><style>
</style>
  • 其他参数

watch(source, (newValue, oldValue) => {// 注意:`newValue` 此处和 `oldValue` 是相等的// *除非* state.someObject 被整个替换了// deep: 深度监听// immediate:立即执行,且当 `source` 改变时再次执行
}, { immediate: true ,deep:true})

3.3 watch、watchEffect、computed区别

watchEffect使用场景:有多个依赖项需要侦听,或需要侦听一个嵌套数据结构中的几个属性时,watchEffect() 比深度侦听器更有效

  • 区别:
    • watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西.,且仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖
  • watchEffect,会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。
  • computed,必须有return返回,使用方法与data中的数据一样,如果函数所依赖的属性没有变化,从缓存中读取

四、高级特性

4.1 组件

组件:组件常常被组织成层层嵌套的树状结构。在vue中.vue文件就是组件(单文件组件SFC)

4.1.1 创建组件

1、参考vue-project项目生成目录,其中components就是约定的组件存放目录,在components中新建Child.vue组件如下

  • child.vue
<template><div ><h1>{{ msg }}</h1></div>
</template>
<script setup >
import {ref, reactive} from "vue"
let msg = ref("这是Child")
</script><style scoped>
</style>

2、父组件中引入。(以App.vue为例,此处以setup语法糖方式编写,只需引入Child.vue就会自动注册该组件。若在optionsApi中需要显示注册components)

  • App.vue
<template><div class="">这是Parent<p>------------------------分隔线------------------</p><Child /></div>
</template>
<script setup lang="ts">
// 引入组件
import Child from './components/Child.vue'
import {ref, reactive} from "vue"</script>

4.1.2 组件通信

  • 组件通信主要分为:父子组件间通信,非父子组件间通信
  • 父传子:props属性
  • 子传父:子组件自定义事件,并通过$emit触发

1、父传子props

  • Child.vue
<template><div ><h1>{{ parentMsg }}</h1></div>
</template>
<script setup >
// 1. 引入defineProps宏
import { defineProps} from "vue"
// 2.定义props
defineProps({parentMsg: {type: String}
})
</script>
  • App.vue
<template><div class="">这是Parent<p>------------------------分隔线------------------</p><!-- 3.传入props --><Child :parentMsg="toChild"/></div>
</template>
<script setup lang="ts">
import Child from './components/Child.vue'
import {ref} from "vue"let toChild = ref("来自Parent的消息")
</script>
  • 子组件向父组件传递参数——自定义事件,$emit调

2、子传父

  • App.vue
<template><div class="">这是Parent<p>------------------------分隔线------------------</p><!-- 3.绑定子组件自定义事件 --><Child @sayHi="hiHandler"/></div>
</template>
<script setup lang="ts">
import Child from './components/Child.vue'// 4.接收子组件抛出事件的参数msg
function hiHandler(msg){alert(msg)
}
</script>
  • child.vue
<template><div ><h1 @click="clickHandler">点击传给Parent</h1></div>
</template>
<script setup >
// 1. 引入defineEmits宏
import { defineEmits } from "vue"
// 2.定义组件会抛出的事件
const emit  = defineEmits(['sayHi'])function clickHandler(){console.log("child 中触发点击")// 3.触发抛出事件emit('sayHi','来自Child的消息')
}
</script>

3、py: provice/inject

如果是祖辈组件与孙辈组件间传值,可使用provide、inject

  • provide(key,value), 必须在组件的setup()阶段同步调用
  • inject(key,defaultValue) : 注入一个由祖先组件或整个应用(通过app.provide())提供的值,defaultValue可选,当没匹配到key对应的值时显示
  • 示例:组件结构如下App>Middle>Child
  • App.vue
<template><div class="">这是App.vue,子组件为Middle,孙组件为Child(由middle包含)<p>------------------------分隔线------------------</p><Middle /></div>
</template>
<script setup lang="ts">
import Middle from './components/Middle.vue'
import {provide,ref} from 'vue'let count = ref(0)// 提供静态值
provide("appName",'测试Demo')
// 提供响应值
provide("count",count)
</script>
  • Middle.vue
<template><div >这是隔代组件,内部引入Child组件<Child /></div>
</template>
<script setup >
import Child from './Child.vue'
</script>
  • Child.vue
<template><div >这是Child.vue内容<p>来自app.vue的appName: {{ appName }}</p><p>这是app.vue的count: {{ count }}</p></div>
</template>
<script setup >
import {inject} from 'vue'let appName = inject("appName")
let count = inject("count")</script>

4.2 生命周期

在vue3 compositionAPI中,生命周期钩子函数都有on前缀,常用如onMounted,onUpdated,onUnmounted(),onActived()

  • onMounted(): 组件挂载完成后执行
  • onUpdated(), 在组件因为响应式状态变更而更新其 DOM 树之后调用
  • onUnMounted(), 在组件实例被卸载之后调用。
  • onActived(),若组件实例是 缓存树的一部分,当组件被插入到 DOM 中时调用。
<template><div >{{ count }}</div>
</template>
<script setup lang="ts">import {ref, onMounted,onUpdated} from "vue"
let count = ref(0)
setTimeout(()=>{count.value++console.log("count改变将触发onUpdated")
},2000)onMounted(()=>{console.log("onMounted")
})
onUpdated(()=>{console.log("onUpdated")
})
</script>

六、脚手架案例

6.1 vue-router:前端路由

官网地址:https://router.vuejs.org/zh/, 在创建单页应用项目时脚手架会提醒是否安装vue router,VueRouter作为前端路由库,控制整个Vue项目的页面跳转服务。以下示例介绍vue-router集成到vue项目中的使用
1、安装vue router

npm install vue-router@4

2、定义路由
- 项目目录中新建router文件夹,并新建index.js

// router/index.js
import {createRouter,createWebHashHistory} from 'vue-router'// 1、定义路由组件(实际应用中通过导入.vue文件组件)
const Home = ()=>import("@/pages/Home.vue")
const About = ()=>import("@/pages/About.vue")// 2、定义路由
const routes = [{ path: '/', component: Home },{ path: '/about', component: About },
]// 3. 创建路由实例并传递 `routes` 配置
const router = createRouter({history:createWebHashHistory(), // 以hash模式创建路由routes,
})export default router

3、挂载路由到Vue实例中
- 打开项目src/main.js文件

// main.js
import './assets/main.css'
import router from '@/router'import { createApp } from 'vue'
import App from './App.vue'// 创建应用实例
const app = createApp(App)
// 整个应用支持路由
app.use(router)
// 挂载整个应用
app.mount('#app')

4、页面中通过router-view渲染

  • App.vue

<template><div>这是App.vu<p>------------------------分隔线------------------</p><router-link to="/">Go to Home</router-link> <br><router-link to="/about">Go to About</router-link><div class="router-page" style="border:1px solid #ddd;padding:10px;"><router-view></router-view></div></div>
</template>
<script setup >
</script>

5、路由跳转及传参

在vue3中使用组合式API编写router业务时,参考文档:https://router.vuejs.org/zh/guide/advanced/composition-api.html

<script setup >
import {useRouter, useRoute } from 'vue-router'
import {onMounted} from 'vue'
const router = useRouter()
const route = useRoute()function goAbout(){// 路由跳转router.push({path:'/about',query:{name:'lala'}})
}
onMounted(()=>{console.log(route.path)
})
console.log(router)
</script>

6.2 axios:接口请求

官网地址: https://www.npmjs.com/package/axios#axios-api

axios是一个基于Promise的http客户端请求工具,可以在浏览器或者node.js中使用。
1、安装

npm install axios --save

2、src目录下创建api文件夹,简单封装
- 一般对axios进行简单封装,使用统一域名,请求拦截,响应拦截,设置超时时间等

// src/api/http.js
import axios from 'axios'const request = axios.create({baseURL: 'https://www.xxx.com', // 后端服务地址timeout: 120000,  // 超时时间
})// 请求拦截器,用于在发出请求前,做一些操作
request.interceptors.request.use(config=>{// 假设本地有tokenif(localStorage.getItem("token")){config.headers.token = token}return config
})// 响应拦截器,用于处理后端报错等
request.interceptors.response.use(response=>{if(response.status!==200){console.log("请求响应服务出错了,具体再看")}return response
})export default request
  • 封装业务请求
// src/api/login.js
import request from './http'const Api = {getCode:'/api/v1/getCode',login:'/api/v1/login'
}// 假设获取验证码
export function getCode(params){return request.get(Api.getCode, params)
}// 登录
export function login(params){return request.post(Api.login, params)
}

3、组件间使用(伪代码示例用)
- pages/login.vue

<template><div >这是登录页</div>
</template>
<script setup >
import {getCode,login} from "@/api/login"
import {ref, onMounted} from "vue"// 调用请求
let params = {name:'zhangsan',password:'123455'
}
login(params).then(res=>{console.log(res)
})
</script>

相关文章:

第四章:前端框架Vue基础入门

文章目录 一、Vue框架概述1.1 声明响应式的数据 二、Vue内置指令2.1、条件渲染指令v-if/v-show2.2 v-for: 列表渲染2.3、v-text/v-html 模板指令2.4 v-on:事件监听器2.6 动态绑定v-bind2.7 v-model表单元素值绑定 三、计算属性与监视3.1 计算属性computed3.2 watch侦听器3.3 wa…...

企业权限管理(十三)-用户关联角色操作

用户关联角色操作 从前台发送请求 <a href"${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id${user.id}" class"btn bg-olive btn-xs">添加角色</a>查询用户以及用户可以添加的角色 usercontroller //查询用户以及用…...

深入理解Vue 3.0x中的Suspense和异步组件

深入理解Vue 3.0x中的Suspense和异步组件 Vue 3.0x作为Vue.js框架的最新版本&#xff0c;引入了许多创新特性&#xff0c;其中Suspense和异步组件是重要的改进之一。在本文中&#xff0c;我们将深入探讨这两个特性&#xff0c;了解它们如何为现代Web应用带来更好的性能和用户体…...

Ajax 笔记(三)—— Ajax 原理

笔记目录 3. Ajax 原理3.1 XMLHttpRequest3.1.1 XHR 使用步骤3.1.2 查询参数3.1.3 数据提交 3.2 Promise3.2.1 Promise 使用步骤3.2.2 Promise 状态3.2.3 Promise 和 XHR 应用小案例 3.3 封装简易 axios3.3.1 核心封装代码3.3.2 支持传递查询参数3.3.3 支持传递请求体数据 Ajax…...

el-tree通过default-expand-all动态控制展开/折叠

1、如下图通过勾选框动态控制展开/折叠&#xff0c;全选/清空 2、实现方式如下&#xff1a;定义key&#xff0c;监听checked2修改treeKey&#xff0c;重新渲染tere&#xff1b;附加全选和清空。 <div class"tree"><el-checkbox v-model"checked1"…...

基于Bsdiff差分算法的汽车OTA升级技术研究(学习)

摘要 针对汽车OTA整包升级时&#xff0c;用户下载时间长&#xff0c;升级时间长&#xff0c;设备服务器端压力大等问题&#xff0c;本文提出了一种基于Bsdiff差分算法的汽车OTA升级技术。该算法能够对比新旧版本的差异&#xff0c;进行差分文件下载&#xff0c;减少软件包的下…...

如何使用CSS实现一个纯CSS的滚动条样式?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现自定义滚动条样式⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣…...

使用维纳过滤器消除驾驶舱噪音(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

vue所有UI库通用)tree-select 下拉多选(设置 maxTagPlaceholder 隐藏 tag 时显示的内容,支持鼠标悬浮展示更多

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 1.需求描述 引用的下拉树形结构支持多选&#xff0c;限制选中tag的个数&#xff0c;且超过制定个数&#xff0c;鼠标悬浮展示更多已选中。 2.先看下效果图 3.实现思路 首先根据API文档&#xff0c;先设置maxTagC…...

进行 200 瓦太阳能 (PV) 模块设计以测量太阳能光伏阵列的电压、电流和功率、综合负荷频率和电压控制系统的方法研究(Simulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

实战:工作中对并发问题的处理 | 京东物流技术团队

1. 问题背景 问题发生在快递分拣的流程中&#xff0c;我尽可能将业务背景简化&#xff0c;让大家只关注并发问题本身。 分拣业务针对每个快递包裹都会生成一个任务&#xff0c;我们称它为 task。task 中有两个字段需要关注&#xff0c;一个是分拣中发生的异常&#xff08;exp…...

解决VSCode CPU高占问题的方法

如果你也遇到VSCode的CPU占用过高的问题&#xff0c;可以尝试使用官方自带的插件Bisect&#xff08;扩展二分查找&#xff09;功能来查找具体是哪个扩展出了问题。 找到“糟糕”的扩展可能很容易&#xff0c;也可能很困难。 打开扩展视图 ( CtrlShiftX )&#xff0c;禁用扩展&…...

tensorflow 1.x和3090、cuda部署

这里写目录标题 3090、cuda和tensorflow 1.x 3090、cuda和tensorflow 1.x 因为3090只支持cuda11.0的版本&#xff0c;而tensorflow1.已经不再维护&#xff0c;没有出支持cuda11.0的版本了。 nvidia提供了TF1.x对RTX 3090、cuda11等新硬件的支持。卸载已有的tensorflow-gpu包和…...

vue-photo-preview( 照片预览功能 )

安装 npm install vue-photo-preview --save 引入项目 import preview from vue-photo-preview import vue-photo-preview/dist/skin.csslet options {fullscreenEl: false //是否可以全屏预览 }; Vue.use(preview, options)如果不写options 和 Vue.use(preview,options)&…...

Angular 独立组件入门

Angular 独立组件入门 如果你正在学习 Angular&#xff0c;那么你可能已经听说过独立组件&#xff08;Component&#xff09;。顾名思义&#xff0c;独立组件就是可以独立使用和管理的组件&#xff0c;它们能够被包含在其他组件中或被其他组件引用。 在本文中&#xff0c;我们…...

Lie group 专题:Lie 群

Lie group 专题&#xff1a;Lie 群 流形 流形的定义 一个m维流形是满足以下条件的集合M&#xff1a;存在可数多个称为坐标卡&#xff08;图集&#xff09;的子集合族.以及映到的连通开子集上的一对一映射&#xff0c;,称为局部坐标映射&#xff0c;满足以下条件 坐标卡覆盖M…...

Vue-打印组件页面

场景: 需要将页面的局部信息打印出来&#xff0c;只在前端实现&#xff0c;不要占用后端的资源。经过百度经验&#xff0c;决定使用 print-js和html2canvas组件。 1. 下载包 npm install print-js --save npm install --save html2canvas 2. 组件内引用 <script>impo…...

Python爬虫——scrapy_基本使用

安装scrapy pip install scrapy创建scrapy项目&#xff0c;需要在终端里创建 注意&#xff1a;项目的名字开头不能是数字&#xff0c;也不能包含中文 scrapy startproject 项目名称 示例&#xff1a; scrapy startproject scra_baidu_36创建好后的文件 3. 创建爬虫文件&…...

30 | 中国高校数据分析

一、数据源 本项目使用了两个csv的数据文件,一个是中国高校(大学)的数据,一个是中国高校专业设置的数据 数据基本栏位:高校(大学)的数据高校专业设置的数据学校学校省份专业类别城市专业名称地址国家特色专业水平层次办学类别办学类型985211双一流二、数据分析目标 本…...

开源低代码平台Openblocks

网友 HankMeng 想看低代码工具&#xff0c;正好手上有一个&#xff1b; 什么是 Openblocks &#xff1f; Openblocks 是一个开发人员友好的开源低代码平台&#xff0c;可在几分钟内构建内部应用程序。 传统上&#xff0c;构建内部应用程序需要复杂的前端和后端交互&#xff0c;…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...

【Vue】scoped+组件通信+props校验

【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性&#xff0c; 令样式只作用于当前组件的标签 作用&#xff1a;防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...

MyBatis-Plus 常用条件构造方法

1.常用条件方法 方法 说明eq等于 ne不等于 <>gt大于 >ge大于等于 >lt小于 <le小于等于 <betweenBETWEEN 值1 AND 值2notBetweenNOT BETWEEN 值1 AND 值2likeLIKE %值%notLikeNOT LIKE %值%likeLeftLIKE %值likeRightLIKE 值%isNull字段 IS NULLisNotNull字段…...

React与原生事件:核心差异与性能对比解析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...