.让数据变成响应式,即改变会引发视图层的变化
.ref通过给value属性设置setter和getter实现数据劫持
.使我们能创造一种任意值的 “引用” 并能够不丢失响应性地随意传递

使用
	import { ref } from 'vue'
	
	setup(){
		const xx =ref(初始值)   无初始值设置为null,返回一个Ref对象,即reference引用对象
			如果传入.value赋值的是对象,将自动调用reactive方法进行深层响应转换,在模板中需要{{xx.属性}}调用,不需要xx.value.属性		
			
	
		(1)调用
			xx.value
		
		(1.5)响应性语法糖调用(试验阶段)
			let count = $ref(0)
			之后的操作都不需要.value,直接操作count就行
			
		(2)自动解套(即不需要xx.value获取值)
			1、在setup的return{xx}中,在template中直接{{xx}},模板会自动加上.value
				.深层次依旧需要.value
				
				如:
					setup(){
						let conut =ref(0)
						let isActive=ref(true)
						let hasError=ref(false)
						
						return {
							nested:{
								count,
								isActive,
								hasError
							}
						}
					}
					{{count}}
					:class="{ active: isActive, 'text-danger': hasError }"
					
			2、在reactive定义的对象属性中
				.shallowReactive浅层响应式中不会
				
				const x=ref(xx) 
				const xxx=reactive({x})
				xxx.x调用
				
			3、通过reactive对象调用属性赋值ref的形式,也会自动解套
				.shallowReactive浅层响应式中不会

				const xx=reactive({x})
				xx.x=ref(xxx)
				xx.x直接调用,新赋值后的ref与旧ref没有任何关系了
				
		(2.4)集合、数组中不能自动解套
			const books = reactive([ref('Vue 3 Guide')])
			console.log(books[0].value)
			
			const map = reactive(new Map([['count', ref(0)]]))
			console.log(map.get('count').value)
	
		
		(2.5)和reactive代理对象的源属性连接
			当ref(reactive属性),返回的内容和源属性无连接,即修改不影响reactive代理的属性
			但使用toRef(reactive,属性),返回的内容会保持对其源 property 的响应式连接,即双方修改都会相互影响
		
		(2.8)和reactive的响应式区别
			(1)直接替换是响应式的
				const objectRef = ref({ count: 0 })
				objectRef.value = { count: 1 }

			(2)解构赋值是响应式的
				const obj = {
				  foo: ref(1),
				  bar: ref(2)
				}
				callSomeFunction(obj.foo)
				const { foo, bar } = obj

				
		(3)获取dom的ref
			当使用组合式 API 时,reactive refs 和 template refs 的概念已经是统一的
				setup(){
					let x=ref(null);
					
					获取dom,必须在组件挂载后才能获得
						onMounted(()=>{
							x.value
						})
					
					return{
						x
					}
				}
			在template中
				<标签 ref='x'></标签>
			在渲染函数中
				return () =>
			      h('div', {
			        ref: root
			      })
			在jsx中	
				return () => <div ref={root} />
				
		(4)使用模板语法遍历获取dom
		
			 template中:
				 <li v-for='(item,index) in 3' :key=index :ref="el=>{divs[index]=el}">
			          {{item}}
			      </li>
			     或:
			     <li v-for='(item,index) in 3' :key=index :ref="divs">
			          {{item}}
			      </li>

			      
			 setup中:
				const divs = ref([])
				组件挂载后,即能通过divs.value获取遍历元素的所有dom
				return{
					divs
				}
	}

类型声明:
	Ref对象:
		interface Ref<T> {
		  value: T
		}
	ref函数:
		function ref<T>(value: T): Ref<T>
类型约束:
	const foo = ref<string | number>('foo')
	未知类型:
	function useState<T>(initial: T) {
	  const state = ref(initial) as Ref<T> 
	  return state
	}

代码示例:

<template>
  <div>
      <img src="./logo.png">
    <h1>Hello Vue 3!</h1>
    {{name}}
    <button @click="inc">Clicked {{ count }} times.</button>
		
	<ul>
      <li v-for='(item,index) in 3' :key=index :ref="el=>{divs[index]=el}">
          {{item}}
      </li>
    </ul>
    
  </div>

</template>

<script>
import { ref,reactive } from 'vue'

export default {
  setup() {
    let count = ref(0)
    let name = ref('jeff')

    let msg=reactive({count})
	const divs = ref([])
	
	onMounted(()=>{
      console.log(divs.value[0])
    })
    
    const inc = () => {
      count.value++
      console.log(msg.count); //在reactive对象中,会被自动解套

      msg.count=name;
      console.log(msg.count) //通过reactive对象调用属性赋值ref的形式,也会自动解套


    }

    return {
      count,
      inc,
      name, //在setup返回对象中自动解套
      divs
    }
  }
}
</script>

<style scoped>
img {
  width: 200px;
}
h1 {
  font-family: Arial, Helvetica, sans-serif;
}
</style>

Logo

前往低代码交流专区

更多推荐