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

uni-app(5):Vue3语法基础上

        Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统,只关注视图层,易于上手。所有东西都是响应式的。本文大部分内容来源于Vue3中文文档,但结合 uni-app 做了部分调整,以更有利于开发者快速上手。

1 vue的优势

        在传统开发中,用原生的 JavaScript DOM 操作函数对 DOM 进行频繁操作的时候,浏览器要不停的渲染新的 DOM 树,导致页面看起来非常卡顿。vue 是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和 DOM ,这样大大加快了访问速度和提升用户体验。

vue的优势:

  • 轻量级:几十K的体积
  • 界面与逻辑分离,与html接近的概念和写法
  • 响应式双向数据绑定,更新数据时无需再写代码更新界面,反之亦然。
  • 组件化,可方便协作。方便造轮子,也就自然有大量轮子可用
  • 虚拟DOM,比大多数手写操作dom的代码都更高效
  • 易于上手,设计直观、文档丰富

vue3相比vue2的优势:

  • 响应式系统提升
  • 更快,性能比Vue2快1.2~2倍(diff方法优化、静态提升、时间侦听器缓存、ssr渲染)
  • 更小,按需编译,体积比Vue2更小
  • 组合式API,提供更灵活的写法,也易于吸引react开发者
  • 加强TypeScript支持

2 白话uni-app

        如果你了解html、js,那么本章节将让你快速了解uni-app和它们的差异。

2.1 文件类型变化

  • 以前是.html文件,开发也是html,运行也是html。
  • 现在每个页面是一个.vue文件,开发是vue,但经过编译后,运行时已经变成了js文件(如果是uts则可能编译成kotlin、swift)。
  • 现代前端开发,很少直接使用HTML,基本都是开发、编译、运行。所以 uni-app 有编译器、运行时的概念。

2.2 文件内代码架构的变化

        以前一个 html 大节点,里面有 script 和 style 节点;

<!DOCTYPE html><html><head><meta charset="utf-8" /><title></title><script type="text/javascript"></script><style type="text/css"></style></head><body></body></html>

        现在 template 是一级节点,用于写tag组件, script 和 style 是并列的一级节点,也就是有3个一级节点。这个叫vue单文件组成规范。

<template><view>注意必须有一个view,且只能有一个根view。所有内容写在这个view下面。</view></template><script>export default {}</script><style></style>

2.3 外部文件引用方式变化

        以前通过script src、link href引入外部的js和css;

<script src="js/jquery-1.10.2.js" type="text/javascript"></script>
<link href="css/bootstrap.css" rel="stylesheet" type="text/css"/>

        现在是es6的写法, import 引入外部的js模块(注意不是文件)或css;js要require进来,变成了对象

	<script>var util = require('../../../common/util.js');  //require这个js模块var formatedPlayTime = util.formatTime(playTime); //调用js模块的方法</script>

        而在这个 util.js 里,要把之前的 function 封装为模块(module)的方法并导出(exports)。只有被导出的方法和属性才能被外部调用,不导出的属于模块内部函数和变量。这是es6的模块规范。

	function formatTime(time) {return time;//这里没写逻辑}module.exports = {formatTime: formatTime}

        当然还有一些高级的用法,比如在导出时可以重命名

	// 直接使用js模块的属性。var dateUtils = require('../../../common/util.js').dateUtils;// 将js导入并重命名为echarts,然后使用echarts.来继续执行方法。在hello uni-app有示例import * as echarts from '/components/echarts/echarts.simple.min.js';

        css外部文件导入。全局样式,在根目录下的 app.vue 里写入,每个页面都会加载 app.vue 里的样式。

<style>@import "./common/uni.css";.uni-hello-text{color:#7A7E83;}</style>

        另外,vue支持组件导入,可以更方便的封装一个包括界面、js、样式的库

2.4 组件/标签的变化

        以前是html标签,比如 <div> ,现在是小程序组件,比如 <view> 。标签与组件的区别:

  • 其实标签是老的概念,标签属于浏览器内置的东西。
  • 但组件,是可以自由扩展的。类似你可以把一段js封装成函数或模块,你也可以把一个ui控件封装成一个组件。

2.5 js的变化

        以前script里随便写js变量和function

<script type="text/javascript">var a;function funa () {}
</script>

        现在script里默认有export default,在里面写data、事件和method 

  • 写在 export default { 前面的变量,是页面内部的全局变量,可以在各种方法里使用。
  • export default {} 里是一个大json,data、生命周期、method都需要用逗号分隔。
  • data -> return 里,编写可以绑定在页面template模板里的变量,页面组件的text里绑定data数据使用{{}},比如下面例子中的textvalue。而下面的globalvar就不能在模板里绑定使用。在HBuilderX中,敲vdata代码块,可以快捷生成data的代码结构。
  • 页面的生命周期/事件,如下面的onLoad,和data平级。
  • 模板里要调用的方法,都需要写在methods下面。每个方法也需要用逗号分隔。不需要再使用function声明,只要写在methods下的函数,都可以在template里调用。
<template><view><text>{{textvalue}}</text><!-- 这里演示了组件值的绑定 --><button :type="buttontype" @click="changetextvalue()">修改为789</button><!-- 这里演示了属性和事件的绑定 --></view></template>
<script>var globalvar = 1function globalfun(){}export default {data() {return {textvalue:"123",buttontype:"primary"};},onLoad() {globalvar = 2globalfun()this.textvalue="456"//这里修改textvalue的值},methods: {changetextvalue() {this.textvalue="789"//这里修改textvalue的值}}}
</script>

        在上述例子中,传统写法的定义的变量globalvar和函数globalfun,可以在export default { }里使用,但无法在模板里直接绑定和调用。模板里只能绑定data里的变量、调用methods里的方法。

        以前的 DOM 操作,如果你想改变某个 DOM 元素的显示内容,比如一个view的显示文字:给view设id,然后js里通过选择器获取 DOM 元素,进一步通过js进行赋值操作,修改 DOM 元素的属性或值。

<html><head><script type="text/javascript">document.addEventListener("DOMContentLoaded",function () {document.getElementById("spana").innerText="456"})function changetextvalue () {document.getElementById("spana").innerText="789"}</script></head><body><span id="spana">123</span><button type="button" onclick="changetextvalue()">修改为789</button></body></html>

        现在的做法,是vue的绑定模式,给这个 DOM 元素绑定一个js变量,在script中修改js变量的值,DOM 会自动变化,页面会自动更新渲染。

  • 前端改用 MVVM(Model-View-ViewModel的简写)模式,简单来说,Model:代表数据模型,View:只专注视图UI处理,ViewModel:只处理业务和数据。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷,大幅减少代码行数,同时差量渲染性能更好。
  • uni-app 使用vue的数据绑定方式解决js和 DOM 界面交互的问题。
<template><view><text>{{textvalue}}</text><!-- 这里演示了组件值的绑定 --><button :type="buttontype" @click="changetextvalue()">修改为789</button><!-- 这里演示了属性和事件的绑定 --></view></template><script>export default {data() {return {textvalue:"123",buttontype:"primary"};},onLoad() {this.textvalue="456"//这里修改textvalue的值,其实123都来不及显示就变成了456},methods: {changetextvalue() {this.textvalue="789"//这里修改textvalue的值,页面自动刷新为789}}}</script>
  • 以前在是html的tag里用一个属性onclick来写点击事件
  • 现在是使用@click(其实是v-on:click的缩写,在uni-app里基本都使用缩写)调用methods里的方法。

3 在 uni-app 中使用vue的差异

   uni-app 在发布到H5时支持所有vue的语法;发布到App和小程序时,由于平台限制,无法实现全部vue语法,但 uni-app 仍是对vue语法支持度最高的跨端框架。相比Web平台, Vue.js 在 uni-app 中使用差异主要集中在两个方面:

  • 新增:uni-app 除了支持 Vue 实例的组件生命周期,还拥有应用生命周期及页面的生命周期。
  • 受限:相比 Web 平台,在小程序和 App 端部分功能支持不完善。

   uni-app 项目对 vue 3.0 的支持版本情况如下:

  • Web平台:支持。
  • 小程序平台:HBuilderX 3.3.3+ 编译器改为 vite,之前版本的编译器为webpack
  • App 平台:uni-app 3.2.5+支持。HBuilderX 3.3.13 起 nvue编译器升级为vite

注意事项

  • vue3 响应式基于 Proxy 实现,不支持iOS9ie11
  • 暂不支持新增的 Teleport,Suspense 组件。
  • 目前 HBuilderX 3.2 起已预置,之前的版本只能使用cli方式。

4 模板语法

   Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层组件实例的数据。 所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应性系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。

4.1 插值

4.1.1 文本

        数据绑定最常见的形式就是文本插值:

<template><view><view>Message: {{ msg }}</view></view></template><script>export default {data() {return {msg: 'Hello Vue!'}}}</script>

        {{ }}的内容将会被替代为对应数据对象上msg的值。无论何时,绑定的数据对象上msg发生了改变,插值处的内容都会更新。

4.1.2 使用 JavaScript 表达式

        迄今为止,在我们的模板中,我们一直都只绑定简单的 property 键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。

<template><view><view>{{ number + 1 }}</view><view>{{ ok ? 'YES' : 'NO' }}</view><!-- 把一个字符串分割成字符串数组,颠倒其元素的顺序,把数组中的所有元素放入一个字符串 --><view>{{ message.split('').reverse().join('') }}</view></view></template><script>export default {data() {return {number:1,ok:true,message: 'Hello Vue!'}}}</script>
<template><view><view v-for="(item,index) in 10"><!-- 通过%运算符求余数,实现隔行换色的效果 --><view :class="'list-' + index%2">{{index%2}}</view></view></view></template><script>export default {data() {return { }}}</script><style>.list-0{background-color: #aaaaff;}.list-1{background-color: #ffaa7f;}</style>

        这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

<template><view><!-- 这是语句,不是表达式 --><view>{{ var a = 1 }}</view><!-- 流控制也不会生效,请使用三元表达式 --><view>{{ if (ok) { return message } }}</view></view></template><script>export default {data() {return {ok:true,message: 'Hello Vue!'}}}</script>

        模板表达式都被放在沙盒中,只能访问全局变量的一个白名单

  • Infinity
  • undefined
  • NaN
  • isFinite
  • isNaN
  • parseFloat
  • parseInt
  • decodeURI
  • decodeURIComponent
  • encodeURI
  • encodeURIComponent
  • Math
  • Number
  • Date
  • Array
  • Object
  • Boolean
  • String
  • RegExp
  • Map
  • Set
  • JSON
  • Intl
  • BigInt

        你不应该在模板表达式中试图访问用户定义的全局变量。

4.2 指令

        指令是带有 v- 前缀的特殊属性。

  • 指令属性的值预期是单个 JavaScript 表达式 (v-for 和 v-on 是例外情况,稍后我们再讨论)。
  • 指令的作用是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM 。
  • 一些指令能够接收一个“参数”,在指令名称之后以冒号( : )表示。

4.2.1 v-bind

        动态地绑定一个或多个属性,v-bind缩写为‘ : ’,可以用于响应式地更新 HTML attribute

<!-- 完整语法 --><image v-bind:src="imgUrl"></image><!-- 缩写 --><image :src="imgUrl"></image><button v-bind:disabled="isButtonDisabled">Button</button>

        在这里 src 是参数,告知 v-bind 指令将该元素的 src attribute 与表达式 imgUrl 的值绑定。如果 isButtonDisabled 的值是 null 或 undefined,则 disabled attribute 甚至不会被包含在渲染出来的 button 元素中。

4.2.2 v-on

        v-on 指令,它用于监听 DOM 事件。v-on缩写为‘ @ ’,下文简称为 @事件

<!-- 完整语法 --><view v-on:click="doSomething">点击</view><!-- 缩写 --><view @click="doSomething">点击</view>

4.2.3 v-once

        只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。和前端框架中的理解不同,客户端里要实现复用的逻辑,会标记模板节点的状态,添加了 v-once 能保证节点只渲染一次,但是并不一定能优化渲染性能,反而可能会拖慢客户端复用节点时的比对效率。h5、微信小程序均不支持。

<!-- 单个元素 --><view v-once>This will never change: {{msg}}</view><!-- 有子元素 --><view v-once><text>comment</text><text>{{msg}}</text></view>

4.2.4 v-html

        更新元素的 innerHTML。

  • 注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。
  • 如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。
  • App端和H5端支持 v-html ,微信小程序会被转为 rich-text,其他端不支持 v-html 。
	<template><view><view v-html="rawHtml"></view></view></template><script>export default {data() {return {rawHtml: '<div style="text-align:center;background-color: #007AFF;"><div >我是内容</div><img src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png"/></div>'}}}</script>

5 Data 选项

   data 选项已标准化为只接受返回一个初始数据对象的函数(注意函数内返回的数据对象不要直接引用函数外的对象);否则页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。

//正确用法,使用函数返回对象data() {return {title: 'Hello'}}//错误写法,会导致再次打开页面时,显示上次数据data: {title: 'Hello'}//错误写法,同样会导致多个组件实例对象数据相互影响const obj = {title: 'Hello'}data() {return {obj}}

6 Class 与 Style 绑定

6.1 绑定 HTML Class

        我们可以传给 :class (v-bind:class 的简写) 一个对象,实现动态地切换 class。也可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class 共存。

<template><view><view class="static" :class="{ active: isActive}">hello uni-app</view><view class="static" :class="{ active: isActive, 'text-danger': hasError }">hello uni-app</view></view></template><script>export default {data() {return {isActive: true,hasError: false}}}</script><style>.static{color: #2C405A;}.active{background-color: #007AFF;font-size:30px;}.text-danger{color: #DD524D;}</style>

        渲染结果为

	<view class="static active"></view>

        当 isActive 或者 hasError 变化时,class 列表将相应地更新。例如,如果 hasError 的值为 true ,class 列表将变为 static active text-danger

        可以把一个数组传给 v-bind:class,以应用一个 class 列表。

<template><view><view :class="[activeClass,errorClass]">hello uni-app</view></view></template><script>export default {data() {return {activeClass: 'active',errorClass: 'text-danger'}}}</script><style>.active{background-color: #007AFF;}.text-danger{font-size:60rpx;color:#DD524D;}</style>

        渲染的结果为: 

	<view class="active text-danger"></view>

        如果你想根据条件切换列表中的 class,可以使用三元表达式:

<view :class="[isActive ? activeClass : '', errorClass]"></view>

        这样写将始终添加 errorClass,但是只有在 isActive 为 truthy 时才添加 activeClass。在 JavaScript 中,truthy(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 false、0、""、nullundefined 和 NaN 以外皆为真值)。

        不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:

<template><view><view class="static" :class="[{ active: isActive }, errorClass]">hello uni-app</view></view></template><script>export default {data() {return {isActive: true,errorClass: 'text-danger'}}}</script><style>.static{font-size:30rpx;}.active{background-color: #007AFF;}.text-danger{font-size:60rpx;color:#DD524D;}</style>

        注意:以:style=""这样的方式设置px像素值,其值为实际像素,不会被编译器转换。此外还可以用计算属性 computed 方法生成 class 或者 style 字符串,插入到页面中,举例说明:

	<template><view><view class="container" :class="computedClassStr">hello uni-app</view><view class="container" :class="{active: isActive}">hello uni-app</view></view></template><script>export default {data() {return {isActive: true}},computed: {computedClassStr() {return this.isActive ? 'active' : ''}}}</script><style>.active {background-color: #007AFF;font-size:30px;}</style>

6.2 绑定内联样式

        :style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:

<template><view :style="{ color: activeColor, fontSize: fontSize + 'px' }">hello uni-app</view></template><script>export default {data() {return {activeColor: 'red',fontSize: 30}}}</script>

        直接绑定到一个样式对象通常更好,这会让模板更清晰:

<template><view :style="styleObject">hello uni-app</view></template><script>export default {data() {return {styleObject: {color: 'red',fontSize: '13px'}}}}</script>

        同样的,对象语法常常结合返回对象的计算属性使用。:style 的数组语法可以将多个样式对象应用到同一个元素上:

<template><view><view :style="[baseStyles, overridingStyles]">hello uni-app</view></view></template><script>export default {data() {return {baseStyles: {color: 'green',fontSize: '30px'},overridingStyles: {'font-weight': 'bold'}}}}</script>

        在 :style 中使用需要 (浏览器引擎前缀) vendor prefixesa 的 CSS property 时,如 transformVue 将自动侦测并添加相应的前缀。可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

	<view :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></view>

        这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex

7 条件渲染

7.1 v-if和v-else

   v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。 使用 v-else 指令来表示 v-if 的“else 块”。 v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

	<template><view><view v-if="seen">现在你看到我了</view><view v-else>你看不到我了</view></view></template><script>export default {data() {return {seen: true}}}</script>

   v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:

<template><view><view v-if="type === 'A'">A</view><view v-else-if="type === 'B'">B</view><view v-else-if="type === 'C'">C</view><view v-else>Not A/B/C</view></view></template><script>export default {data() {return {type:'B'}}}</script>

        类似于 v-else ,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。

7.2 条件渲染分组

        因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 template 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 template 元素。

<template v-if="seen"><view>标题</view><view>内容:现在你看到我了</view></template>

7.3 v-show

        另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:

<view v-show="ok">Hello!</view>

        不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性的 display 。注意,v-show 不支持 template 元素,也不支持 v-else。nvue 页面不支持 v-show。

7.4 v-if 和 v-show 区别

  • v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  • v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  • 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换,来控制元素的显示和隐藏。

根据应用场景选择

  • v-if 有更高的切换开销,如果在运行时条件很少改变,则使用 v-if 较好。
  • v-show 有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好。

注意

  • 不推荐同时使用 v-if 和 v-for
  • 当 v-if 与 v-for 一起使用时,v-if 具有比 v-for 更高的优先级

相关文章:

uni-app(5):Vue3语法基础上

Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统&#xff0c;只关注视图层&#xff0c;…...

深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化,全面掌握性能优化核心技巧

深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化&#xff0c;全面掌握性能优化核心技巧 一、分包核心价值与基本原理 1.1 为什么需要分包 首屏加载优化&#xff1a;减少主包体积&#xff0c;提升TTI&#xff08;Time to Interactive&#xff09;缓存利用率提升&am…...

ubuntu下docker安装mongodb-支持单副本集

1.mogodb支持事务的前提 1) MongoDB 版本&#xff1a;确保 MongoDB 版本大于或等于 4.0&#xff0c;因为事务支持是在 4.0 版本中引入的。 2) 副本集配置&#xff1a;MongoDB 必须以副本集&#xff08;Replica Set&#xff09;模式运行&#xff0c;即使是单节点副本集&#x…...

spring-boot-starter-data-redis应用详解

一、依赖引入与基础配置 添加依赖 在 pom.xml 中引入 Spring Data Redis 的 Starter 依赖&#xff0c;默认使用 Lettuce 客户端&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis<…...

5060显卡驱动PyCUDA开发环境搭建

5060显卡驱动PyCUDA开发环境搭建 本文手把手讲解了RTX5060ti显卡从上手尝试折腾&#xff0c;到在最新Ubuntu LTS版本上CUDA开发环境搭建成功的详细流程。 1.1 开机后Ubuntu2404LTS不识别显卡 1.1.1 显卡硬件规格要求 笔者下单的铭瑄电竞之心&#xff0c;安装规格是PCIe …...

redis搭建最小的集群,3主3从

create.sh脚本用于快速部署一个Docker化的Redis集群。首先&#xff0c;脚本创建了一个自定义的Docker网络redis-net&#xff0c;并指定了子网以防止IP变动。接着&#xff0c;脚本设置了宿主机的公网IP&#xff0c;并生成了六个Redis节点的配置文件&#xff0c;每个配置文件都启…...

《帝国时代1》游戏秘籍

资源类 PEPPERONI PIZZA&#xff1a;获得 1000 食物。COINAGE&#xff1a;获得 1000 金。WOODSTOCK&#xff1a;获得 1000 木头。QUARRY&#xff1a;获得 1000 石头。 建筑与生产类 STEROIDS&#xff1a;快速建筑。 地图类 REVEAL MAP&#xff1a;显示所有地图。NO FOG&#xf…...

【sylar-webserver】10 HTTP模块

HTTP 解析 这里使用 nodejs/http-parser 提供的 HTTP 解析器。 HTTP 常量定义 HttpMethod HttpStatus /* Request Methods */ #define HTTP_METHOD_MAP(XX) \XX(0, DELETE, DELETE) \XX(1, GET, GET) \XX(2, HEAD, HEAD) …...

攻略生成模块

攻略生成模块 这个模块实现了一个旅行行程规划服务&#xff0c;主要流程如下&#xff1a; 核心思路是通过前端传来的城市和出游天数信息&#xff0c;先在本地数据库中查找是否已存有相应的旅游数据&#xff08;例如景点、美食等&#xff09;&#xff0c;如果没有就自动检索和…...

海康NVR录像回放SDK原始流转FLV视频流:基于Java的流媒体转码(无需安装第三方插件ffmpeg)

wlinker-video-monitor 代码地址&#xff1a;https://gitee.com/wlinker/wlinker-video-monitor 背景与需求 在安防监控、智能楼宇等场景中&#xff0c;海康威视设备作为行业主流硬件&#xff0c;常需要将录像回放功能集成到Web系统中。然而&#xff0c;海康设备的原始视频流…...

深入理解设计模式:工厂模式、单例模式

深入理解设计模式&#xff1a;工厂模式、单例模式 设计模式是软件开发中解决常见问题的可复用方案。本文将详细介绍两种种重要的创建型设计模式&#xff1a;工厂模式、单例模式&#xff0c;并提供Java实现示例。 一、工厂模式 工厂模式是一种创建对象的设计模式&#xff0c;…...

运维Linux之Ansible详解学习(更新中)

什么是Ansible Ansible 是一款新出现的自动化运维工具&#xff0c;基于 Python 开发。以下是对它的详细介绍&#xff1a; 功能特点&#xff1a;集合了众多运维工具的优点&#xff0c;能实现批量系统配置、批量程序部署、批量运行命令等功能。它是基于模块工作的&#xff0c;本…...

深入浅出IIC协议 - 从总线原理到FPGA实战开发 -- 第三篇:Verilog实现I2C Master核

第三篇&#xff1a;Verilog实现I2C Master核 副标题 &#xff1a;从零构建工业级I2C控制器——代码逐行解析与仿真实战 1. 架构设计 1.1 模块分层设计 三层架构 &#xff1a; 层级功能描述关键信号PHY层物理信号驱动与采样sda_oe, scl_oe控制层协议状态机与数据流控制state…...

网络世界的“变色龙“:动态IP如何重构你的数据旅程?

在深秋的下午调试代码时&#xff0c;我偶然发现服务器日志中出现异常登录记录——IP地址显示为某个境外数据中心。更有趣的是&#xff0c;当我切换到公司VPN后&#xff0c;这个"可疑IP"竟自动消失在了防火墙监控列表中。这个瞬间让我意识到&#xff1a;现代网络架构中…...

进阶-自定义类型(结构体、位段、枚举、联合)

自定义类型&#xff1a;结构体&#xff0c;枚举&#xff0c;联合 结构体 结构体类型的声明 结构的自引用 结构体变量的定义和初始化 结构体内存对齐 结构体传参 结构体实现位段(位段的填充&可移植性) 枚举 枚举类型的定义 枚举的优点 枚举的使用 联合 联合类型的定义 联…...

5G 网络全场景注册方式深度解析:从信令交互到报文分析

摘要 本文全面梳理 5G 网络包含的初始注册、移动性注册更新、紧急注册、周期性注册更新、服务请求触发注册、切换触发注册、基于策略的注册更新等多种注册方式。详细阐述每种注册方式的触发条件、信令流程、关键报文结构,结合对比分析与实际案例,助力读者深入理解 5G 网络接…...

ARM笔记-嵌入式系统基础

第一章 嵌入式系统基础 1.1嵌入式系统简介 1.1.1嵌入式系统定义 嵌入式系统定义&#xff1a; 嵌入式系统是以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软硬件可剪裁&#xff0c;对功能、可靠性、成本、体积、功耗等有严格要求的专用计算机系统 ------Any devic…...

一文讲透golang channel 的特点、原理及使用场景

在 Go 语言中&#xff0c;通道&#xff08;Channel&#xff09; 是实现并发编程的核心机制之一&#xff0c;基于 CSP&#xff08;Communicating Sequential Processes&#xff09; 模型设计。它不仅用于协程&#xff08;Goroutine&#xff09;之间的数据传递&#xff0c;还通过…...

upload-labs通关笔记-第19关文件上传之条件竞争

系列目录 upload-labs通关笔记-第1关 文件上传之前端绕过&#xff08;3种渗透方法&#xff09; upload-labs通关笔记-第2关 文件上传之MIME绕过-CSDN博客 upload-labs通关笔记-第3关 文件上传之黑名单绕过-CSDN博客 upload-labs通关笔记-第4关 文件上传之.htacess绕过-CSDN…...

第5章:任务间通信机制(IPC)全解析

💬 在多线程开发中,线程之间如何协作?如何让一个线程产生数据,另一个线程消费数据?本章聚焦 Zephyr 提供的多种任务间通信机制(IPC)及实战使用技巧。 📚 本章导读 你将学到: Zephyr 提供的常用 IPC 接口:FIFO、消息队列、邮箱、信号量 每种机制适用场景和用法对比…...

CAPL自动化-诊断Demo工程

文章目录 前言一、诊断控制面板二、诊断定义三、发送诊断通过类.方法的方式req.SetParameterdiagSetParameter四、SendRequestAndWaitForResponse前言 本文将介绍CANoe的诊断自动化测试,工程可以从CANoe的 Sample Configruration 界面打开,也可以参考下面的路径中打开(以实…...

SVN被锁定解决svn is already locked

今天遇到一个问题&#xff0c;svn 在提交代码的时候出现了svn is already locked&#xff0c;解决方案...

【深度学习】1. 感知器,MLP, 梯度下降,激活函数,反向传播,链式法则

一、感知机 对于分类问题&#xff0c;我们设定一个映射&#xff0c;将x通过函数f(x)映射到y 1. 感知机的基本结构 感知机&#xff08;Perceptron&#xff09;是最早期的神经网络模型&#xff0c;由 Rosenblatt 在 1958 年提出&#xff0c;是现代神经网络和深度学习模型的雏形…...

云原生安全:网络协议TCP详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 &#xff08;注&#xff1a;文末附可视化流程图与专有名词说明表&#xff09; 1. 基础概念 TCP&#xff08;Transmission Control Protocol&#xff09;是…...

使用CentOS部署本地DeekSeek

一、查看服务器的操作系统版本 cat /etc/centos-release二、下载并安装ollama 1、ollama下载地址&#xff1a; Releases ollama/ollama GitHubGet up and running with Llama 3.3, DeepSeek-R1, Phi-4, Gemma 3, Mistral Small 3.1 and other large language models. - Re…...

Spring Boot与Eventuate Tram整合:构建可靠的事件驱动型分布式事务

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、引言 在现代微服务架构中&#xff0c;分布式事务管理一直是复杂系统中的核心挑战之一。传统的两阶段提交&#xff08;2PC&#xff09;方案存在性能瓶颈&…...

Python:从脚本语言到工业级应用的传奇进化

一、Python的诞生:一场喜剧与编程的奇妙相遇 1989年的冬天,荷兰程序员Guido van Rossum在阿姆斯特丹的CWI研究所里,用一段独特的代码开启了编程语言的新纪元。这个被命名为"Python"的项目,灵感并非源自冷血的蟒蛇,而是源于Guido对英国喜剧团体Monty Python的痴…...

【排序算法】典型排序算法 Java实现

以下是典型的排序算法分类及对应的 Java 实现&#xff0c;包含时间复杂度、稳定性说明和核心代码示例&#xff1a; 一、比较类排序&#xff08;通过元素比较&#xff09; 1. 交换排序 ① 冒泡排序 时间复杂度&#xff1a;O(n)&#xff08;优化后最优O(n)&#xff09; 稳定性&…...

node.js如何实现双 Token + Cookie 存储 + 无感刷新机制

node.js如何实现双 Token Cookie 存储 无感刷新机制 为什么要实施双token机制&#xff1f; 优点描述安全性Access Token 短期有效&#xff0c;降低泄露风险&#xff1b;Refresh Token 权限受限&#xff0c;仅用于获取新 Token用户体验用户无需频繁重新登录&#xff0c;Toke…...

[DS]使用 Python 库中自带的数据集来实现上述 50 个数据分析和数据可视化程序的示例代码

使用 Python 库中自带的数据集来实现上述 50 个数据分析和数据可视化程序的示例代码 摘要&#xff1a;由于 sample_data.csv 是一个占位符文件&#xff0c;用于代表任意数据集&#xff0c;我将使用 Python 库中自带的数据集来实现上述 50 个数据分析和数据可视化程序的示例代码…...