一篇文章认识Vue3

Vue 3 介绍

  1. Vue3 于 2022 年 2 月 7 日星期一成为新的默认版本!
  2. Vue3 性能更高,体积更小
  3. Vue3 在经过一年的迭代后,越来越好用。

官方文档:

  • vue3官方文档: vuejs.org/ [1]
  • vue3中文文档: v3.cn.vuejs.org/ [2]
  • vue3预发布版文档: staging-cn.vuejs.org/ [3]

目前已支持 vue3 的UI组件库:

  • element-plus

    element-plus.gitee.io/#/zh-CN[4] (PC组件库)

    Element Plus,一套为开发者、设计师和产品经理准备的基于 Vue 3.0 的桌面端组件库。

  • vant

    vant-contrib.gitee.io/vant/v3/#/z…[5]

    轻量、可靠的移动端 Vue 组件库。

    Vant 是有赞前端团队开源的移动端组件库,于 2016 年开源,已持续维护 4 年时间。

    目前 Vant 已完成了对 Vue 3.0 的适配工作,并发布了 Vant 3.0 版本

  • ant-design-vue (PC组件库)

    antdv.com/docs/vue/in…[6]

    ant-design-vue 是 Ant Design 的 Vue 实现,组件的风格与 Ant Design 保持同步。

Vue3 动机 和 新特性

Vue3 设计理念 vue3js.cn/vue-composi…[7]

动机与目的:

  1. 更好的 逻辑复用 与 代码组织 (composition组合式api)

    options 选项API(旧) => composition 组合API(新), 效果: 代码组织更方便了, 逻辑复用更方便了 非常利于维护!!

  2. 更好的类型推导 (typescript支持)

    vue3 源码用 ts 重写了, vue3 对 ts 的支持更友好了 (ts 可以让代码更加稳定, 类型检测! )

vue3 新特性:

  1. 数据响应式原理重新实现 (ES6 proxy 替代了 ES5 的 Object.defineProperty)

    解决了: 例如数组的更新检测等bug, 大大优化了响应式监听的性能

    (原来检测对象属性的变化, 需要一个个对属性递归监听) proxy 可以直接对整个对象劫持

  2. 虚拟DOM - 新算法 (更快 更小)

  3. 提供了composition api, 可以更好的逻辑复用

  4. 模板可以有多个根元素

  5. 源码用 typescript 重写, 有更好的类型推导 (类型检测更为严格, 更稳定)

    ...

小结: vue3 性能更高, 体积更小, 更利于复用, 代码维护更方便

vite介绍

Vite 官方中文文档:vitejs.cn/[8]

Vite(法语意为 "快速的",发音 /vit/,发音同 "veet")是一种新型前端构建工具

优势

  • 💡 极速的服务启动,使用原生 ESM 文件,无需打包
  • ⚡️ 轻量快速的热重载,始终极快的模块热重载(HMR)
  • 🛠️丰富的功能,对 TypeScript、JSX、CSS 等支持开箱即用
  • 📦等等

Vite的优势?

传统方式

  • 基于打包器的方式启动,必须优先抓取并构建你的整个应用,然后才能提供服务。
  • 更新速度会随着应用体积增长而直线下降。
image-20220212224001104.png
image-20220212224001104.png

vite 方式

  • Vite 以 原生 ESM [9] 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作。
  • Vite 只需要在浏览器请求源码时进行转换并按需提供源码。
  • 根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
image-20220212224054798.png
image-20220212224054798.png

Vite 的基本使用

目标:能够使用vite创建一个vue3的项目

(1)使用vite创建项目

npm create vite
# or
yarn create vite

(2)输入项目名字,默认为vite-project

image-20220212224535365.png
image-20220212224535365.png

(3)选择创建的项目类型,选择vue即可

image-20220212224709912.png
image-20220212224709912.png

(4)选择创建的vue项目类型, 不选ts

image-20220212224735340.png
image-20220212224735340.png

(5)启动项目

image-20220212224801574.png
image-20220212224801574.png

vite快捷使用

如果想要快速创建一个vue3项目,可以使用如下命令

  • 创建普通vue项目
yarn create vite vite-demo --template vue
  • 创建基于ts模板的项目
yarn create vite vite-demo-ts --template vue-ts

Vue3.0项目介绍

  • 删除src下所有的文件和代码
  • 创建App.vue
<template>
  <div>我是App组件</div>
</template>

  • 创建main.js文件
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

vscode插件说明

  • vue2中需要安装插件 vetur,可以实现组件高亮。但是vue3的一些语法在vetur中报错。
  • vue3中需要安装插件 volar,提供了更加强大的功能。
  • 所以,使用功能vue3,需要禁用或卸载 vetur插件,安装 volar插件。
image-20220212230447148.png
image-20220212230447148.png

组合式API

composition API vs options API

  1. vue2 采用的就是 options API

    (1) 优点:易于学习和使用, 每个代码有着明确的位置 (例如: 数据放 data 中, 方法放 methods中)

    (2) 缺点: 相似的逻辑, 不容易复用, 在大项目中尤为明显

    (3) 虽然 optionsAPI 可以通过mixins 提取相同的逻辑, 但是也并不是特别好维护

  2. vue3 新增的就是 composition API

    (1) compositionAPI 是基于 逻辑功能 组织代码的, 一个功能 api 相关放到一起

    (2) 即使项目大了, 功能多了, 也能快速定位功能相关的 api

    (3) 大大的提升了 代码可读性可维护性

  3. vue3 推荐使用 composition API, 也保留了options API

    即就算不用composition API, 用 vue2 的写法也完全兼容!!

setup 函数

composition api 的使用, 需要配置一个 setup 函数

  1. 从生命周期角度来看, setup 会在 beforeCreate 钩子函数之前执行
  2. setup 中不能使用 this, this 指向 undefined
  3. 在模版中需要使用的数据和函数,需要在 setup 返回。
  4. setup 函数是一个新的组件选项, 作为组件中 compositionAPI 的起点
<template>
  <div class="container">
    <h1 @click="say()">{{msg}}</h1>
  </div>

</template>

<script>
export default {
  setup () {
    console.log('setup执行了')
    console.log(this)
    /
/ 定义数据和函数
    const msg = 'hi vue3'
    const say = () => {
      console.log(msg)
    }

    return { msg , say}
  },
  beforeCreate() {
    console.log('beforeCreate执行了')
    console.log(this)
  }
}
</
script>

reactive 函数

前置说明:

  1. setup 需要有返回值, 只有返回的值才能在模板中使用
  2. 默认普通的数据, 不是响应式的

作用: 传入一个复杂数据类型,将复杂类型数据, 转换成响应式数据 (返回该对象的响应式代理)

<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <button @click="obj.name = 'ls'">改值</button>
</template>

<script>
import { reactive } from 'vue'

export default {
  setup () {
    /
/ 1. setup 需要返回值, 返回的值才能在模板中使用
    /
/ 2. 默认的普通的值不是响应式的, 需要用 reactive 函数
    const obj = reactive({
      name: 'zs',
      age: 18
    })

    return { obj }
  }
}
</
script>

总结: 通常是用来定义响应式 对象数据

ref 函数

reactive 处理的数据, 必须是复杂类型, 如果是简单类型无法处理成响应式, 所以有 ref 函数!

作用: 对传入的数据(一般简单数据类型),包裹一层对象, 转换成响应式。

  1. ref 函数接收一个的值, 返回一个ref 响应式对象, 有唯一的属性 value
  2. 在 setup 函数中, 通过 ref 对象的 .value 属性, 可以访问到值
  3. 在模板中, ref 属性会 自动解套, 不需要额外的 .value
  4. ref函数也支持传入复杂类型,传入复杂类型,也会做响应式处理
<template>
  <div>{{ money }}</div>
  <button @click="money++">改值</button>
</template>

<script>
import { reactive, ref } from 'vue'
export default {
  setup() {
    let money = ref(100)
    money.value++
    return {
      money
    }
  }
}
</
script>

ref 和 reactive 的最佳使用方式:

  • 明确的对象,明确的属性,用 reactive,其他用 ref
  • 从vue3.2之后,更推荐使用 ref

script setup 语法(★)

script setup 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。相比于普通的 script 语法更加简洁

要使用这个语法,需要将 setup attribute 添加到 <script> 代码块上:

<script setup>
console.log('hello script setup')
</script>

顶层的绑定会自动暴露给模板,所以定义的变量,函数和import导入的内容都可以直接在模板中直接使用

<template>
  <div>
    <h3>根组件</h3>
    <div>点击次数:{{ count }}</div>
    <button @click="add">点击修改</button>
  </div>

</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)
const add = () => {
  count.value++
}
</
script>

计算属性 computed 函数

computed 函数调用时, 要接收一个处理函数, 处理函数中, 需要返回计算属性的值

<template>
  <div>我今年的年纪 <input type="text" v-model="age" /></div>
  <div>我明年的年龄 {{ nextAge }}</div>
  <div>我后年的年龄 <input type="text" v-model="nextAge2" /></div>
</template>

<script setup>
import { computed, ref } from 'vue'
const age = ref(10)
/
/ 不带set的计算属性
const nextAge = computed(() => {
  return +age.value + 1
})

/
/ 带set的计算属性
const nextAge2 = computed({
  get() {
    return +age.value + 2
  },
  set(value) {
    age.value = value - 2
  },
})
</
script>

侦听器watch函数

watch监视, 接收三个参数
1. 参数1: 监视的数据源
2. 参数2: 回调函数
3. 参数3: 额外的配置
// 监听单个ref
const money = ref(100)
watch(money, (value, oldValue) => {
  console.log(value)
})

// 监听多个ref
const money = ref(100)
const count = ref(0)
watch([money, count], (value) => {
  console.log(value)
})

// 监听ref复杂数据
const user = ref({
  name'zs',
  age18,
})
watch(
  user,
  (value) => {
    console.log('user变化了', value)
  },
  {
    // 深度监听,,,当ref的值是一个复杂数据类型,需要深度监听
    deeptrue,
    // 立即执行
    immediatetrue
  }
)

// 监听对象的某个属性的变化
const user = ref({
  name'zs',
  age18,
})
watch(
  () => user.value.name,
  (value) => {
    console.log(value)
  }
)

钩子函数的使用

生命周期函数[10] vue3 中的生命周期函数, 需要在 setup 中调用

import { onMounted, onUpdated, onUnmounted } from 'vue'

const MyComponent = {
  setup() {
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
  }
}
image-20220213225003030.png
image-20220213225003030.png

组件通讯-父传子

目标:能够实现组件通讯中的父传子组件通讯

步骤:

  1. 父组件提供数据
  2. 父组件将数据传递给子组件
  3. 子组件通过 defineProps 进行接收
  4. 子组件渲染父组件传递的数据

核心代码:

父组件

<script setup>
import { ref } from 'vue'
// 在setup语法中,组件导入之后就能够直接使用,不需要使用components进行局部注册
import Son from './components/Son.vue'

const money = ref(100)
const car = ref('玛莎拉蒂')
</script>

<template>
  <div>
    <h1>我是父组件</
h1>
    <div>金钱:{{ money }}</div>
    <div>车辆:{{ car }}</div>
    <hr />
    <Son :money="money" :car="car"></Son>
  </div>
</
template>


子组件

<script setup>
import { computed } from 'vue'

// defineProps: 接收父组件传递的数据
const props = defineProps({
  moneyNumber,
  carString,
})

const myMoney = computed(() => {
  return props.money + 100
})
</script>

<template>
  <div>
    <h3>我是子组件</
h3>
    <div>{{ money }} --- {{ car }}</div>
  </div>
</
template>

注意:如果使用defineProps接收数据,这个数据只能在模板中渲染,如果想要在script中也操作props属性,应该接收返回值。

组件通讯-子传父

目标:能够实现组件通讯中的子传父

步骤:

  1. 子组件通过 defineEmits 获取 emit 对象(setup中没有this)
  2. 子组件通过emit触发事件,并且传递数据
  3. 父组件提供方法
  4. 父组件通过自定义事件的方式给子组件注册事件

核心代码

子组件

<script setup>
defineProps({
  money: Number,
  car: String,
})

const emit = defineEmits(['changeMoney'])

const change = () => {
  emit('changeMoney', 10)
}
</script>

父组件

<script setup>
import { ref } from 'vue'
// 在setup语法中,组件导入之后就能够直接使用,不需要使用components进行局部注册
import Son from './components/Son.vue'

const money = ref(100)
const car = ref('玛莎拉蒂')
const changeMoney = (num) => {
  money.value = money.value - num
}
</script>


<Son :money="money" :car="car" @changeMoney="changeMoney"></Son>

依赖注入 - provide 和 inject

依赖注入, 可以非常方便的实现 跨层级的 组件通信

image-20220213110153307.png
image-20220213110153307.png

父组件利用 provide 提供数据

<script setup>
import { provide, ref } from 'vue'
import Son from './components/Son.vue'
const money = ref(100)
provide('money', money)
</script>

<template>
  <div>
    <h1>我是父组件</
h1>
    <div>金钱:{{ money }}</div>
    <hr />
    <Son></Son>
  </div>
</
template>

子组件 (子孙后代, 都可以拿到这个数据)

<script setup>
import { inject } from 'vue'

const money = inject('money')
</script>

<template>
  <div>
    <h3>我是子组件--{{ money }}</
h3>
    <button>修改数据</button>
  </div>
</
template>

如果希望子传父, 可以 provide 传递一个方法

父组件

<script setup>
import { provide, ref } from 'vue'
import Son from './components/Son.vue'
const money = ref(100)
const changeMoney = (num) => {
  money.value = money.value - num
}
provide('money', money)
provide('changeMoney', changeMoney)
</script>

子组件

<script setup>
import { inject } from 'vue'

const money = inject('money')
const changeMoney = inject('changeMoney')
</script>

模板中 ref 的使用

联想之前的 ref 和 $refs, 获取模板的元素(dom元素,组件)

1 创建 ref => const hRef = ref(null)

2 模板中建立关联 => <h1 ref="hRef">钩子函数-----123</h1>

3 使用 => hRef.value

<script setup>
import { ref } from 'vue'

const hRef = ref(null)  
const clickFn = () => {
  hRef.value.innerText = '我不是标题'
}
</script>

<template>
  <div>
    <h1 ref="hRef">我是标题</
h1>
    <button @click="clickFn">操作DOM</button>
  </div>
</
template>

ref操作组件

<script setup>
import { ref } from 'vue'
import Form from './components/Form.vue'

// 1. 提供一个ref
const formRef = ref(null)

const fn = () => {
  console.log(formRef.value.count)
  formRef.value.sayHi()
}
</script>

<template>

  <Form ref="formRef"></
Form>
</template>

需要配合defineExpose

<script setup>
import { ref } from 'vue'

const count = ref(0)
const sayHi = () => {
  console.log('表单校验方法')
}
// 暴露属性给外部组件使用
defineExpose({
  sayHi,
})
</script>

<template>
  <h3>我是Form组件</
h3>
</template>

vue3 中废弃了过滤器

vue3.0 中不能使用过滤器,直接使用函数进行替代

<template>
  <h1>ref的使用</h1>
  <h3>我是一个h3的内容 {{ formatTime(now) }}</h3>
  <h3>{{ formatTime(other) }}</h3>
  <hr />
</template>

<script>
import moment from 'moment'
export default {
  setup() {
    /
/ 过滤器
    const now = new Date()
    const other = new Date('2020-11-12 12:00:00')
    const formatTime = (value) => {
      return moment(value).format('YYYY-MM-DD')
    }
    
    return {
      now,
      formatTime,
      other,
    }
  },
}
</
script>

补充-toRefs 函数

使用场景: 如果对一个响应数据, 进行解构 或者 展开, 会丢失他的响应式特性!

原因: vue3 底层是对 对象 进行监听劫持

作用: 对一个响应式对象的所有内部属性, 都做响应式处理

  1. reactive/ref的响应式功能是赋值给对象的, 如果给对象解构或者展开, 会让数据丢失响应式的能力
  2. 使用 toRefs 可以保证该对象展开的每个属性都是响应式的
<template>
  <div>{{ money }}</div>
  <div>{{ car }}</div>
  <div>{{ name }}</div>
  <button @click="money++">改值</button>
</template>

<script setup>
import { reactive, ref, toRefs } from 'vue'
const user = ref({
  name: 'zs',
  age: 18,
})
const { name, age } = toRefs(user.value)
</
script>

vue-router4

vue升级vue3之后,配套的vue-router也升级为vue-router@4.x[11]版本

vue-router4的语法和3的版本语法基本一致,但是有一些细微的修改。

vue-router官网:router.vuejs.org/[12]

vue@2 + vue-router@3 + vuex@3   options api

vue@3 + vue-router@4 + vuex@4    composition api

基本使用

(0)安装vue-router

yarn add vue-router
or
npm install vue-router

(1)创建组件Home.vue和Login.vue

(2)创建文件router/index.js

import {
  createRouter,
  createWebHashHistory,
  createWebHistory,
from 'vue-router'

// 1. 创建路由
const router = createRouter({
  // 创建history模式的路由
  // history: createWebHistory(),
  // 创建hash模式的路由
  history: createWebHashHistory(),
  // 配置路由规则
  routes: [
    { path'/home'component() => import('../pages/Home.vue') },
    { path'/login'component() => import('../pages/Login.vue') },
  ],
})

export default router

(3)在main.js中引入

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

(4)App.vue中使用

<template>
  <ul>
    <li>
      <router-link to="/home">首页</router-link>
    </li>
    <li>
      <router-link to="/login">登陆</router-link>
    </li>
  </ul>

  <!-- 路由出口 -->
  <router-view></router-view>
</template>


组件中使用route与router

由于组件中无法访问this,因为无法访问this.route与this.route与this.route与this.router

(1)通过useRoute()可以获取route信息

<script>
import { useRoute } from 'vue-router'

export default {
  setup() {
    const route = useRoute()
    console.log(route.path)
    console.log(route.fullPath)
  },
}
</script>

(2)通过useRouter()可以获取router信息

<script>
import { useRouter } from 'vue-router'

export default {
  setup() {
    const router = useRouter()
    const login = () => {
      router.push('/home')
    }
    return {
      login,
    }
  },
}
</script>

vuex4

基本使用

  1. 安装依赖包
yarn add vuex
or
npm install vuex
  1. 创建文件 store/index.js
import { createStore } from 'vuex'

const store = createStore({
  state: {
    money100,
  },
  mutations: {
    changeMoney(state) {
      state.money += 10
    },
  },
  actions: {
    changeMoneyAsync(context) {
      setTimeout(() => {
        context.commit('changeMoney')
      }, 1000)
    },
  },
  getters: {
    double(state) {
      return state.money * 2
    },
  },
})

export default store

  1. 在main.js中关联store
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App)

app.use(router)
app.use(store)
app.mount('#app')

在组件中使用vuex

const store = useStore()

const money = computed(() => store.state.money)
const double = computed(() => store.getters.double)


// mapState  mapMutations mapActions mapGetters  需要配合options api才能使用

总结:vuex4 在vue3项目中能用,但是不好用,推荐pinia,上一篇文章有介绍🎈

新增内置组件:Teleport 传送门组件

拓展阅读:官方文档[13]

Vue3 官方文档中提到同样的定位问题:

当在初始 HTML 结构中使用这个组件时,会有一些潜在的问题:

  • position: fixed 能够相对于视口放置的条件是:没有任何祖先元素设置了 transformperspective 或者 filter 样式属性。而如果我们想要用 transform 为祖先节点设置动画,则会破坏模态框的布局结构!
  • 模态框的 z-index 被包含它的元素所制约。

基本用法

  • 传送门 to 属性可以指定传送到某个节点。
 <template>
  <!-- 🔔 Teleport 的内容会传送到 body 标签中 -->
  <div style="transform:translate(0) ;">
  <Teleport to="body">
        <h1>传送内容</h1>
  </Teleport>
 </template>

  
  <style lang="less" scoped>
  .box{
    position: fixed;
    width200px;
    margin-left500px;
    margin-top100px;
  }
</style>

image.png
image.png

传送到指定结构

  • 准备一个结构接收。
<template>
   <div id="transfer"></div>
   
   <div style="transform:translate(0) ;">
   <Teleport to="#transfer">
          <div class="box">传送内容</div>
   </Teleport>
   </div>

</template>

<style lang="less" scoped>
  .box{
    position: fixed;
    width: 200px;
    margin-left: 500px;
    margin-top: 100px;
}
</
style>
image.png
image.png
  • 如果要传送到指定结构,结构需要提前准备,否则报错。🚨 alt
参考资料
[1]

https://vuejs.org/: https://vuejs.org/

[2]

https://v3.cn.vuejs.org/: https://v3.cn.vuejs.org/

[3]

http://staging-cn.vuejs.org/: http://staging-cn.vuejs.org/

[4]

https://element-plus.gitee.io/#/zh-CN: https://element-plus.gitee.io/#/zh-CN

[5]

https://vant-contrib.gitee.io/vant/v3/#/zh-CN: https://vant-contrib.gitee.io/vant/v3/#/zh-CN

[6]

https://antdv.com/docs/vue/introduce-cn/: https://antdv.com/docs/vue/introduce-cn/

[7]

https://vue3js.cn/vue-composition/: https://vue3js.cn/vue-composition/

[8]

https://vitejs.cn/: https://vitejs.cn/

[9]

https://gitee.com/link?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FJavaScript%2FGuide%2FModules: https://gitee.com/link?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FJavaScript%2FGuide%2FModules

[10]

https://staging-cn.vuejs.org/guide/essentials/lifecycle.html#registering-lifecycle-hooks: https://staging-cn.vuejs.org/guide/essentials/lifecycle.html#registering-lifecycle-hooks

[11]

mailto:vue-router@4.x: mailto:vue-router@4.x

[12]

https://router.vuejs.org/: https://router.vuejs.org/

[13]

https://staging-cn.vuejs.org/guide/built-ins/teleport.html#teleport: https://staging-cn.vuejs.org/guide/built-ins/teleport.html#teleport

本文由 mdnice 多平台发布

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构-day7

二叉树创建、遍历、计算结点、计算深度 head.h #include<stdio.h> #include<stdlib.h> #include<string.h>typedef char datatype; typedef struct Btree{datatype data;struct Btree *lchild;struct Btree *rchild; }*btree;btree create(); void insert_…

【数据结构】双向链表 超详细 (含:何时用一级指针或二级指针;指针域的指针是否要释放)

目录 一、简介 二. 双链表的实现 1.准备工作及其注意事项 1.1 先创建三个文件 1.2 注意事项&#xff1a;帮助高效记忆 1.3 关于什么时候 用 一级指针接收&#xff0c;什么时候用 二级指针接收&#xff1f; 1.4 释放节点时&#xff0c;要将节点地址 置为NULL&#xff0…

如何过滤离线logcat日志文件?

1.需求&#xff1a; How did Android Studio Logcat to read the files which have save in logcat? I saved some logs and would like to open them with Android Studio - Logcat interface and be able to see the colours and apply some filters just as if the pho…

T113-Pro的buildroot添加gdisk ( GPT disks )出现gptfdisk needs a toolchain w/ C++的解决方法

问题背景&#xff1a; 最近入手了百问网的全志T113-Pro&#xff0c;用Emmc启动发现一张32GB的SD卡在烧录了百问网镜像 100ask-t113-pro_sdcard.img 的系统后&#xff0c;仅有200多M的存储空间。第一时间上百问网论坛看是否有板友也出现类似情况&#xff0c;发现了一个帖子正是描…

7.NFS服务器

目录 1. 简介 1.1. NFS背景介绍 1.2. 生产应用场景 2. NFS工作原理 2.1. 示例图 2.2. 流程 3. NFS的使用 3.1. 安装 3.2. 配置文件 3.3. 主配置文件分析 3.4. 实验1 3.5. NFS账户映射 3.5.1. 实验2&#xff1a; 3.5.2. 实验3 4. autofs自动挂载服务 4.1. 产生原…

Transformer 代码补充

本文是对Transformer - Attention is all you need 论文阅读-CSDN博客以及【李宏毅机器学习】Transformer 内容补充-CSDN博客的补充&#xff0c;是对相关代码的理解。 先说个题外话&#xff0c;在之前李宏毅老师的课程中提到multi-head attention是把得到的qkv分别乘上不同的矩…

030-安全开发-JS应用NodeJS指南原型链污染Express框架功能实现审计

030-安全开发-JS应用&NodeJS指南&原型链污染&Express框架&功能实现&审计 #知识点&#xff1a; 1、NodeJS-开发环境&功能实现 2、NodeJS-安全漏洞&案例分析 3、NodeJS-开发指南&特有漏洞 演示案例&#xff1a; ➢环境搭建-NodeJS-解析安装&…

常用换源总结

1.Ubuntu16.04更换国内源 在Ubuntu系统上使用apt-get install进行软件安装或更新的时候&#xff0c;由于使用的是国外源&#xff0c;导致下载速度很慢或者连接超时&#xff0c;需要更换下载源。 1.将系统原始的源文件进行备份 sudo cp /etc/apt/sources.list /etc/apt/source…

c语言--二进制和其他进制之间的转换

目录 一、前言二、二进制、十进制、十六进制、八进制的组成2.1二进制的组成2.2十进制的组成2.3八进制的组成2.4十六进制的组成 三、二进制转换为十进制3.1 二进制转换为十进制3.2十进制转换为二进制 四、二进制转八进制和十六进制4.1二进制转八进制4.2二进制转换为十六进制 五、…

【安装指南】maven下载、安装与配置详细教程

&#x1f33c;一、概述 maven功能与python的pip类似。 Apache Maven是一个用于软件项目管理和构建的强大工具。它是基于项目对象模型的&#xff0c;用于描述项目的构建配置和依赖关系。以下是一些关键的 Maven 特性和概念&#xff1a; POM&#xff08;Project Object Model&…

Mybatis基础教程及使用细节

本篇主要对Mybatis基础使用进行总结&#xff0c;包括Mybatis的基础操作&#xff0c;使用注解进行增删改查的练习&#xff1b;详细介绍xml映射文件配置过程并且使用xml映射文件进行动态sql语句进行条件查询&#xff1b;为了简化java开发提高效率&#xff0c;介绍一下依赖&#x…

安科瑞电气火灾监控系统在海尔(合肥)创新产业园一期厂房改扩建项目的设计与应用

摘要&#xff1a;介绍海尔&#xff08;合肥&#xff09;创新产业园一期厂房改扩建项目采用安科瑞剩余电流式电气火灾探测器&#xff0c;就地组网方式&#xff0c;通过现场总线通讯远传至后台&#xff0c;从而实现剩余电流式电气火灾监控系统的搭建&#xff0c;完成对现场配电回…

万户 ezOFFICE wpsservlet SQL注入漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

微信小程序应用商店源码系统 带完整的安装代码包以及搭建教程

随着微信小程序的普及&#xff0c;越来越多的企业和开发者开始关注小程序的开发与运营。为了满足市场需求&#xff0c;小编给大家分享一款微信小程序应用商店源码系统。该系统集成了完整的安装代码包&#xff0c;方便用户快速搭建自己的小程序应用商店。 以下是部分代码示例&a…

typedef

typedef typedef &#xff0c;type表示类型&#xff0c; def就是define&#xff0c; 定义的意思。所以&#xff0c;根据名字我们就可以知道typedef就是类型定义的意思。可以对一个类型进行重新定义。 一般对一个类型重新定义都是这种形式: typedef 类型 重定义 如&#xff…

web学习笔记(十九)

目录 1.作用域 1.1作用域的概念 1.2作用域的分类 1.2.1全局作用域 1.2.2局部作用域 1.2.3块级作用域&#xff08;ES6新增 &#xff09; 2.变量作用域 2.1全局变量 2.2局部变量 3.作用域链 3.1作用域链的定义 4.垃圾回收机制 4.1定义 4.2如何避免内存泄漏 5.预…

1895_分离进程的能力

1895_分离进程的能力 全部学习汇总&#xff1a; g_unix: UNIX系统学习笔记 (gitee.com) 有些理念可能在控制类的嵌入式系统中不好实施&#xff0c;尤其是没有unix这样的系统搭载的情况下。如果是考虑在RTOS的基础上看是否有一些理念可以做尝试&#xff0c;我觉得还是可以有一定…

Android: 深入理解 ‘companion object {}‘

Android: 深入理解 ‘companion object {}’ Kotlin是一种现代的、静态类型的编程语言&#xff0c;它在设计时充分考虑了开发者的生产力和代码的可读性。其中一个独特的特性就是companion object。在本篇博客中&#xff0c;我们将深入探讨这个特性&#xff0c;理解它的工作原理…

一款轻量级、高性能、功能强大的内网穿透代理服务器

简介 nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发&#xff0c;可支持任何tcp、udp上层协议&#xff08;访问内网网站、本地支付接口调试、ssh访问、远程桌面&#xff0c;内网dns解析等等……&#xff09;&#xff0c;此外还支持内网htt…

Node需要了解的知识

Node能执行javascript的原因。 浏览器之所以能执行Javascript代码&#xff0c;因为内部含有v8引擎。Node.js基于v8引擎封装&#xff0c;因此可以执行javascript代码。Node.js环境没有DOM和BOM。DOM能访问HTML所有的节点对象&#xff0c;BOM是浏览器对象。但是node中提供了cons…