Vue框架底层

news2025/1/11 9:08:19

一、前端框架的由来

1、服务端渲染

sequenceDiagram
浏览器->>+服务器: https://www.bilibili.com/
Note right of 服务器: 组装页面(服务端渲染)
服务器->>-浏览器: 完整页面

image.png

2、前后端分离


sequenceDiagram
浏览器->>服务器: https://www.bilibili.com/
服务器->>浏览器: 无内容的html
activate 浏览器
浏览器-->>服务器: ajax
服务器-->>浏览器: 各种业务数据
Note left of 浏览器: 运行js,创建元素,渲染页面
deactivate 浏览器

image.png

3、单页应用

sequenceDiagram
浏览器->>服务器: https://www.bilibili.com/
服务器->>浏览器: 无内容的html
activate 浏览器
Note left of 浏览器: 运行js,创建元素,渲染页面
浏览器-->>服务器: ajax
服务器-->>浏览器: 各种业务数据
Note left of 浏览器: 跳转页面
浏览器-->>服务器: ajax
服务器-->>浏览器: 各种业务数据
Note left of 浏览器: JS重新构建页面元素
deactivate 浏览器

image.png

4、vue

sequenceDiagram
浏览器->>服务器: https://www.bilibili.com/
服务器->>浏览器: 无内容的html
activate 浏览器
Note left of 浏览器: 运行包含vue的js,使用框架渲染页面
浏览器-->>服务器: ajax
服务器-->>浏览器: 各种业务数据
Note left of 浏览器: 使用vue-router跳转页面
deactivate 浏览器

image.png

二、vue的一些底层原理

1、注入

image.png

vue会将以下配置注入到vue实例:

  • data:和界面相关的数据
  • computed:通过已有数据计算得来的数据
  • methods:方法

模板中可以使用vue实例中的成员

2、虚拟DOM树

直接操作真实的DOM会引发严重的效率问题,vue使用虚拟DOM(vnode)的方式来描述要渲染的内容
vnode是一个普通的js对象,用于描述界面上应该有什么,比如:

 var vnode = {
            tag: "h1",
            children: [{
                tag: undefined,
                text: "Hello"
            }]
        }

上面的对象描述了:

有一个标签名为h1的节点,它有一个子节点,该子节点是一个文本,内容为【Hello】

vue模板并不是真实的DOM,它会编译为虚拟DOM

<div id="app">
  <h1>第一个vue应用:{{title}}</h1>
  <p>作者:{{author}}</p>
</div>

上面的模板会被编译为类似下面结构的虚拟DOM

var vnode = {
            tag: "div",
            children: [{
                tag: "h1",
                children: [{
                    text: "第一个vue应用:Hello World"
                }]
            }, {
                tag: "p",
                children: [{
                    text: "作者:siuser"
                }]
            }]
        }

虚拟DOM树会最终成为真实的DOM树
image.png

当数据变化后,将引发重新渲染,vue会比较新旧两棵vnode tree,找出差异,然后仅把差异部分应用到真实dom tree中

image.png

可见,在vue中,要得到最终的界面,必须要生成一个vnode tree

vue通过以下逻辑生成vnode tree:

image.png

注意:虚拟节点树必须是单根的

3、挂载

将生成的真实DOM树,放置到某个元素位置,称之为挂载

挂载的方式:

  1. 通过el:"css选择器"进行配置
  2. 通过vue实例.$mount(“css选择器”)进行配置

4、完整流程

image.png

三、组件开发

1、创建组件

组件是根据一个普通的配置对象创建的,所以要开发一个组件,只需要写一个配置对象即可

该配置对象和vue实例的配置是几乎一样

//组件配置对象
var myComp = {
  data(){
    return {
      // ...
    }
  },
  template: `....`
}

值得注意的是,组件配置对象和vue实例有以下几点差异:

  • 无el
  • data必须是一个函数,该函数返回的对象作为数据
  • 由于没有el配置,组件的虚拟DOM树必须定义在template或render中

2、注册组件

注册组件分为两种方式,一种是全局注册,一种是局部注册

2.1、全局注册

一旦全局注册了一个组件,整个应用中任何地方都可以使用该组件

image.png

全局注册的方式是:

// 参数1:组件名称,将来在模板中使用组件时,会使用该名称
// 参数2:组件配置对象
// 该代码运行后,即可在模板中使用组件
Vue.component('my-comp', myComp)

在模板中,可以使用组件了

<my-comp />
<!---->
<my-comp></my-comp>

但在一些工程化的大型项目中,很多组件都不需要全局使用
比如一个登录组件,只有在登录的相关页面中使用,如果全局注册,将导致构建工具无法优化打包
因此,除非组件特别通用,否则不建议使用全局注册

2.2、局部注册

局部注册就是哪里要用到组件,就在哪里注册

image.png

局部注册的方式是,在要使用组件的组件或实例中加入一个配置:

// 这是另一个要使用my-comp的组件
var otherComp = {
  components:{
    // 属性名为组件名称,模板中将使用该名称
    // 属性值为组件配置对象
    "my-comp": myComp
  },
  template: `
    <div>
      <!-- 该组件的其他内容 -->
      <my-comp></my-comp>
    </div>
  `;
}

3、应用组件

在模板中使用组件特别简单,把组件名当作HTML元素名使用即可
但要注意以下几点:

  1. 组件必须有结束

组件可以自结束,也可以用结束标记结束,但必须要有结束
下面的组件使用是错误的:

<my-comp>
  1. 组件的命名

无论你使用哪种方式注册组件,组件的命名需要遵循规范。

组件可以使用kebab-case 短横线命名法,也可以使用PascalCase 大驼峰命名法

下面两种命名均是可以的

var otherComp = {
  components:{
    "my-comp": myComp,  // 方式1
    MyComp: myComp //方式2
  }
}

实际上,使用小驼峰命名法 camelCase也是可以识别的,只不过不符合官方要求的规范

使用PascalCase方式命名还有一个额外的好处,即可以在模板中使用两种组件名

var otherComp = {
  components:{
    MyComp: myComp
  }
}

模板中:

<!-- 可用 -->
<my-comp />
<MyComp />

因此,在使用组件时,为了方便,往往使用以下代码:

var MyComp = {
  //组件配置
}

var OtherComp = {
  components:{
    MyComp // ES6速写属性
  }
}

四、组件树

一个组件创建好后,往往会在各种地方使用它。它可能多次出现在vue实例中,也可能出现在其他组件中

于是就形成了一个组件树

image.png

五、向组件传递数据(基础)

大部分组件要完成自身的功能,都需要一些额外的信息

比如一个头像组件,需要告诉它头像的地址,这就需要在组件时向组件传递数据

传递数据的方式有很多种,很常见的一种是使用组件属性component props

首先在组件中申明可以接收哪些属性:

var MyComp = {
  props:["p1", "p2", "p3"],
  // 和vue实例一样,使用组件时也会创建组件的实例
  // 而组件的属性会被提取到组件实例中,因此可以在模板中使用
  template: `
    <div>
      {{p1}}, {{p2}}, {{p3}}
    </div>
  `
}

在使用组件时,向其传递属性:

var OtherComp = {
  components: {
    MyComp
  },
  data(){
    return {
      a:1
    }
  },
  template: `
    <my-comp :p1="a" :p2="2" p3="3"/>
  `
}

注意:在组件中,属性是只读的,绝不可以更改,这叫做单向数据流
image.png

六、v-if和v-show

image.png

image.png

面试题:v-if和v-show有什么区别?

v-if能够控制是否生成vnode,也就间接控制了是否生成对应的dom。
当v-if为true时,会生成对应的vnode,并生成对应的dom元素;当其为false时,不会生成对应的vnode,自然不会生成任何的dom元素

v-show始终会生成vnode,也就间接导致了始终生成dom。
它只是控制dom的display属性,当v-show为true时,不做任何处理;当其为false时,生成的dom的display属性为none

使用v-if可以有效的减少树的节点和渲染量,但也会导致树的不稳定;
而使用v-show可以保持树的稳定,但不能减少树的节点和渲染量

因此,在实际开发中,显示状态变化频繁的情况下应该使用v-show,以保持树的稳定;
显示状态变化较少时应该使用v-if,以减少树的结点和渲染量

七、组件事件

image.png

  • 抛出事件:子组件在某个时候发生了一件事,但自身无法处理,于是通过事件的方式通知父组件处理
  • 事件参数:子组件抛出事件时,传递给父组件的数据
  • 注册事件:父组件申明,当子组件发生某件事的时候,自身将做出一些处理

八、插槽

在某些组件模板中,有一部分区域需要父组件来指定

<!-- message组件:一个弹窗消息 -->
<div class="message-container">
  <div class="content">
    <!-- 这里是消息内容,可以是一个文本,也可能是一段html,具体是什么不知道,需要父组件指定 -->
  </div>
  <button>确定</button>
  <button>关闭</button>
</div>

1、插槽的简单用法

此时,就需要使用插槽来定制组件的功能

<!-- message组件:一个弹窗消息 -->
<div class="message-container">
  <div class="content">
    <!-- slot是vue的内置组件 -->
    <slot></slot>
  </div>
  <button>确定</button>
  <button>关闭</button>
</div>

<!-- 父组件App -->
<Message>
	<div class="app-message">
    <p>App Message</p>
    <a href="">detail</a>
  </div>
</Message>

<!-- 最终的结果 -->
<div class="message-container">
  <div class="content">
    <div class="app-message">
      <p>App Message</p>
      <a href="">detail</a>
    </div>
  </div>
  <button>确定</button>
  <button>关闭</button>
</div>

image.png

2、具名插槽

如果某个组件中需要父元素传递多个区域的内容,也就意味着需要提供多个插槽
为了避免冲突,就需要给不同的插槽赋予不同的名字

<!-- Layout 组件 -->
<div class="layout-container">
  <header>
    <!-- 我们希望把页头放这里,提供插槽,名为header -->
    <slot name="header"></slot>
  </header>
  <main>
    <!-- 我们希望把主要内容放这里,提供插槽,名为default -->
    <slot></slot>
  </main>
  <footer>
    <!-- 我们希望把页脚放这里,提供插槽,名为footer -->
    <slot name="footer"></slot>
  </footer>
</div>

<!-- 父组件App -->
<BaseLayout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  <template v-slot:default>
    
  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</BaseLayout>

image.png

九、路由

vue-router官网:https://router.vuejs.org/zh/

image.png

1、路由插件

npm i vue-router

路由插件的使用

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter); // Vue.use(插件)  在Vue中安装插件

const router = new VueRouter({
  // 路由配置
})
new Vue({
  ...,
  router
})

2、基本使用

// 路由配置
const router = new VueRouter({
  routes: [ // 路由规则
    // 当匹配到路径 /foo 时,渲染 Foo 组件
    { path: '/foo', component: Foo },
    // 当匹配到路径 /bar 时,渲染 Bar 组件
  	{ path: '/bar', component: Bar }
  ]
})
<!-- App.vue -->
<div class="container">
  <div>
    <!-- 公共区域 -->
  </div>
  <div>
    <!-- 页面区域 -->
    <!-- vue-router 匹配到的组件会渲染到这里 -->
    <RouterView />
  </div>
</div>

3、路由模式

  1. 路由从哪里获取访问路径
  2. 路由如何改变访问路径

vue-router提供了三种路由模式:

  • hash:默认值。路由从浏览器地址栏中的hash部分获取路径,改变路径也是改变的hash部分。该模式兼容性最好
http://localhost:8081/#/blog  -->  /blog
http://localhost:8081/about#/blog  --> /blog
  • history:路由从浏览器地址栏的location.pathname中获取路径,改变路径使用的H5的history api。该模式可以让地址栏最友好,但是需要浏览器支持history api
http://localhost:8081/#/blog  -->  /
http://localhost:8081/about#/blog  --> /about
http://localhost:8081/blog  --> /blog
  • abstract:路由从内存中获取路径,改变路径也只是改动内存中的值。这种模式通常应用到非浏览器环境中
内存: /			-->   /
内存: /about	--> /about
内存: /blog	  --> /blog

4、导航

vue-router提供了全局的组件RouterLink,它的渲染结果是一个a元素

<RouterLink to="/blog">文章</RouterLink>
<!-- mode:hash 生成 -->
<a href="#/blog">文章</a>
<!-- mode:history 生成 -->
<!-- 为了避免刷新页面,vue-router实际上为它添加了点击事件,并阻止了默认行为,在事件内部使用hitory api更改路径 -->
<a href="/blog">文章</a>

image.png

image.png

激活状态

默认情况下,vue-router会用当前路径匹配导航路径

  • 如果当前路径是以导航路径开头,则算作匹配,会为导航的a元素添加类名router-link-active
  • 如果当前路径完全等于导航路径,则算作精确匹配,会为导航的a元素添加类名router-link-exact-active

例如,当前访问的路径是/blog,则:

导航路径类名
/router-link-active
/blogrouter-link-active   router-link-exact-active
/about
/message

可以为组件RouterLink添加bool属性exact,将匹配规则改为:必须要精确匹配才能添加匹配类名router-link-active

例如,当前访问的路径是/blog,则:

导航路径exact类名
/true
/blogfalserouter-link-active   router-link-exact-active
/abouttrue
/messagetrue

例如,当前访问的路径是/blog/detail/123,则:

导航路径exact类名
/true
/blogfalserouter-link-active
/abouttrue
/messagetrue

另外,可以通过active-class属性更改匹配的类名,通过exact-active-class更改精确匹配的类名

5、命名路由

使用命名路由可以解除系统与路径之间的耦合

// 路由配置
const router = new VueRouter({
  routes: [ // 路由规则
    // 当匹配到路径 /foo 时,渲染 Foo 组件
    { name:"foo", path: '/foo', component: Foo },
    // 当匹配到路径 /bar 时,渲染 Bar 组件
  	{ name:"bar", path: '/bar', component: Bar }
  ]
})
<!-- 向to属性传递路由信息对象 RouterLink会根据你传递的信息以及路由配置生成对应的路径 -->
<RouterLink :to="{ name:'foo' }">go to foo</RouterLink>

十、vue的一些边角知识

1、css module

当在main.js使用纯dom操作,需要引用css module

需要将样式文件命名为xxx.module.ooo
xxx为文件名

ooo为样式文件后缀名,可以是css、less

// 测试一下纯DOM操作
import styles from "./styles/message.module.less";
console.log(styles);
const div = document.createElement("div");
div.className = styles.message;
div.innerText = "asdfasdf";
document.body.appendChild(div);

2、得到组件渲染的Dom

  /**
    获取某个组件渲染的Dom根元素
  */
function getComponentRootDom(comp, props){
  const vm = new Vue({
    render: h => h(comp, {props})
  })
  vm.$mount();
  return vm.$el;
}

3、扩展vue实例

image.png

prototype的知识点延申

4、ref

<template>
	<div>
    <p ref="para">some paragraph</p>
    <ChildComp ref="comp" />
    <button @click="handleClick">查看所有引用</button>
  </div>
</template>

<script>
  import ChildComp from "./ChildComp"
	export default {
    components:{
      ChildComp
    },
    methods:{
      handleClick(){
        // 获取持有的所有引用
        console.log(this.$refs);
        /*
        {
        	para: p元素(原生DOM),
        	comp: ChildComp的组件实例
        }
        */
      }
    }
  }
</script>

通过ref可以直接操作dom元素,甚至可能直接改动子组件,这些都不符合vue的设计理念。
除非迫不得已,否则不要使用ref

十一、远程获取数据的意义

image.png

1、开发环境有跨域问题

sequenceDiagram
浏览器->>前端开发服务器: http://localhost:8080/
前端开发服务器->>浏览器: 页面
浏览器->>后端测试服务器: ajax 跨域:http://test-data:3000/api/news
后端测试服务器->>浏览器: JSON数据
rect rgb(224,74,74)
Note right of 浏览器: 浏览器阻止数据移交
end

image.png

2、生产环境没有跨域问题

sequenceDiagram
浏览器->>服务器: http://www.my-site.com/
服务器->>浏览器: 页面
浏览器->>服务器: ajax:http://www.my-site.com/api/news
服务器->>浏览器: JSON数据

image.png

sequenceDiagram
浏览器->>静态资源服务器: http://www.my-site.com/
静态资源服务器->>浏览器: 页面
浏览器->>数据服务器: ajax 跨域:http://api.my-site.com/api/news
数据服务器->>浏览器: [允许www.my-site.com]JSON数据

image.png

3、解决开发环境的跨域问题

sequenceDiagram
浏览器->>前端开发服务器: http://localhost:8080/
前端开发服务器->>浏览器: 页面
浏览器->>前端开发服务器: ajax:http://localhost:8080/api/news
前端开发服务器->>后端测试服务器: 代理请求:http://test-data:3000/api/news
后端测试服务器->>前端开发服务器: JSON数据
前端开发服务器->>浏览器: JSON数据

image.png

4、为什么要用mock数据

sequenceDiagram
浏览器->>前端开发服务器: http://localhost:8080/
前端开发服务器->>浏览器: 页面
浏览器->>前端开发服务器: ajax:http://localhost:8080/api/news
前端开发服务器->>后端测试服务器: 代理请求:http://test-data:3000/api/news
后端测试服务器->>前端开发服务器: 404 (后端正在开发中)
前端开发服务器->>浏览器: 404

image.png

sequenceDiagram
participant 浏览器
participant MockJS
participant 前端开发服务器
activate MockJS
Note left of MockJS: 定义ajax拦截规则
deactivate MockJS
浏览器->>前端开发服务器: http://localhost:8080/
前端开发服务器->>浏览器: 页面
浏览器->>MockJS: ajax:http://localhost:8080/api/news
MockJS->>浏览器: 模拟的JSON数据

image.png

十二、组件生命周期

image.png
image.png

1、常见应用

1.1、加载远程数据

export default {
  data(){
    return {
      news: []
    }
  },
  async created(){
    this.news = await getNews();
  }
}

1.2、直接操作DOM

export default {
  data(){
    return {
      containerWidth:0,
    	containerHeight:0
    }
  },
  mounted(){
    this.containerWidth = this.$refs.container.clientWidth;
    this.containerHeight = this.$refs.container.containerHeight;
  }
}

1.3、启动和清除计时器

export default {
  data(){
    return {
      timer: null
    }
  },
  created(){
    this.timer = setInterval(()=>{
     ... 
    }, 1000)
  },
  destroyed(){
    clearInterval(this.timer);               
  }
}

十三、自定义指令

1、全局定义

// 指令名称为:mydirec1
Vue.directive('mydirec1', {
  // 指令配置
})

// 指令名称为:mydirec2
Vue.directive('mydirec2', {
  // 指令配置
})

之后,所有的组件均可以使用mydirec1mydirec2指令

<template>
  <!-- 某个组件代码 -->
  <div>
    <MyComp v-mydirec1="js表达式" />
    <div v-mydirec2="js表达式">
      ...
    </div>
    <img v-mydirec1="js表达式" />
  </div>
</template>

2、局部定义

局部定义是指在某个组件中定义指令,和局部注册组件类似。

定义的指令仅在该组件中有效。

<template>
  <!-- 某个组件代码 -->
  <div>
    <MyComp v-mydirec1="js表达式" />
    <div v-mydirec2="js表达式">
      ...
    </div>
    <img v-mydirec1="js表达式" />
  </div>
</template>

<script>
export default {
  // 定义指令
  directives: {
    // 指令名称:mydirec1
    mydirec1: {
      // 指令配置
    },
    // 指令名称:mydirec2
    mydirec2: {
      // 指令配置
    }
  }
}
</script>

和局部注册组件一样,为了让指令更加通用,通常我们会把指令的配置提取到其他模块。

<template>
  <!-- 某个组件代码 -->
  <div>
    <MyComp v-mydirec1="js表达式" />
    <div v-mydirec2="js表达式">
      ...
    </div>
    <img v-mydirec1="js表达式" />
  </div>
</template>

<script>
  // 导入当前组件需要用到的指令配置对象
  import mydirec1 from "@/directives/mydirec1";
  import mydirec2 from "@/directives/mydirec2";
	export default {
    // 定义指令
    directives: {
      mydirec1,
      mydirec2
    }
  }
</script>

指令配置对象

没有配置的指令,就像没有配置的组件一样,毫无意义

vue支持在指令中配置一些钩子函数,在适当的时机,vue会调用这些钩子函数并传入适当的参数,以便开发者完成自己想做的事情。

常用的钩子函数:

// 指令配置对象
{
  bind(){
    // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  },
  inserted(){
    // 被绑定元素插入父节点时调用。
  },
  update(){
    // 所在组件的 VNode 更新时调用
  }
}

查看更多的钩子函数

每个钩子函数在调用时,vue都会向其传递一些参数,其中最重要的是前两个参数

// 指令配置对象
{
  bind(el, binding){
    // el 是被绑定元素对应的真实DOM
    // binding 是一个对象,描述了指令中提供的信息
  }
}

bingding 对象

查看更多bingding对象的属性

配置简化

比较多的时候,在配置自定义指令时,我们都会配置两个钩子函数

{
  bind(el, bingding){
    
  },
  update(el, bingding){
    
  }
}

这样,在元素绑定和更新时,都能运行到钩子函数

如果这两个钩子函数实现的功能相同,可以直接把指令配置简化为一个单独的函数:

function(el, bingding){
  // 该函数会被同时设置到bind和update中
}

利用上述知识,可满足大部分自定义指令的需求

更多的自定义指令用法见官网

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

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

相关文章

Linux文件系统和日志分析

一、inode表结构 1. inode表 inode号在同一个设备上是唯一的。 inode号是有限资源&#xff0c;它的大小和磁盘大小有关。 访问文件的基本流程 根据文件夹的文件名和inode号的关系找到对应的inode表&#xff0c;再根据inode表&#xff08;属主 属组&#xff09;当中的指针找到磁…

毛概笔记。

一、 毛泽东思想是马中化的第一果&#xff0c;是关于搞革命&#xff0c;搞改造&#xff0c;搞建设的理论。 二、新民主主义革命 新民主主义革命的三大法宝&#xff1a;1.统一战线 2. 武装斗争 3.党的建设 政治纲领 经济纲领 文化纲领 乱世造英雄 三、社会主义改造理论&#xff…

多类指针式仪表自动读数系统的LabVIEW开发应用案例

多类指针式仪表自动读数系统的LabVIEW开发应用案例 工业环境中&#xff0c;多类指针式仪表的自动读数一直是一个具有挑战性的问题。本案例旨在展示如何使用LabVIEW开发一个高度智能化的多类指针式仪表自动读数系统&#xff0c;以应对复杂的工业环境。通过结合图像处理技术和深…

DSP2335的时钟PLL配置

PLL模块框图 xclkin是直接进来的外部时钟&#xff1b; 而下面的是振荡器&#xff08;晶振出来&#xff09;的时钟 PLLSTS 锁相环状态寄存器 PLLCR 锁相环控制寄存器 PLLSTS【oscoff】 决定着外部时钟的输入 PLLSTS【plloff】 锁相器关闭位 0使能PLL 锁相环控制寄存器…

程序猿的时间管理和生产力

文章目录 为什么时间管理很重要&#xff1f;如何管理时间&#xff1f;心理维度生理维度技术尺寸 时间管理技巧每周计划基于目标的规划番茄钟为什么是25分钟&#xff1f;番茄钟为什么有效&#xff1f;艾森豪威尔矩阵这一切都是从开发者的角度来看的 也许我从开始学习或从事软件开…

C++面向对象核心-权限-多态

1、权限 1.1 权限修饰符 三种权限&#xff0c;一共对应九种场景。要做到心中有表&#xff0c;遇到任何一种场景都能直接反映出是否能访问。 类内 派生类中 全局 private √ protected √ √ public √ √ √ #include <iostream> using namespace std;…

第二百五十三回

文章目录 概念介绍使用方法示例代码 概念介绍 进度条是常用的组件之一&#xff0c;它主要用来显示某种动作的完成进度。Flutter提供了多种进度条组件&#xff0c;常用的是水平进度条&#xff1a;LinearProgressIndicator&#xff1b;圆形进度条 :CircularProgressIndicator和R…

4.4 TILING FOR REDUCED MEMORY TRAFFIC

我们在CUDA中使用设备内存方面有一个内在的权衡&#xff1a;全局内存大但速度慢&#xff0c;而共享内存小但速度快。一个常见的策略是将数据划分为称为tile的子集&#xff0c;以便每个tile都适合共享内存。tile一词”借鉴了一个类比&#xff0c;即大墙&#xff08;即全局内存数…

data-factory java 开源根据对象定义自动生成测试对象数据

创作目的 我们平时在写测试用例的时候&#xff0c;免不了要写一大堆 set 方法为对象设置属性。 有时候为了补全测试用例&#xff0c;这件事就会变得非常枯燥。 于是就在想&#xff0c;能不能写一个可以自动生成测试对象的工具呢&#xff1f; 于是就有了这一个没啥用的测试框…

网络调试 UDP1,开发板用动态地址-入门6

https://www.bilibili.com/video/BV1zx411d7eC?p11&vd_source109fb20ee1f39e5212cd7a443a0286c5 1, 开发板连接路由器 1.1&#xff0c;烧录无OS UDP例程 1.2&#xff0c;Mini USB连接电脑 1.3&#xff0c;开发板LAN接口连接路由器 2. Ping开发板与电脑之间通信* 2.1 根据…

人工智能AI网站大全—实现自动聊天、绘画、创作论文、生成视频等

人工智能正在逐步改变大家的生活和工作方式&#xff0c;本文总结当前人工智能实用网站&#xff0c;方便大家更快地把AI应用到工作和生活中&#xff0c;提高效率。主要包括自动聊天、自动创作论文、自动绘画、、自动创作视频等模块。 文章目录 Part1 10w.aiPart2 liblib.AIPart3…

洗地机什么牌子好?目前口碑最好的洗地机

如今&#xff0c;人们的生活中&#xff0c;洗地机已经成为了越来越受欢迎的清洁工具&#xff0c;洗地机能迅速而有效地清理地板、地毯以及其他硬表面&#xff0c;为用户提供更加方便快捷的洗地机体验。那么&#xff0c;洗地机什么牌子好?我们一起来看看目前口碑最好的洗地机有…

人工智能任务2-读懂Transformer模型的十个灵魂拷问问题,深度理解Transformer模型架构

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能任务2-读懂Transformer模型的十个灵魂拷问问题&#xff0c;深度理解Transformer模型架构。Transformer模型是一种基于自注意力机制的神经网络架构&#xff0c;被广泛用于自然语言处理任务中&#xff0c;如机…

C语言注意点(4)

1、void *a是什么意思 答&#xff1a;泛型指针&#xff0c;但不规定其类型(就是地址确定&#xff0c;但数据长度不确定)在动态分配内存时&#xff0c;malloc的返回值就是该类型&#xff0c;方便用户进行强制转换。 2、VS怎么一键规范格式 for(i0;i<10;i)enter后&#xff0c;…

selenium3自动化测试(这一篇就够了)——自学篇

本人整理收藏了20年多家公司面试知识点整理 &#xff0c;以及学习路线和视频教程免费分享给大家&#xff0c;我认为对面试来说是非常有用的&#xff0c;想要资料的话请点1150305204暗号CSDN。或者点击文末名片进入&#xff0c;免费领取 &#xff08;一&#xff09;安装seleniu…

120°AGV|RGV小车激光障碍物传感器|避障雷达DE系列安装与连线方法

120AGV|RGV小车激光障碍物传感器|避障雷达DE系列包含DE-4211、DE-4611、DE-4311、DE-4511等型号&#xff0c;根据激光飞行时间&#xff08;TOF&#xff09;测量原理运行的&#xff0c;利用激光光束对周围进行 120 半径 4m&#xff08;90%反射率&#xff09;扫描&#xff0c;获得…

一文初步了解slam技术

本文初步介绍slam技术&#xff0c;主要是slam技术的概述&#xff0c;涉及技术原理、应用场景、分类、以及各自优缺点&#xff0c;和slam技术的未来展望。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;slam精进之…

基于Java SSM框架实现时间管理系统项目【项目源码+论文说明】

基于java的SSM框架实现时间管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于时间管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了时间管理…

小程序学习基础(页面加载)

打开首页&#xff0c;然后点击第一个按钮进去心得页面 进入心得页面以后 第一个模块是轮播图用的是swiper组件&#xff0c;然后就是四个按钮绑定点击事件&#xff0c;最后就是下拉刷新&#xff0c;下拉滚动&#xff0c;上拉加载。代码顺序wxml,js,wcss,json。 <!--pages/o…

04、Kafka ------ 各个功能的作用解释(Cluster、集群、Broker、位移主题、复制因子、领导者副本、主题)

目录 启动命令&#xff1a;CMAK的用法★ 在CMAK中添加 Cluster★ 在CMAK中查看指定集群★ 在CMAK中查看 Broker★ 位移主题★ 复制因子★ 领导者副本和追随者副本★ 查看主题 启动命令&#xff1a; 1、启动 zookeeper 服务器端 小黑窗输入命令&#xff1a; zkServer 2、启动 …