VUE3.0基础入门笔记

一、响应式基础

1.ref():声明基本类型,引用类型,函数需接收参数,并将其包裹在一个带有 .value 属性的对象中,在模板中使用 ref 时,我们不需要附加 .value,当在模板中使用时,ref 会自动解包。

<template>
    <button @click="count++">
        {{ count }}
    </button>
</template>

<script setUp>
    import { ref } from 'vue'    
    const count = ref(0)
    console.log(count.value)
</script>

2.reactive():声明对象、数组等复杂类型。

<template>
    <button @click="state.count++">
          {{ state.count }}
    </button>
</tempalte>
<script setUp>
    import { reactive } from 'vue'
    const state = reactive({ count: 0 })
    console.log(state)
</script>


3. toRefs与toRef深度剖析

3.1 toRefs()函数用于将一个响应式对象的所有属性转换为单独的响应式引用。这个函数通常与解构赋值一起使用,以便我们可以轻松地访问响应式对象的每个属性。

<script setUp> 
import { reactive, toRefs  } from 'vue'
const state = reactive({
  name: 'Commas',
  age: 18
})
//现在解构这个对象,并保持每个属性的响应式,这时toRefs 就派上用场了
//这样,name 和 age 就成为了单独的响应式引用,我们可以直接使用它们,而不必担心失去响应式。
const { name, age } = toRefs(state);
</script> 

3.2 toRef()函数用于为源响应式对象的某个属性创建一个响应式引用。与 toRefs 不同的是,toRef 只能用于单个属性。

<script setUp>
//假设我们有一个响应式对象 state,包含name和age两个属性,现在我们只想为name属性创建一个响应式引用
//这样name就成为了state.name的响应式引用,我们可以直接修改name.value,这个修改会反映state.nam上。
 const name = toRef(state, 'name');
</script>

3.3 联系与区别

(1)toRefs 和 toRef 都用于创建响应式引用。

(2)toRefs 用于将整个响应式对象的所有属性转换为响应式引用,而 toRef 只用于单个属性。

(3)toRefs 通常与解构赋值一起使用,方便同时访问多个属性,而 toRef 用于为单个属性创建响应式引用。

二、计算属性 computed()

getter与setter的计算属性

 get()获取数据

 set()改变数据

<template>
  <div class="computed">
    姓: <input type="text" v-model="firstName" /> <br />
    名: <input type="text" v-model="lastName" /><br />
    姓名: <span>{{ fullName }}</span>
    <br />
    <button @click="changeName">更改姓名</button>
</template>

<script setUp>
import { computed, reactive } from "vue";
let firstName = ref("han");
let lastName = ref("召华");
//默认是 getter 方法
const fullName = computed(() => {
   return firstName.value + "_" + lastName.value;
});

//有getter与setter的计算属性
let fullName = computed({
  get() {
    return (
      firstName.value.slice(0, 1).toUpperCase() +
      firstName.value.slice(1) +
      "-" +
      lastName.value
    );
  },
  set(val) {
    let [str1, str2] = val.split("-");
    firstName.value = str1;
    lastName.value = str2;
  },
});
function changeName() {
  fullName.value = "huang-aaa";
}
</script>

三、watch与watchEffect

3.1watch 监听函数

 情况一:ref(监听不需要加.value)

 情况二:reactive(默认深度监听且deep不可变)

 情况三:getter函数监听 响应式对象的某个属性且是基本数据类型

 情况四:监视多个数据使用数组情况 [() => obj.value.a.b,() => obj.value.a]

<template>
  <h2>one:{{ one }} | two: {{ two.value }}</h2>
  <button @click="one++">改变 one 数据</button>
  <button @click="two.value++">改变 two 数据</button>
</template>

<script setup>
	import { watch, ref ,reactive} from 'vue'
	// 变量1
	const one = ref(0)
	// 变量2
	const two = reactive({
	  value: 10
	})
	// 监听多个变量
	// 第一个参数变为数组形式,每个下标对应一个要监听的变量
	// 第二个参数的函数传参改为每项数组形式,每个数组对应新旧值的参数
	watch([one, () => two.value], ([oneNew, twoNew], [oneOld, twoOld]) => {
		console.log(`one: ${oneNew}(新) ——— ${oneOld}(旧)`);
		console.log(`two: ${twoNew}(新) ——— ${twoOld}(旧)`);
	
	});
</script>

3.2 watchEffect 监听函数

 1.立即运行一个函数,同时响应式追踪其依赖,并在依赖更改时重新执行该函数

 2.watch与watchEffect区别

    2.1都能监听响应式数据变化,只不过见监听方式不同

    2.2watch:要明确指出监视数据

    2.3watchEffect:不用指出监视数据(函数使用哪些,就监视哪些属性)

<script setUp>
let obj = ref({
  a: {
    b: {
      watchName: "韩召华",
      watchAge: 28,
    },
  },
});
    watchEffect(() => {
         if (obj.value.a.b.watchAge > 23) {
            console.log("watchEffect--------", "监听到了");
          }
    });
</script>

四、ref获取DOM的使用

  1.用于修改HTML的DOM

  2.作用在组件上时,获取的是组件实例对象,子组件需通过defineExpose暴露数据,父组件才能使用

const presonDom = ref();
console.log("DOM实例", presonDom);

五、props使用

子组件接收

 1.defineProps 接收list + 限制类型

    defineProps(['a','b'])接收

    defineProps带默认值写法

 const props = defineProps({
  name: String,
    age:{
       type: Number,
       default: 23
    }
  })

 ts写法defineProp<{list?:Persons}>()

 2.withDefaults 接收list + 限制类型 + 限制必要性 + 指定默认值

 withDefaults(defineProps<{list?:Persons}>(),{list:()=>[{id:0,name:"张三",age:18}]})

六、生命周期

 1.创建 setUP

 2.挂载前 onBeforeMount(()=>{})

 3.挂载后 onMounted(()=>{ console.log(子组件挂载优先于父组件) })

 4.更新前 onBeforeUpdate(()=>{})

 5.更新后 onUpdate(()=>{})

 6.卸载前 onBeforeUnmount(()=>{})

 7.卸载后 onUnmounted(()=>{})

七、hooks

 1.use命名

 2.return 可用对象,数组,方法暴露数据且包含属性和方法

3.使用如下

八、routes路由

1.RouterLink 跳转路由

    >to的使用对象:name,path

    >active-class 激活样式

 2.RouterView 展示路由

 3.params query props 路由传参

 4.push推入,replace 替换(无路由记录,直接作用于RouterLink上)

 5.编程式导航 useRouter

 6.redirect 重定向

const router = useRouter();
router.push();
router.replace();

九、集中式状态数据管理 redux | vuex | pinia

1.npm i pinia

2.创建pinia(创建store文件-根据页面组件命名-用use命名store文件-defineStore定义store - 在使用组件引入该store文件 - 通过talkStore.value或者talkStore.$store.value)

3.pinia 修改的三种方式

  3.1第一种方式修改 countstore.sum 直接修改值

  3.2第二种方式修改 批量

 countstore.$patch ({
     sum: 100,
     xxx: 123
  })

  3.3第三种方式 使用actions

 //直接调用actions里的方法

  countStore.increment('参数集');

 4.storeToRefs响应式数据 只关注store中数据,不会对方法进行ref包裹

 5.getters 计算属性

 6.$subscribe 订阅 监听store中的数据变化

 countStore.$subscribe((mutate,satat)=>{
     console.log('监听',mutate,satat)
 }

 十、组件通信

 1.props

  父传子":data"

 子传父 子defineProps(['sentData']) 通过事件传参

 在父组件:sentData="getData"

 getData( value ) {
    console.log('接收子传数据',value);
  }

 2.自定义 defineEmits

  子组件 const emit = defineEmits(['eimtData'])

 emit('emitData',{name:'张三',age:18})

  父组件 @emitData="getData"

   getData( value ) {
       console.log('接收子传数据',value);
   }

  3._mitt工具-总线

 npm引入 mitt

 const emitter =mitt()

 emitter.emit() // 触发钩子

 emitter.on()   // 监听钩子

 emitter.off()  // 解绑钩子(一般在onUnmounted()里使用)

 emitter.all()  // 清空事件

 4.v-model方式

 5.$attrs 祖孙组件传值

  如下图所示,A 和 B、B 和 C/D 都是父子关系,C 和 D 是兄弟关系,A 和 C/D 是隔代关系。

$attrs: 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (包含class 和 style)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (包含class 和 style ),并且可以通过 v-bind=“$attrs” 传入内部组件。在Vue3.0版本中,$listeners / inheritAttrs已被移除掉,现在事件监听器是 $attrs 的一部分。

案例组件(父子孙)

同样,我们创建3个组件: 父组件:parent.vue,子组件:child.vue,孙组件:grandchild.vue

  • 父组件:parent.vue
<template>
  <div class="parent-root">
    <child
      class="child"
      :name="name"
      :age="age"
      @grandchildByValue="grandchildByValue"
    >
    </child>
  </div>
</template>

<script>
import { ref } from 'vue'
import child from '@/views/test/child.vue'
export default {
  name: 'parent',
  components: { child },
  props: {},
  setup() {
    const name = ref('小明'),
      age = ref(18),
      grandchildByValue = value => {
        console.log('孙组件传过来的值:', value)
      }
    return {
      name,
      age,
      grandchildByValue
    }
  }
}
</script>

<style scoped lang="scss"></style>
  • 子组件:child.vue
<template>
  <div class="child-root">
    <grandchild v-bind="$attrs"></grandchild>
  </div>
</template>

<script>
import { ref } from 'vue'
import grandchild from '@/views/test/grandchild.vue'
export default {
  name: 'child',
  components: { grandchild },
  props: {},
  setup(context) {
    console.log('attrs:', context.attrs) 
  }
}
</script>

<style scoped lang="scss"></style>

  • 孙组件:grandchild.vue
<template>
  <div class="grandchild-root">
    <p>name:{{ name }}</p>
    <p>age:{{ age }}</p>
    <el-button type="primary" @click="fn">孙子传值爷爷</el-button>
  </div>
</template>

<script>
export default {
  name: 'grandchild',
  components: {},
  props: {
    name: {
      type: String,
      default: ''
    },
    age: {
      type: Number,
      default: null
    }
  },
  setup(context) {
    const fn = () => {
      context.emit('grandchildByValue', '爷爷,您好')
    }
    return {
      fn
    }
  }
}
</script>

<style scoped lang="scss"></style>

6.$refs跟$parent

ref 需要结合defineExpose暴露数据使用

1、$refs用法

父组件(模板代码:参数$refs
 

<button @click="getAllChild($refs)">让所有孩子的书变多</button>
<Child1 ref="c1"/>
<Child2 ref="c2"/>

 按钮对应的函数代码
这里,就可以同时获取到c1和c2两个实例

	function getAllChild(refs:{[key:string]:any}){
		console.log(refs)
		for (let key in refs){
			refs[key].book += 3
		}
	}

两个子组件
暴露变量,这样父组件就可以操作该变量

// 把数据交给外部
defineExpose({book})

2、$parent用法

子组件(模板代码:参数$parent

<button @click="minusHouse($parent)">干掉父亲的一套房产</button>

按钮对应的函数代码

	function minusHouse(parent:any){
		parent.house -= 1
	}

 父组件(暴露变量

	// 向外部提供数据
	defineExpose({house})

  7.provide_inject依赖注入 祖孙之间直接通信

我们可以使用provide和inject使顶层组件向底层组件提供数据和方法。

Provide

语法格式: provide('key',顶层组件中的数据或方法)

顶层组件示例代码如下:

<template>
    顶层组件
    <Middle />
</template>
 
<script setup>
import { provide, ref } from 'vue'
import Middle from './components/middle.vue'
const count = ref('这是顶层组件提供的数据')
provide('count-key', count)		// 向底层组件提供数据
const sayHello = () => {
  console.log('你好,我是顶层组件提供的方法')
}
provide('sayHello', sayHello)   // 向底层组件提供方法
</script>

 中间组件示例代码如下:

<template>
  中间组件
  <Bottom />
</template>
 
<script setup>
import Bottom from './bottom.vue'
</script>

inject

底层组件通过inject函数获取数据并通过变量接收,其语法格式如下:

const 变量名=inject('key')

底层组件示例代码如下: 

<template>
  底层组件
  <button @click="sayHello">sayHello</button>
  <div>来自顶层组件的数据:{{ countData }}</div>
</template>
 
<script setup>
import { inject } from 'vue'
const sayHello = inject('sayHello')
const countData = inject('count-key')
</script>

十一、shallowReactive和shallowRef

shallowReactive

(1)作用:与reactive作用类似,但只处理对象最外层属性的响应式(浅响应式)

(2)使用场景:如果有一个对象数据,结构比较深(内嵌多层对象),但只需要最外层的属性进行响应式,则使用shallowReactive

shallowRef

(1)作用:与ref作用类型,但只处理基本数据类型的响应式,不处理对象类的响应式

(2)使用场景:如果有一个对象数据,后续功能不会修改该对象中的属性,而是生成新的对象来替换,则使用shallowRef

十二、readonly和shallowReadonly

(1)readonly:将包裹的对象变为只读,并且是深度只读
(2)shallowReadonly:浅层属性为只读,深层次属性可以修改

十三、toRaw和markRaw

     toRaw将代理对象变成普通对象,数据发生变化,不会更新
     markRaw标记的对象数据,从此以后再也不能成为代理对象了

两者区别:toRaw会将整个对象变成非响应式的,markRaw可以指定哪些属性值可以变化

<template>
  <div>
    <h2>toRaw与markRaw</h2>
    <h3>state:{{state}}</h3>
    <button @click="updateToRaw">测试toRaw</button>
    <button @click="updateMarkRaw">测试markRaw</button>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent,reactive,ref,toRaw,markRaw } from 'vue'
interface UserInfo {
  name:string,
  age:number,
  likes?:string[]
}
// 引入子集组件
import Child from './components/child.vue';
export default defineComponent({
    components:{
        Child
    },
    setup(){
      const state = reactive<UserInfo>({
        name:'小明',
        age:12,
      })
      const updateToRaw = () => {
        const user = toRaw(state)
        user.name += '-----'
        console.log('测试')
      }
      const updateMarkRaw = () => {
        // state.likes = ['吃','喝']
        // state.likes[0] += '-----'
        const likes = ['吃','喝']
        state.likes = markRaw(likes)

       setInterval(() => {
           console.log('定时器走起来')
           if (state.likes) {
             state.likes[0] += '----'
           }
         },1000)
        console.log('测试')
      }
      
      return {
        updateToRaw,
        updateMarkRaw,
        state
      }
    }
})
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

十四、自定义customRef

(1)customRef 用于自定义返回一个ref对象,可以显式地控制依赖追踪和触发响应,接受工厂函数
(2)两个参数分别是用于追踪的 track 与用于触发响应的 trigger,并返回一个一个带有 get 和 set 属性的对象

使用:
	import {customRef} from 'vue';
    function useDebouncedRef(value) {
	      return customRef((track, trigger) => {
	        return {
	          get() {
	            track()	追踪当前数据
	            return value
	          },
	          set(newValue) {
	            value=newValue
	            trigger() 触发响应,即更新界面
	          },
	        }
	      })
	 }
	
通过customRef返回的ref对象,和正常ref对象一样,通过x.value修改或读取值

类型声明:
	function customRef<T>(factory: CustomRefFactory<T>): Ref<T>

	type CustomRefFactory<T> = (
	  track: () => void,
	  trigger: () => void
	) => {
	  get: () => T
	  set: (value: T) => void
	}

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

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

相关文章

计算机毕业设计 基于 Python的考研学习系统的设计与实现 Python毕业设计选题 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

CISP/NISP二级练习题-第一卷

目录 另外免费为大家准备了刷题小程序和docx文档&#xff0c;有需要的可以私信获取 1&#xff0e;不同的信息安全风险评估方法可能得到不同的风险评估结果&#xff0c;所以组织 机构应当根据各自的实际情况选择适当的风险评估方法。下面的描述中错误的是 &#xff08;&#…

【Linux】进程的挂起状态

挂起状态的前提条件 当 内存资源严重不足 时&#xff0c;操作系统会考虑将部分进程换出到磁盘上的交换空间&#xff08;swap 分区&#xff09;。这通常发生在以下几种情况下&#xff1a; 内存不足&#xff1a; 当物理内存接近耗尽时&#xff0c;操作系统会选择将一部分暂时不需…

明源云ERP报表服务GetErpConfig.aspx接口存在敏感信息泄露

一、漏洞简介 在访问 /service/Mysoft.Report.Web.Service.Base/GetErpConfig.aspx?erpKeyerp60 路径时&#xff0c;返回了包含敏感信息的响应。这些信息包括但不限于数据库连接字符串、用户名、密码、加密密钥等。这些敏感信息的暴露可能导致以下风险&#xff1a;数据库访问…

Linux 常用命令(一)

目录 ll命令&#xff1a;显示指定文件的详细属性信息 ls&#xff1a;显示目录中文件及其属性信息 mkdir命令&#xff1a;创建目录文件 touch&#xff1a;创建空文件与修改时间戳 rm命令&#xff1a;删除文件或目录 cd命令&#xff1a;切换目录 chmod命令&#xff1a;改变…

llama.cpp 去掉打印,只显示推理结果

llama.cpp 去掉打印&#xff0c;只显示推理结果 1 llama.cpp/common/log.h #define LOG_INF(...) LOG_TMPL(GGML_LOG_LEVEL_INFO, 0, __VA_ARGS__) #define LOG_WRN(...) LOG_TMPL(GGML_LOG_LEVEL_WARN, 0, __VA_ARGS__) #define LOG_ERR(…

docker部署es与kibana Mac

1. 创建网络 神一样的链接&#xff0c;不用谢&#xff1a; 1.Docker命令链接&#xff1a;黑马整理的docker速成链接 2.jdk11链接&#xff1a;jdk11 3.神资源链接&#xff1a;别点&#xff0c;要脸 注意&#xff1a;es需要先安装jdk环境&#xff0c;推荐jdk11&#xff0c;否则…

MySQL企业常见架构与调优经验分享

文章目录 一、选择 PerconaServer、MariaDB 还是 MYSQL二、常用的 MYSQL 调优策略三、MYSOL 常见的应用架构分享四、MYSOL 经典应用架构 观看学习课程的笔记&#xff0c;分享于此~ 课程&#xff1a;MySQL企业常见架构与调优经验分享 mysql官方优化文档 一、选择 PerconaServer、…

基于SSM的的水电管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

Keil8051 下载与安装

文章目录 下载方法&#xff08;一&#xff09;官网下载&#xff08;二&#xff09;百度网盘下载 安装步骤小技巧 下载方法 &#xff08;一&#xff09;官网下载 1&#xff0c;进入官网&#xff1a;https://www.keil.com/。 2&#xff0c;单击“download”按钮&#xff0c;进…

如何快速解决游戏提示系统中的emp.dll缺失问题

emp.dll是一个动态链接库&#xff08;Dynamic Link Library, DLL&#xff09;文件&#xff0c;这类文件在Windows操作系统中扮演着至关重要的角色。它们包含了可由多个程序同时使用的代码和数据&#xff0c;其主要目的是实现模块化&#xff0c;以便于程序的更新和动态链接。emp…

在VMware上创建虚拟机以及安装Linux操作系统,使用ssh进行远程连接VMware安装注意点 (包含 v1,v8两张网卡如果没有的解决办法)

一&#xff0c;VMware上创建虚拟机 1.VMware下载 1&#xff09;点击VMware官网进入官网 网址:VMware by Broadcom - Cloud Computing for the EnterpriseOptimize cloud infrastructure with VMware for app platforms, private cloud, edge, networking, and security.https…

语言/图像/视频模型一网打尽!BigModel大模型开放平台助力开发者轻松打造AI新应用!

2024年8⽉28⽇&#xff0c;在ACM SIGKDD&#xff08;国际数据挖掘与知识发现⼤会&#xff0c;KDD&#xff09;上会议现场&#xff0c;智谱AI重磅推出了新⼀代全⾃研基座⼤模型 GLM-4-Plus、图像/视频理解模型 GLM-4V-Plus 和⽂⽣图模型 CogView3-Plus。这些新模型&#xff0c;已…

数据驱动,漫途能耗管理系统打造高效节能新生态!

在我国能源消耗结构中&#xff0c;工业企业所占能耗比例相对较大。为实现碳达峰、碳中和目标&#xff0c;工厂需强化能效管理&#xff0c;减少能耗与成本。高效的能耗管理系统通过数据采集与分析&#xff0c;能实时监控工厂能源使用及报警情况&#xff0c;为节能提供数据。构建…

梦熊十三连测题解

加减乘除 1.通过造样例可知&#xff1a;注意到两类操作并不会改变单调性&#xff0c;即对于任意 x≤y&#xff0c;在操作后仍然满足 x≤y。 2.所以我们就可以将原序列升序排序&#xff0c;分别通过二分找出最大和最小的下标。 3.时间复杂度&#xff1a;O(n*)。 代码如下&am…

android11 usb摄像头添加多分辨率支持

部分借鉴于&#xff1a;https://blog.csdn.net/weixin_45639314/article/details/142210634 目录 一、需求介绍 二、UVC介绍 三、解析 四、补丁修改 1、预览的限制主要存在于hal层和framework层 2、添加所需要的分辨率&#xff1a; 3、hal层修改 4、frameworks 5、备…

漏洞挖掘JS构造新手向

前置思路文章 JS逆向混淆前端对抗 油猴JS逆向插件 JS加解密之mitmproxy工具联动Burp JS挖掘基础 伪协议 JavaScript伪协议是一种在浏览器中模拟网络请求的方法。它使用window.XMLHttpRequest对象或fetch()方法来模拟发送HTTP请求&#xff0c;而不是通过实际的网络请求来获…

【H2O2|全栈】JS入门知识(五)

目录 JS 前言 准备工作 数组API&#xff08;一&#xff09; API概念 数组常见API&#xff08;一&#xff09; arguments 作用域 概念 全局作用域 局部作用域 块级作用域 变量的作用域 作用域链 案例 预解析 概念 变量预解析 函数预解析 案例 对象 概念 …

MySQL 异常: “Host ‘xxx‘ is not allowed to connect to this MySQL server“

update user set host % where user root; FLUSH PRIVILEGES; 这两行代码就行

Mysql 和MongoDB用户访问权限问题

Mysql 刚给二线运维排查了一个问题&#xff0c;Mysql安装完可用&#xff0c;且可用navicat连接&#xff0c;项目中通过127.0.0.1去连数据库报错了。错误是access denied for user ‘root’localhost,排查思路 1. 密码是否正确 &#xff08;不需要重置。到Mysql的安装目录下找…