初识vue3

对vue3的理解

  • 2020年9月发布的正式版
  • vue3支持大多数的Vue2的特性
  • Vue中设计了一套强大的组合APi代替了Vue2中的option API,复用性更强了
  • 更好的支持TS
  • 最主要:Vue3中使用了Proxy配合Reflect代替了Vue2中Object.defineProperty()方法实现数据的响应式(数据代理)
  • 重写了虚拟DOM,速度更快了
  • 新的组件:Fragment(片段)/ Teleport(瞬移) / Suspense(不确定)
  • 设计了一个新的脚手架工具,vite

vue3为什么可以使用多个组件,好处是什么

在vue3中:组件可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中
好处:减少标签层级,减少内存占用

setup

- setup中的返回值是一个对象,内部的属性和方法是给html模板使用的
- setup中的对象中的方法会和data函数中的都会像中的属性合并为组件对象的方法
- setup不能是一个async函数:因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性数据
 【注意】 在Vue3中尽量不要混合的使用data和setup及methods和setup

参数:props 、context

  • props 是响应式的,当传入新的 prop 时,它将被更新。、

【注意】因为 props 是响应式的,你不能使用 ES6 解构,它会消除 prop 的响应性

如果需要解构 prop,可以在 setup 函数中使用 toRefs 函数来完成此操作

不确定的props属性,用toRef
const title = toRef(props,'title')

  • context 是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对 context 使用 ES6 解构
// 暴露三个 property
export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)

    // 插槽 (非响应式对象)
    console.log(context.slots)

    // 触发事件 (方法)
    console.log(context.emit)
  }
}

访问组件的 property

执行 setup 时,组件实例尚未被创建。因此,你只能访问以下 property

  • props
  • attrs
  • slots
  • emit

setup中的this

this是undefined

setup是在beforeCreate生命周期回调之前就执行了,而且就执行一次由此可以推断setup在执行的时候,当前的组件还没有创建出来,也就意味着,组件实例对象this根本就不能使用

ref

  • ref是一个函数:定义一个响应式的数据,返回的是一个ref对象,对中有一个value属性,如果需要对数据进行操作,需要使用ref对象调用value属性的方式进行数据操作

  • html模板中是不需要使用 .value写法的

  • 一般定义一个基本类型的响应式数据,换句话说,ref 为我们的值创建了一个响应式引用

      如果用ref(对象/数组),内部会自动将对象/数组转换为reactive的代理对象
      ref内部:通过给value属性添加getter和setter来实现数据的劫持
    
  • 放到标签上可以用来获取dom <p ref="aaa">得到我</p>

reactive

  • 返回一个返回的是一个proxy代理对象
  • reactive内部:通过Proxy来实现对对象内部所有数据的劫持,并通过Reflect操作对象内部数据

计算属性和监听属性

computed

【注意】 vue3中没有filters,可以用computed和watch代替
两种写法

  • 只读不能修改

     接受一个 getter 函数,并为从 getter 返回的值返回一个不变的响应式 ref 对象。
    
const count = ref(1)
const plusOne = computed(() => count.value + 1)

console.log(plusOne.value) // 2

plusOne.value++ // 错误
  • 可读可修改

    使用具有 get 和 set 函数的对象来创建可写的 ref 对象。
    
const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: val => {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) // 0

watch

  - 三个参数
	- 1,可以直接写被监听的值,也可以是返回值的 getter 函数
	- 2, 回调函数,有旧值和新值两个参数
	- 3,一个对象(可选) {immediate: true, deep: true}

与 watchEffect 比较,watch 允许我们:

1, 懒执行副作用;
2,更具体地说明什么状态应该触发侦听器重新运行;
3,访问侦听状态变化前后的值。

监听单个数据源

const num = ref(0)
  watch(
			() => num,
      // 或者直接写 num
      // 当值为复合数据类型时这些值是响应式的,要求它有一个由值构成的副本 
      // 例:nums=reactive([1,2,3,4])    () => [...nums],
			(newValues, prevValues) => {
				console.log(newValues, prevValues)
			}
		)

监听多个数据源

const firstName = ref('');
const lastName = ref('');

watch([firstName, lastName], (newValues, prevValues) => {
  console.log(newValues, prevValues);
})

firstName.value = "John"; // logs: ["John",""] ["", ""]
lastName.value = "Smith"; // logs: ["John", "Smith"] ["John", ""]

watchEffect

const count = ref(0)

watchEffect(() => console.log(count.value))
// -> logs 0

setTimeout(() => {
  count.value++
  // -> logs 1
}, 100)

-----------副作用,停止侦听,清除副作用,副作用刷新时机,侦听器调试还不懂------------

爷孙级组件传递

provide 进行传递
	inject 进行接收
let color = ref('red')
爷组件 provide{"color":color}
孙组件 inject('color')

响应式数据判断的方法

  • isRef:检测一个值是否为一个ref对象
  • isReactive:检测一个对象是否由reactive创建的响应式代理
  • isReadonly:检测一个对象是否是由readonly创建的制度代理
  • isProxy:检查一个对象是否是由reactive或者readonly方法创建的代理
		console.log(isRef(ref()))    
		console.log(isReactive(reactive({})))
		console.log(isReadonly(readonly({})))
		console.log(isProxy(reactive({})))
		console.log(isProxy(readonly({})))

customRef

  创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。
<template>
	<input type="text" v-model="keyword" />
	<h1>{{ keyword }}</h1>
</template>

<script>
import { customRef } from 'vue'
export default {
	setup() {
		// 自定义hook防抖的函数
		function useDebouncedRef(value, delay = 200) {
			// 准备一个存储定时器的id的变量
			let timeOutId
			return customRef((track, trigger) => {
				return {
					get() {
						track()
						return value
					},
					set(newValue) {
						clearTimeout(timeOutId)
						timeOutId = setTimeout(() => {
							value = newValue
							trigger()
							return value
						}, delay)
					},
				}
			})
		}
		const keyword = useDebouncedRef('a11aa', 500)

		return {
			keyword,
		}
	},
}
</script>
上一篇:别再轻易说会自动化了,99%测试人还不会用nose进行自动化测试


下一篇:python 打包wheel文件,自己的SDK包