setup、ref函数、reactive函数、Vue3中的响应式原理、Vue3中组件的使用、计算属性-vue3

文章目录

  • 1、setup
    • ps:
  • 2、ref函数
  • 3、reactive函数
  • 4、Vue3中的响应式原理
    • Vue3中的响应式原理
    • vue2的响应式原理
  • 5、Vue3.0中组件的使用
  • 6、计算属性

1、setup

理解:Vue3.0中一个新的配置向,值为一个函数

  • setup是所有Composition API(组合API) ”表演的舞台“

  • 组件中所有用到的:数据、方法等等,均要配置在setup中

  • setup函数的两种返回值:

  • 若返回一个对象,则对象中的数据、方法、在模板中均可直接使用(重点)

<template>  
 <div class="home">
    <h1>显示vue3.0的数据和方法</h1>
    <h2>姓名:{{name}}</h2>
    <h2>年龄:{{age}}</h2>
    <button @click="sayName()">点击测试vue3.0的方法</button>  
     </div>
      </template> 
       <script>   
       export default {   setup() {
  
    // 数据 
    let name = "hhrhr";
    let age = 18;
 
    // 方法
    let sayName = function () {
      console.log(`我的名字是${name},我的年龄是${age}`);
    }
 
    return {
      name, age, sayName
               }  
         }  
    } </script>

若返回一个渲染函数,则可以自定义渲染内容(了解)

<script>
 import {h} from 'vue' export default {   setup() {
    // 返回一个渲染函数
    // h相当于document.CreateElement()
    return ()=>{return h("h1","vue3返回渲染函数")}   } } 
</script> 

ps:

  • 尽量不要和Vue2.x配置混用
  • Vue2.x配置(data,methods,computed…)中可以访问setup中的属性,方法
  • 但在setup中不能访问到Vue2.x配置(data,methods,computed…)
  • 如有重名,setup优先
  • setup不能是一个async函数,因为返回值不再是return的对象,而是Promise,模板看不到return对象中的属性

2、ref函数

  • 作用:定义一个响应式的数据 ()
  • 语法:const xxx = ref(“value”)
    import { ref } from “vue”
    name.value = “名字”;

存值和取值都是用 点value ,但是页面使用就不用点value,直接写{{name}}

ref的返回值是一个对象,然后有个属性是value

  • 创建一个包含响应式的数据的引用对象(reference对象)
  • js中操作数据:xxx.value
  • 模板中读取数据不需要.value,直接
    {{xxx}}

可以用箭头函数,因为这里面用不到this

  • 接收的数据类型 :可以是基本数据类型 也可以是 引用数据类型
  • 基本类型的数据:响应式依然是靠Object.defineProperty()的get和set完成的
  • 对象类型的数据:内部“求助”了Vue3.0的一个新的函数------reactive函数
    ref这个响应式是怎么设计的?

就是监听了value的改变,劫持value属性的setter、getter
因此ref一般用在基本数据,或者是引用数据的嵌套层级不深的数据上
reactive也是响应式的设计,怎么设计的呢?
跟ref一样,但是底层采用的是ES6的proxy代理了整个引用数据。比起ref,它的性能更好

3、reactive函数

  • 作用:定义一个对象类型的响应式数据 (基本数据类型用ref函数)
  • 语法:const 代理一个对象 = reactive(被代理的对象) 接收一个对象(或数组),返回一个代理器对象(proxy对象)
  • reactive定义的响应式数据是“深层次的”
  • 内部基于ES6的Proxy实现,通过代理对象内部的数据都是响应式的

它就不用value了,引用数据用reactive更好,它底层不是劫持,而是代理

<script setup>
let obj = reactive({
  name: "rexhll",
  arr: [
    { name: "zwqhll",id: 1,count: 3,price: 1 },
    { name: "rwxhll",id: 2,count: 6,price: 1 },
    { name: "wlhll",id: 3,count: 9,price: 1 },
  ],
});
let total = computed(() => {
  return obj.arr.reduce((n1,n2) => {
    return n1 + n2.count * n2.price
  },0)
})
let jiajia = (index) => {
  obj.arr[index].count++
}
</script>
<template>
  <div v-for="(item, index) in obj.arr" :key="item.id">
    <div>
      <span>name:{{ item.name }}------count:{{ item.count }}----- price:{{item.price}}</span>
      <button @click="jiajia(index)"> + </button>
    </div>
  </div>
  <div>total:{{total}}</div>
</template>

4、Vue3中的响应式原理

Vue3中的响应式原理

实现原理

  • 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写,属性的添加,属性的删除等
  • 通过Reflect(反射):对被代理对象的属性进行操作
  • MDN文档中描述的Proxy与Reflect:
  • Proxy:https://developer.mozilla.org/zhCN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
  • Reflect:https://developer.mozilla.org/zhCN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
   let person = {
            name:"李国栋",
            age:18
        }
 
        let p = new Proxy(person,{
            // 读取
            get(target,proname){
                // target表示原对象  proname表示对象名
                console.log("有人读取了person上的属性",target);
                return target[proname]
            },
            // 修改或者增加
            set(target,proname,value){
                console.log("有人修改了person上的属性,我要去更新了");
                target[proname] = value
            },
            // 删除
            deleteProperty(target,proname){
                console.log("有人删除了person上面的属性,我要去调用了");
                return delete target[proname]
            },
            
        });

vue2的响应式原理

实现原理

  • 对象类型:通过Object.definedProperty()对属性的读取、修改进行拦截(数据劫持)

  • 数组类型:通过重写更新数据的一系列方法来实现拦截。(对数组的方法进行了包裹)

Object.defineProperty(data,"count",{
    get(){},
    set(){}
})

存在问题:

  • 新增属性,删除属性都不会刷新界面
  • 直接通过下标修改数组,界面不会自动更新 (可以用$set来刷新页面)

5、Vue3.0中组件的使用

App.vue

<script setup>
//Vue3.0中组件的使用案例
import Box from "./Box.vue"
</script>
<template>
	<div>
		<Box></Box>
	</div>
</template>

Box.vue

<script setup>
import {  reactive } from "vue";
let arr = reactive([{ name: "karen" }, { age: [1, 2, 3, { name: "jack" }] }]);
let fm=function(){
	console.log(obj.age[2].age[1])
	obj.age[2].age[1]=24
}
</script>
<template>
  <div>
	<h1>{{obj.age[2].age[1]}}</h1>
	<button @click="fm">点击修改obj</button>
  </div>
</template>

6、计算属性

与vue2.x中computed配置功能一致

computed比起方法,它可以缓存上一次的结果,如果下一次关于计算的东西没有变化,那它就不会重新计算,这样就不会消耗太多性能问题

<script setup>
let obj = reactive({
  name: "rexhll",
  arr: [
    { name: "zwqhll",id: 1,count: 3,price: 1 },
    { name: "rwxhll",id: 2,count: 6,price: 1 },
    { name: "wlhll",id: 3,count: 9,price: 1 },
  ],
});
let total = computed(() => {
  return obj.arr.reduce((n1,n2) => {
    return n1 + n2.count * n2.price
  },0)
})
let jiajia = (index) => {
  obj.arr[index].count++
}
</script>
<template>
  <div v-for="(item, index) in obj.arr" :key="item.id">
    <div>
      <span>name:{{ item.name }}------count:{{ item.count }}----- price:{{item.price}}</span>
      <button @click="jiajia(index)"> + </button>
    </div>
  </div>
  <div>total:{{total}}</div>
</template>

你可能感兴趣的:(vue3,javascript,vue.js,前端)