【B站 heima】小兔鲜Vue3 项目学习笔记

news2024/12/25 2:27:29

系列文章目录

Day 01

目录

  • 系列文章目录
    • 前言
    • Day01
      • 1.项目使用相关技术栈
      • 2. 项目规模和亮点
      • 3. Vue2和Vue3实现一个小案例
      • 4. vue3的优势
      • 5. create-vue脚手架工具
      • 6. 熟悉我们的项目目录和文件
      • 7. 组合式API-setup选项
      • 8. 组合式API-reactive和ref函数
      • 9. 组合式API-computed计算属性
      • 10. 组合式API-watch监听属性
      • 11. 组合式API-生命周期函数
      • 12. 组合式API-父子通信
      • 13. 组合式API-子传父
      • 14.组合式API-模板引用
      • 15.组合式API-provide和inject
      • 16.综合小案例
        • 渲染
        • 删除
        • 编辑
    • Day01小结

前言

vue3现在使用很广泛,必学!

vue3项目,本文主要是学习项目功能实现并进行总结。

配套资料的话去B站下方自己拿。

持续更新…

Day01

1.项目使用相关技术栈

create-vue、Vue3+Setup、VueRouter、VueUse、Pinia

知识点插入:

C端:C是单词Consumer的缩写,即个人用户。C端产品指的是面向个人用户的产品,如微信、淘宝。

B端:B是单词Business的缩写,即企业用户。B端产品指的是面向企业用户的产品,如ERP系统、CRM系统。

2. 项目规模和亮点

项目规模:涉及到9大业务模块,27+业务组件、20+业务接口、10+业务解决方案

项目亮点:长页面吸顶交互实现、图片懒加载指令封装、画板插槽组件等业务通用组件封装、SKU电商组件封装、通用逻辑函数封装、路由缓存问题处理。

3. Vue2和Vue3实现一个小案例

需求描述:点击按钮,数字+1

vue2实现:

//vue2 选项式API
<template>
    <button @click="addCounter">{{ counter }}</button>
</template>

<script>
export default {
    name: 'Counter',
    data() {
        return {
            counter: 0
        }
    },
    methods: {
        addCounter() {
            this.counter++;
        }
    }
}
</script>

vue3实现:

//vue3 组合式API
<template>
    <button @click="addCounter">{{ counter }}</button>
</template>

<script setup>
//有这个setup就可以写组合式api了
import { ref } from 'vue'  //ref 生成响应数据
const counter = ref(0)
const addCounter = () => { counter.value++ }
</script>

vue3的代码量变少了,分散式维护编程了集中式维护了

4. vue3的优势

  • 组合式API,能更好的支持TS,容易维护
  • 速度提高,diff算法重写,模板编译优化,组件初始化更高效了
  • 按需引入,良好的treeShaking,体积更小
  • 数据响应式更优了,proxy

5. create-vue脚手架工具

我们之前在vue2学过使用过vue-cli脚手架

vue3使用的是create-vue,底层是vite,我们使用它来创建项目。

创建环境条件:node.js版本16.0以上

创建vue3应用,安装并执行create-vuenpm init vue@latest

注:目前配置项我们都是否,做项目的时候按需选择。在这里插入图片描述

这样我们就安装成功了,按照它的绿色代码执行(进入文件夹,安装依赖,运行项目),将我们的代码运行起来
在这里插入图片描述
运行起来地址,我们打开:
在这里插入图片描述

如果是这个页面就是成功的,这个页面也是一个很好的学习工具,感兴趣可以点击了解一下:
在这里插入图片描述

6. 熟悉我们的项目目录和文件

package.json:本次项目执行的命令和相关的依赖。
在这里插入图片描述
vite.config.js:项目配置文件,在vue2中是vue.config.js
在这里插入图片描述

业务文件夹src下的main.js入口文件

//入口文件
//vue2中式new Vue()创建一个应用实例对象
//vue3中使用createApp函数创建应用实例
import './assets/main.css'

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

//1.以App为参数,生成一个应用实例对象
//2.挂载到id为app的节点上
createApp(App).mount('#app')

这个节点在哪呢,和vue2一样在index.html

在这里插入图片描述

src中的App.vue

我删了一些代码,结构看起来更清晰

<script setup>
<!--setup:开关,容许在script中书写组合式API-->
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
</script>

<template>
  <header>
    <img  />
    <div class="wrapper"></div>
  </header>
  <main>
    <TheWelcome />
  </main>
</template>

<style scoped>
...
</style>

相比于vue2scripttemplate顺序发生了改变,template里不再要求唯一根元素,省去了一些无用的元素。

7. 组合式API-setup选项

我们先看一些组合式api和选项式api是什么

  • 组合式API是一种基于函数的API,它允许开发者将组件的逻辑代码拆分成多个独立的函数,每个函数负责处理特定的功能或逻辑。

  • 选项式API是基于对象的,我们将一个Vue实例的各个部分拆分成不同的选项,如data、methods、computed、watch等,并在创建Vue实例时将它们作为选项传入。

setup的写法:

<script>
export default {
  setup() {
   ...
  }
}
</script>

这个函数会在生命周期beforeCreate之前执行,验证一下:

<!--App.vue-->
<script>
export default {
  setup() {
    console.log('setup')
  },
  beforeCreate() {
    console.log('beforeCreate')
  }
}
</script>
<template>

</template>
<style></style>

在这里插入图片描述

setup的用法:

  • 在setup定义数据和函数
  • setup函数中 return 数据和函数
  • 在template中使用数据和方法

做个小练习:

<script>
export default {
  setup() {
    //1.声明变量和函数
    const message = '我是一个小蘑菇'
    const logMessage = () => {
      console.log(message)
    }
    return {
      //2.返回变量和函数
      message,
      logMessage
    }
  },
}
</script>
<template>
  //3.使用变量和函数
  {{ message }}
  <button @click="logMessage">点击我</button>
</template>
<style></style>

保存,看效果:

在这里插入图片描述

这里不再推荐使用this,this也获取不到组件实例对象了

这里vue3提供了一个语法糖<script setup>,可以简化代码的写法,将export default、setup()、return都简化掉了

刚才那个栗子使用语法糖的写法:

<script setup>
    const message = '我是一个小蘑菇'
    const logMessage = () => {
      console.log(message)
    }
</script>
<template>
  {{ message }}
  <button @click="logMessage">点击我</button>
</template>

8. 组合式API-reactive和ref函数

作用:生成响应数据

响应式数据:数据变而页面变

reactive:传入对象类型数据,返回一个响应式对象,注意是对象类型

reactive用法:

  • 导入reactive
  • 执行函数(传参,接收)
<script setup>
//引入
import { reactive } from 'vue';
//对象类型变量
const person = {
  name: 'ruru',
  age: 18
}
//使用函数
const res = reactive(person);

</script>
<template>
  <!-- 使用变量 -->
  我是{{ res.name }},我今年{{ res.age }}岁了
  <button @click="res.age++">年龄+1</button>
</template>

在这里插入图片描述

ref:传入简单或对象类型数据,返回一个响应式对象,简单类型和对象类型都支持

ref用法:

  • 导入ref
  • 执行函数(传参,接收)

注意:脚本区域修改ref产生的响应式对象数据(如 a),需要通过value属性。

<script setup>
//引入
import { ref } from 'vue';
//对象类型变量
const name = 'ruru'
const age = 18
const add = () => {
  a.value++
}
//使用函数
const n = ref(name);
const a = ref(age)

</script>
<template>
  <!-- 使用变量 -->
  我是{{ n }},我今年{{ a }}岁了
  <button @click="add">点击a+1</button>
</template>

在这里插入图片描述

ref函数内部实现依赖于reactive,实际工作中推荐使用ref函数,比较灵活

9. 组合式API-computed计算属性

思想和vue2保持一致,只是写法不同

用法:

  • 导入
  • 执行函数,return计算之后的值,变量接收

小栗子实现:[1,2,3,4,5,6,7,8] =》 [3,4,5,6,7,8]

<script setup>
import { computed, ref } from 'vue';
const arr = ref([1, 2, 3, 4, 5, 6, 7, 8]);
const arr2 = computed(() => {
  //ref产生的数据要通过value修改,使用filter函数过滤
  return arr.value.filter(item => item > 2)
})
</script>

<template>
  <div>
    原始响应式数组:{{ arr }}
	<br />
    过滤后的数组:{{ arr2 }}
  </div>
</template>

****

计算属性中不应该有副作用,避免直接修改计算属性的值,计算属性应该是只读

10. 组合式API-watch监听属性

侦听一个或者多个数据的变化,数据变化时执行监听函数

额外参数:immediate(立即执行)、deep(深度监听)

使用:

  • 导入函数
  • 执行watch函数,参数传入响应式数据回调函数

举个 单个数据 的栗子

<script setup>
import { watch, ref } from 'vue';
const count = ref(0)
const setCount = () => {
  count.value++
}
//监听属性watch
watch(count, (newValue, oldValue) => {
    //当count发生改变时打印
  console.log('count改变了',newValue, oldValue)
  
})

</script>

<template>
  <div>
    当前count:{{ count }}
    <button @click="setCount">count+1</button>
  </div>
</template>

在这里插入图片描述

监听 多个数据 的话,只需要改动一下参数,参考代码⬇

多个数据中,只要有一个数据改变了,就会调用回调函数。

watch(
[count,name],
([newCount,newName],[oldCount.oldName]) =>{
	...
	}
)

immediate:侦听器创建时立即触发回调,响应式数据变化继续执行回调

用法示例:

const count = ref(0)
watch(count,()=>{
	console.log('count发生了变化')
},{
immediate : true
})

通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项

deep:深层监听

const state = ref({count:0})
watch(count,()=>{
    //count发生变化也不会打印
	console.log('count发生了变化')
})
const state = ref({count:0})
watch(count,()=>{
    //会打印
	console.log('count发生了变化')
},{
    deep:true
})

精确监听

假如目前有两个响应式数据agename,我只想在监听到age数据变化的时候执行回调函数,该怎么办呢?

我们可以这样做:watch参数写两个回调,一个写数据值,另一个写逻辑,大致代码如下:

const person = ref({name:'ruru',age:18})
watch(
	()=>person.age.value,
    ()=> console.log('age改变了')
)

deep有性能损耗,尽量不开启deep,使用 精确监听

11. 组合式API-生命周期函数

vue2和vue3生命周期API(选项式 vs 组合式)

选项式API组合式API
beforeCreate/createdsetupvue3无onCreated钩子,直接写在setup中即可。
beforeMountonBeforeMount挂载之前
mountedonMounted挂载完毕
beforeUpdateonBoforeUpdate更新之前
UpdatedonUpdated更新完毕
beforeUnmountonBeforeUnmount销毁之前
unmountedonUnmounted销毁完毕

基本使用:

  • 导入
  • 执行函数,传入回调

我们以onMounted作栗子来演示生命钩子的使用。

<script setup>
import { onMounted, ref } from 'vue';

onMounted(() => {
  console.log('组件挂载完毕')
})

</script>

<template>
</template>

生命周期函数可执行多次,按顺序执行

一种适用场景是:当你拿到一个写好的项目,不敢改别人的代码怕给整错了,就可以创建一个钩子写入自己的代码,不会影响别人的代码。

<script setup>
import { onMounted, ref } from 'vue';
onMounted(() => {
  console.log('组件挂载完毕1')
})
onMounted(() => {
  console.log('组件挂载完毕3')
})
onMounted(() => {
  console.log('组件挂载完毕2')
})


</script>

<template>
  <div>

  </div>
</template>

在这里插入图片描述

12. 组合式API-父子通信

最常用,最简单

基本思想:

  • 父组件给子组件绑定属性
  • 子组件通过defineProps编译器宏,接收子组件传递过来的数据

现在我们准备了父App.vue和子son.vue组件。

子组件导入父组件之后,不需要注册直接使用,这是setup语法糖的一个效果。

<!-- App.vue -->
<script setup>
import { onMounted, ref } from 'vue';
import Son from '@/components/son.vue'

</script>

<template>
  <div>
    <h2>父组件App</h2>
    <Son />
  </div>
</template>
<!-- son.vue -->
<script setup>

</script>
<template>
    <div class="son">
        <h3>子组件son</h3>
    </div>
</template>

效果:
在这里插入图片描述

现在我们要实现数据的传递:

<!-- App.vue -->
<script setup>
import { onMounted, ref } from 'vue';
import Son from '@/components/son.vue'

</script>

<template>
  <div>
    <h2>父组件App</h2>
    <!-- 1.属性绑定 -->
    <Son message='我是父组件的数据' />
  </div>
</template>
<!-- son.vue -->
<script setup>
const props = defineProps({
    // 2.接收
    message: String
})
</script>
<template>
    <div class="son">
        <h3>子组件son</h3>
        <!-- 3.使用 -->
        {{ message }}
    </div>
</template>

上述代码使用了props变量接收了数据,我们可以props.message获取到数据。

补充:

传入响应式数据,传递多个数据,相关代码演示:

// App.vue 
const count = ref(0)

<Son :count="count" message = '我是父组件的数据' />
//son.vue 
const props = defineProps({
	message:String,
	count:Number
})

13. 组合式API-子传父

基本思想:

  • 父组件给子组件标签通过@绑定事件

  • 子组件通过defineEmits编译器生成emit方法

  • 触发自定义事件,传递参数

通过栗子演示

<!-- App.vue -->
<script setup>
import { onMounted, ref } from 'vue';
import Son from '@/components/son.vue'
const getMessage = (msg) => {
  console.log(msg)
}
</script>

<template>
  <div>
    <h2>父组件App</h2>
    <!--1.绑定事件  -->
    <Son @get-message="getMessage" />
  </div>
</template>
<!-- son.vue -->
<script setup>
//2.生成emit方法
const emit = defineEmits(['get-message'])
//3.触发自定义事件,传参 
const sendMsg = () => emit('get-message', '我是来自子组件的信息,收到请回答!')
</script>
<template>
    <div class="son">
        <h3>子组件son</h3>
        <!-- 4.使用 -->
        <button @click="sendMsg">给父组件发信息</button>
    </div>
</template>

在这里插入图片描述

14.组合式API-模板引用

学过vue2的应该很熟悉

通过ref获取真实的dom对象或者组件示例对象。

获取dom使用方法(组件同理):

  • 调用 ref 函数生成一个 ref 对象
  • 通过 ref 标识绑定 ref 对象到标签
  • 通过value获取标签
<script setup>
import {ref} from 'vue'
//1.调用ref函数
const h1ref = ref(null)

//组件挂载完毕才能获取到dom对象
onMounted(()=>{
    console.log(h1ref.value)  //<h1>我是dom标签h1</h1>
})
</script>
<template>
<!--2.通过ref标识绑定ref对象-->
<h1 ref="h1ref">我是dom标签h1</h1>
</template>

defineExpose:

默认情况下,在<script setup>语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过defineExpose编译宏指定哪些属性可以访问。

<script setup>
import {ref} from 'vue'
const msg = ref('一段消息')
defineExpose({
    msg
})
</script>

15.组合式API-provide和inject

顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信。

在这里插入图片描述

实现办法:

  • 从vue中引入这俩函数

  • 顶层数据通过provide函数提供数据/响应式数据

provide('key',顶层数据/ref对象)
  • 底层组件通过inject函数获取数据
const message = inject('key')

除了可以传数据,还可以传方法

  • 从vue中引入这俩函数

  • 顶层数据通过provide函数提供函数

const setCount = ()=>{
    count.value++
}
provide('setCount-key',setCount)
  • 底层组件通过inject函数获取函数
const setCount = inject('setCount-key')
  • 就可以在底层组件中使用了
<button @click="setCount">修改顶层组件的count</button>

底层函数想要通知顶层函数组件做修改的话,传递一个方法,底层函数调用方法·

16.综合小案例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

找个文件夹,克隆一下,阅读README.md

安装依赖,启动项目:

npm install
npm run dev

页面就是这样的啦:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们是要实现:渲染、编辑、删除 三个小功能

渲染

思路:声明响应式列表list - 调接口获取数据赋值给list - 绑定给table

const list = ref([])
const getList = async () => {
  const res = await axios.get('/list')
  list.value = res.data  //赋值
}
 <el-table :data=list>
     ...
</el-table>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

删除

思路:获取当前行的id - 调用接口 - 更新数据

<!--利用插槽-->
<template #default="{ row }">
          <el-button type="primary" link>编辑</el-button>
          <el-button type="danger" link @click="delList(row.id)">删除</el-button>
        </template>
const delList = async (id) => {
  await axios.delete(`/del/${id}`)
  getList()
}
编辑

思路:打开弹框 - 回填数据 - 更新数据

点击 编辑 按钮,打开弹框

<el-button type="primary" link @click="onEdit">编辑</el-button>

父组件获取子组件的数据dialogVisible,使用ref获取子组件的示例对象,调用其方法或者属性

const editRef = ref(null)

<Edit ref="editRef" />
const open = ()=>{
	dialogVisible.value = true
}
defineExpose({
    open
})
const onEdit = ()=>{
	editRef.value.open()
}

这时弹框可以正常打开了。

我们在点击按钮调用onEdit,将数据给Edit组件传下去

<el-button type="primary" link @click="onEdit(row)">编辑</el-button>
const onEdit = (row)=>{
	editRef.value.open(row)
}
const open = (row)=>{
	dialogVisible.value = true
	console.log(row)
}

这样子组件就拿到了数据

准备一个Edit组件的响应式数据form,用来绑定数据

这个属性名称要参考下面的姓名和籍贯书写

const form = ref({
	name:'',
	place:''
})
const open = (row)=>{
	dialogVisible.value = true
	//console.log(row)
    form.value.name = row.name
   	form.value.place = row.place
}

双向绑定:

 <el-form label-width="50px">
      <el-form-item label="姓名">
        <el-input placeholder="请输入姓名" v-model="form.name"/>
      </el-form-item>
      <el-form-item label="籍贯">
        <el-input placeholder="请输入籍贯" v-model="form.place"/>
      </el-form-item>
    </el-form>

更新数据,先调接口,关闭弹窗,通知父组件更新列表

<el-button type="primary" @click="onUpdate">确认</el-button>
import axios from 'axios';
const onUpdate = async ()=>{
	await axios.patch(`/edit/${id}`, {
  	name: form.value.name, 
  	place: form.value.place,
 })
}

要传入id,我们补一个id 上面的 ${id} => ${form.value.id},姓名和籍贯都改改,async,await也写上。

const form = ref({
	name:'',
	place:'',
	id:''
})
const open = (row)=>{
	dialogVisible.value = true
	//console.log(row)
    form.value.name = row.name
   	form.value.place = row.place
   	form.value.id = row.id
}

关闭弹窗

dialogVisible.value = false

通知父组件做列表更新,是子传父,我们使用自定义事件。

<!--绑定事件,将 获取列表数据 的函数传过去-->
<Edit ref="editRef" @on-update="getList"/>
const emit = defineEmits(['on-update'])

emit('on-update')

这样就完成了

项目相关全部代码:

<!-- App.vue -->
<script setup>
import Edit from './components/Edit.vue'
import { onMounted, ref } from 'vue';
import axios from 'axios'

// TODO: 列表渲染
const list = ref([])
const getList = async () => {
  const res = await axios.get('/list')
  list.value = res.data  //赋值
}

onMounted(() => getList())
// TODO: 删除功能
const delList = async (id) => {
  await axios.delete(`/del/${id}`)
  getList()
}

// TODO: 编辑功能
//思路:打开弹框 - 回填数据 - 更新数据
const editRef = ref(null)

const onEdit = (row) => {
  editRef.value.open(row)
}
</script>

<template>
  <div class="app">
    <el-table :data=list>
      <el-table-column label="ID" prop="id"></el-table-column>
      <el-table-column label="姓名" prop="name" width="150"></el-table-column>
      <el-table-column label="籍贯" prop="place"></el-table-column>
      <el-table-column label="操作" width="150">
        <template #default="{ row }">
          <el-button type="primary" link @click="onEdit(row)">编辑</el-button>
          <el-button type="danger" link @click="delList(row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
  <Edit ref="editRef" @on-update="getList" />
</template>

<style scoped>
.app {
  width: 980px;
  margin: 100px auto 0;
}
</style>

<!-- Edit.vue -->
<script setup>
// TODO: 编辑
import { ref } from 'vue'
import axios from 'axios';
// 弹框开关
const dialogVisible = ref(false)
const emit = defineEmits(['on-update'])
const form = ref({
  name: '',
  place: '',
  id: ''
})
const onUpdate = async () => {
  await axios.patch(`/edit/${form.value.id}`, {
    name: form.value.name,
    place: form.value.place,
  })
  dialogVisible.value = false  //关闭弹窗
  emit('on-update')
}
const open = (row) => {
  dialogVisible.value = true
  form.value.name = row.name
  form.value.place = row.place
  form.value.id = row.id
}
defineExpose({
  open
})
</script>

<template>
  <el-dialog v-model="dialogVisible" title="编辑" width="400px">
    <el-form label-width="50px">
      <el-form-item label="姓名">
        <el-input placeholder="请输入姓名" v-model="form.name" />
      </el-form-item>
      <el-form-item label="籍贯">
        <el-input placeholder="请输入籍贯" v-model="form.place" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="onUpdate">确认</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped>
.el-input {
  width: 290px;
}
</style>

Day01小结

第一天,讲的是vue3的一些基础知识,做了一个小练习
love and peace
没学vue2的慎入

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

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

相关文章

动态IP与静态IP有什么区别?如何选择?

动态IP和静态IP都是指网络设备&#xff08;如计算机、服务器、路由器等&#xff09;在互联网上分配的IP地址的类型。 一、什么是动态IP&#xff0c;什么是静态IP&#xff1f; 1、什么是动态IP&#xff1f; 动态IP是指由Internet服务提供商&#xff08;ISP&#xff09;动态分配…

xrdp多用户多控制界面远程控制

1、无桌面安装桌面&#xff08;原本有ubuntu桌面的可以直接跳过这一步&#xff09; Gnome 与 xfce 相比&#xff0c;xfce 由于其轻巧&#xff0c;它可以安装在低端台式机上。Xfce 优雅的外观&#xff0c;增强了用户体验&#xff0c;它对用户非常友好&#xff0c;性能优于其他桌…

docker- 购建服务镜像并启动

文章目录 前言docker- 购建服务镜像并启动1. 前期准备2. 构建镜像3. 运行容器4. 验证 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实…

扩散模型自动管道AutoPipeline

推荐&#xff1a;write_own_pipeline.ipynb - Colab (google.com) 为您的任务选择一个 AutoPipeline 首先选择一个检查点。例如&#xff0c;如果您对使用 runwayml/stable-diffusion-v1-5 检查点的文本到图像感兴趣&#xff0c;请使用 AutoPipelineForText2Image&#xff1a; f…

linux ping https是否连接

在Linux系统中&#xff0c;ping通常用于测试网络上另一台主机的可达性。它使用的是ICMP协议&#xff0c;这是一种设计用来处理网络通信问题的协议。HTTPS则是一种安全的网络传输协议&#xff0c;它使用SSL/TLS加密。 如果你想要测试到某个HTTPS服务器的连接&#xff0c;你可以使…

【MySQL精通之路】InnoDB(6)-磁盘结构(2)-索引

主博客&#xff1a; 【MySQL精通之路】InnoDB(6)-磁盘上的InnoDB结构-CSDN博客 上一篇&#xff1a; 下一篇&#xff1a; 【MySQL精通之路】磁盘上的InnoDB结构-表空间-CSDN博客 目录 1.聚集索引和二级索引 1.1 Innodb 如何建立聚集索引 1.2 聚集索引如何加快查询速度 1…

CustomTkinter:便捷美化Tkinter的UI界面(附模板)

CustomTkinter是一个基于Tkinter的Python用户界面库。 pip3 install customtkinter它提供了各种UI界面常见的小部件。这些小部件可以像正常的Tkinter小部件一样创建和使用&#xff0c;也可以与正常的Tkinter元素一起使用。 它的优势如下&#xff1a; CustomTkinter的小部件和…

四天学会JS高阶(学好vue的关键)——深入面向对象(理论+实战)(第三天)

***本章面试使用居多* 理论篇**一、编程思想 1.1 面向过程 JS 前端居多 按照步骤 性能高 适合跟硬件关系很紧密 没有面向对象易维护易复用易扩展 1.2 面向对象 java典型 按照功能&#xff0c;把事务分别成一个个对象&#xff0c;对象之间分工合作 比较灵活 适合多人合作的…

模拟笔试 - 卡码网周赛第十八期(23年科大讯飞提前批笔试真题)

第一题&#xff1a; 参考思路解析&#xff1a;&#xff08;遍历nums中的每个数字&#xff0c;得到不为0的数位即可。&#xff09; 1.导入Scanner类&#xff1a; import java.util.Scanner;&#xff1a;引入 Scanner 类&#xff0c;用于读取用户输入。 2.主方法&#xff1a; …

力扣1809 没有广告的剧集(postgresql)

需求 Table: Playback ----------------- | Column Name | Type | ----------------- | session_id | int | | customer_id | int | | start_time | int | | end_time | int | ----------------- 该表主键为&#xff1a;session_id &#xff08;剧集id&#xff09; customer_…

【C++算法】BFS解决FloodFill算法相关经典算法题

1.图像渲染 我们这道题可以使用深搜来解决&#xff0c;利用一个队列遍历到与该点相连的所有像素相同的点&#xff0c;然后将其修改成指定的像素即可&#xff0c;直接上思路&#xff1a; 直接上代码&#xff1a; class Solution {int dx[4] {0, 0, 1, -1};int dy[4] {1, -1, …

计组期末必考大题

一.寻址方式详解 1.直接寻址 指令地址码直接给到操作数所在的存储单元地址 2.间接寻址 A为操作数EA的地址 3.寄存寻址 4.寄存器间接寻址 5.变址寻址 6.基地址寻址 7.小结 二、指令周期详解 一、基本概念 指令周期:去除指令并执行指令所需要的时间指令周期:由若干个CPU周…

go语言的一些常见踩坑问题

开始之前&#xff0c;介绍一下​最近很火的开源技术&#xff0c;低代码。 作为一种软件开发技术逐渐进入了人们的视角里&#xff0c;它利用自身独特的优势占领市场一角——让使用者可以通过可视化的方式&#xff0c;以更少的编码&#xff0c;更快速地构建和交付应用软件&#…

docker 安装minio 服务 ssl 证书

minio 安装 ssl 证书 下载apache 证书 &#xff08;可以使用免费的证书&#xff09; 放在/opt/minio/conf/certs 下 (安装minio 时的 挂载目录 参考文章 docker 安装minio,详细图解 ) 拷贝进容器 /root/.minio docker cp /opt/minio/conf/certs/private.key minio:/root/.mi…

蜂窝物联四情监测:助力农业升级,科技赋能打造丰收新篇章!

农业四情指的是田间的虫情、作物的苗情、气候的灾情和土壤墒情。“四情”监测预警系统的组成包括管式土壤墒情监测站、虫情测报灯、气象站、农情监测摄像机&#xff0c;可实时监测基地状况,可以提高监测的效率和准确性&#xff0c;为农业生产提供及时、科学的数据支持&#xff…

知识图谱数据预处理笔记

知识图谱数据预处理笔记 0. 引言1. 笔记1-1. \的转义1-2. 特殊符号的清理1-3. 检查结尾是否正常1-4. 检查<>是否存在1-5. 两端空格的清理1-6. 检查object内容长时是否以<开始 0. 引言 最近学习知识图谱&#xff0c;发现数据有很多问题&#xff0c;这篇笔记记录遇到的…

【android 9】【input】【2.结构体含义】

系列文章目录 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录…

怎么认识和应用Redis内部数据结构?no.22

Redis 内部数据结构 RdeisDb Redis 中所有数据都保存在 DB 中&#xff0c;一个 Redis 默认最多支持 16 个 DB。Redis 中的每个 DB 都对应一个 redisDb 结构&#xff0c;即每个 Redis 实例&#xff0c;默认有 16 个 redisDb。用户访问时&#xff0c;默认使用的是 0 号 DB&#…

NLP(18)--大模型发展(2)

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 LLM的结构变化&#xff1a; Muti-head 共享&#xff1a; Q继续切割为muti-head,但是K,V少切&#xff0c;比如切为2个&#xff0c;然后复制到n个muti-head减少参数量&#xff0c;加速训练 attention结构改动&#xff1a; s…

数据安全保护的权益有什么?

针对个人主体&#xff0c;数据需要保护的权益有&#xff1a; 个人的隐私安全、社交安全、财产安全、支付安全、各类权利安全、生命安全、声誉安全 这些权益在物理世界中也基本都是存在的&#xff0c;只不过在数字世界中进行了映射或者重构。 针对企业的主体&#xff0c;需要保…