vue3的基本使用

1、简介

2020年9月18日,vue.js发布3.0版本,代号One Piece(海贼王)

2、vue3带来了什么

1、性能的提升
打包大小减少41%
初次渲染快55%,更新渲染快133%
内存减少54%

2、源码的升级
使用proxy代替defineProperty实现响应式
重写了虚拟Dom实现和Tree-shaking

3、拥抱了TypeScript

4、新的特性

1、 组合api compositionAPI

  1. setup设置

  2. ref与reactive

  3. watch与watchEffect

  4. provide与inject
    2、新的组件内置

  5. Fragment

  6. Teleport

  7. Suspense
    3、其他改变
    新的生命周期钩子
    data选择应始终声明为一个函数
    移除keycode支持作为v-on的修饰符

一、创建vue3.0工程

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、常用Composition API

1、初时setup

在这里插入图片描述

<template>
<!-- vue3的组件结构可以没有根标签 -->
  <h1>我的个人信息</h1>
  <h2>{{name}}</h2>
  <h2>{{age}}</h2>
  <button style="width:80px;height:40px;border-radius:5px" @click="sayHello">点击我</button>
</template>

<script>
export default {
  name: 'App',  
  setup(){
    let name='zhangjing'
    let age =18
    function sayHello(){
      alert(`你好呀,我叫${name},年龄${age}`)
    }
   return {
    name,
    age,
    sayHello
   }
  }
}
</script>

在这里插入图片描述

<template>
  <h1>我的个人信息</h1>
  <!-- <h2>{{name}}</h2>
  <h2>{{age}}</h2> -->
  <!-- <button style="width:80px;height:40px;border-radius:5px" @click="sayHello">点击我</button> -->
</template>

<script>

import {h} from 'vue'

export default {
  name: 'App',
  //此处只是测试setup暂时不考虑响应式的问题
  setup(){
    // let name='zhangjing'
    // let age =18
    // function sayHello(){
    //   alert(`你好呀,我叫${name},年龄${age}`)
    // }

//返回一个对象(常用)
  //  return {
  //   name,
  //   age,
  //   sayHello
  //  }
  
  //返回一个函数(渲染函数),将上面内容替换了
  return ()=>
     h('h2','我的名字')
  
  }
}
</script>

<style>

</style>

此处没有展示我的个人信息字样
在这里插入图片描述

2、ref函数处理基本数据类型

在这里插入图片描述

控制台已经打印出数据,但是页面没变化

<template>
  <h1>我的个人信息</h1>
  <h2>{{ name }}</h2>
  <h2>{{ age }}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
export default {
  name: "App",
  setup() {
    let name = "zhangjing";
    let age = 18;
    function addInfo(){
      name='张静'
      age=20
      console.log(name,age)
    }
    
    return {
      name,
      age,
      addInfo
    };
  },
};
</script>

<style>
</style>

在这里插入图片描述

<template>
  <h1>我的个人信息</h1>
  <!--   vue3解析发现name是ref对象,则自动的读取了value的值 -->
  <h2>{{ name }}</h2>
  <h2>{{ age }}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
import {ref} from 'vue'
export default {
  name: "App",
  setup() {
    //想把一个普通数据变成响应式,就必须使用ref
    let name = ref("zhangjing")
    let age = ref(18)
    function addInfo(){
      // name='张静'
      // age=20
      name.value='张静'
      age.value=20
      console.log(name,age)//引用实现的实例对象,简称引用对象
    }
    
    return {
      name,
      age,
      addInfo
    };
  },
};
</script>

<style>
</style>

在这里插入图片描述

ref函数处理引用数据类型

<template>
  <h1>我的个人信息</h1>
  <!--   vue3解析发现name是ref对象,则自动的读取了value的值 -->
  <h2>{{ name }}</h2>
  <h2>{{ age }}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
import {ref} from 'vue'
export default {
  name: "App",
  setup() {
    //想把一个普通数据变成响应式,就必须使用ref
    let name = ref("zhangjing")
    let age = ref(18)
    let job=ref({
      type:'前端工程师',
      salay:'30k'
    })
    function addInfo(){
      // name.value='张静'
      // age.value=20
      // console.log(name,age)//引用实现的实例对象,简称引用对象
      console.log(job)
      console.log(job.value)
    }
    
    return {
      name,
      age,
      addInfo
    };
  },
};
</script>

<style>
</style>

在这里插入图片描述

<template>
  <h1>我的个人信息</h1>
  <!--   vue3解析发现name是ref对象,则自动的读取了value的值 -->
  <h2>{{ name }}</h2>
  <h2>{{ age }}</h2>
  <h2>{{job.type}}</h2>
  <h2>{{job.salay}}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
import {ref} from 'vue'
export default {
  name: "App",
  setup() {
    //想把一个普通数据变成响应式,就必须使用ref
    let name = ref("zhangjing")
    let age = ref(18)
    let job=ref({
      type:'前端工程师',
      salay:'30k'
    })
    function addInfo(){
      // name.value='张静'
      // age.value=20
      // console.log(name,age)//引用实现的实例对象,简称引用对象
      console.log(job)
      console.log(job.value)
      job.value.type='软件开发工程师'
      job.value.salay='35k'
    }
    
    return {
      name,
      age,
      addInfo,
      job
    };
  },
};
</script>

<style>
</style>

在这里插入图片描述

3、reactive函数

在这里插入图片描述

<template>
  <h1>我的个人信息</h1>
  <!--   vue3解析发现name是ref对象,则自动的读取了value的值 -->
  <h2>{{ name }}</h2>
  <h2>{{ age }}</h2>
  <h2>{{job.type}}</h2>
  <h2>{{job.salay}}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
import {ref,reactive} from 'vue'
export default {
  name: "App",
  setup() {
    //想把一个普通数据变成响应式,就必须使用ref
    let name = ref("zhangjing")
    let age = ref(18)
    let job=reactive({
      type:'前端工程师',
      salay:'30k'
    })
    function addInfo(){
      // name.value='张静'
      // age.value=20
      // console.log(name,age)//引用实现的实例对象,简称引用对象
      console.log(job)
      // console.log(job.value)
      // job.value.type='软件开发工程师'
      // job.value.salay='35k'
      job.type='后端开发工程师'
      job.salay='36k'
      console.log(job)
    }
    
    return {
      name,
      age,
      addInfo,
      job
    };
  },
};
</script>

<style>
</style>

在这里插入图片描述
对象嵌套对象也是可以监听到的

<template>
  <h1>我的个人信息</h1>
  <!--   vue3解析发现name是ref对象,则自动的读取了value的值 -->
  <h2>{{ name }}</h2>
  <h2>{{ age }}</h2>
  <h2>{{job.type}}</h2>
  <h2>{{job.salay}}</h2>
  <h2>{{job.a.b.c}}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
import {ref,reactive} from 'vue'
export default {
  name: "App",
  setup() {
    //想把一个普通数据变成响应式,就必须使用ref
    let name = ref("zhangjing")
    let age = ref(18)
    let job=reactive({
      type:'前端工程师',
      salay:'30k',
      a:{
        b:{
          c:666
        }
      }
    })
    function addInfo(){
      // name.value='张静'
      // age.value=20
      // console.log(name,age)//引用实现的实例对象,简称引用对象
      console.log(job)
      // console.log(job.value)
      // job.value.type='软件开发工程师'
      // job.value.salay='35k'
      job.type='后端开发工程师'
      job.salay='36k'
      job.a.b.c=888
      console.log(job)
    }
    
    return {
      name,
      age,
      addInfo,
      job
    };
  },
};
</script>

<style>
</style>

在这里插入图片描述
数组也可通过reactive变成响应式的

<template>
  <h1>我的个人信息</h1>
  <!--   vue3解析发现name是ref对象,则自动的读取了value的值 -->
  <h2>{{ name }}</h2>
  <h2>{{ age }}</h2>
  <h2>{{job.type}}</h2>
  <h2>{{job.salay}}</h2>
  <h2>{{job.a.b.c}}</h2>
  <h2>{{hobby}}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
import {ref,reactive} from 'vue'
export default {
  name: "App",
  setup() {
    //想把一个普通数据变成响应式,就必须使用ref
    let name = ref("zhangjing")
    let age = ref(18)
    let job=reactive({
      type:'前端工程师',
      salay:'30k',
      a:{
        b:{
          c:666
        }
      }
    })
    let hobby=reactive(['看书','听歌','旅游'])
    function addInfo(){
      // name.value='张静'
      // age.value=20
      // console.log(name,age)//引用实现的实例对象,简称引用对象
      // console.log(job)
      // console.log(job.value)
      // job.value.type='软件开发工程师'
      // job.value.salay='35k'
      // job.type='后端开发工程师'
      // job.salay='36k'
      // job.a.b.c=888
      // console.log(job)
      console.log(hobby[0])
      hobby[0]='看电影'
      console.log(hobby[0])
    }
    
    return {
      name,
      age,
      addInfo,
      job,
      hobby
    };
  },
};
</script>

<style>
</style>

在这里插入图片描述

<template>
  <h1>我的个人信息</h1>
  <h2>{{ person.name }}</h2>
  <h2>{{ person.age }}</h2>
  <h2>{{ person.job.type }}</h2>
  <h2>{{ person.job.salay }}</h2>
  <h2>{{ person.job.a.b.c }}</h2>
  <h2>{{ person.hobby }}</h2>
  <button @click="addInfo">点击修改我的信息</button>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
  setup() {
    let person = reactive({
      name: "zhangjing",
      age: "18",
      job: {
        type: "前端工程师",
        salay: "30k",
        a: {
          b: {
            c: 666,
          },
        },
      },
      hobby: ["看书", "听歌", "旅游"],
    });

    function addInfo() {
      person.name = "张静";
      person.age = 20;
      person.job.type = "软件开发工程师";
      person.job.salay = "35k";
      person.job.a.b.c = 888;
      person.hobby[0] = "看电影";
    }
    return {
      person,
      addInfo
    };
  },
};
</script>
<style>
</style>

在这里插入图片描述
点击后效果
在这里插入图片描述

4、模拟vue3中的响应式

在这里插入图片描述

在这里插入图片描述
实际上用的是reflect,封装框架友好
在这里插入图片描述
在这里插入图片描述

5、reactive对比ref

在这里插入图片描述

6、setup的两个注意点

在这里插入图片描述
第一个参数 setup里面的第一个参数props
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
attrs

<template>
  <h1>我的个人信息</h1>
  <h2>{{ person.name }}</h2>
  <h2>{{ person.age }}</h2>
 
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
//   props:['msg','school'],
  //setup只能收到两个参数
  setup(props,context) {
    
    console.log('------------',context)
    console.log(context.attrs)
    let person = reactive({
      name: "zhangjing",
      age: "18",
    
    });

    return {
      person,
      
    };
  },
};
</script>

在这里插入图片描述
在这里插入图片描述
此时没有使用props,所以arrs里面有值
在这里插入图片描述
contxt.emit的使用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
context.slots
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

7、computed计算属性

1、计算属性与监视

在这里插入图片描述

vue2的写法如下图所示,能实现,但不建议这么使用

Demo.vue
<template>
  姓:<input v-model="person.firstName" />
  <br />
  名:<input v-model="person.lastName" />
  <br/>
  <span>全名:{{fullName}}</span>
</template>
<script>
import { reactive } from "vue";
export default {
  name: "App",
  computed: {
    //vue2中是可以用vue3中的属性的,要使用this
    fullName() {
      return this.person.firstName + this.person.lastName;
    },
  },
  setup() {
    let person = reactive({
      firstName: "张",
      lastName: "三",
    });
    return {
      person,
    };
  },
};
</script>
App.vue
<template>
  <Demo /> 
</template>
<script>
import Demo from "./components/Demo.vue";

export default {
  components: { Demo },
  name: "App",
};
</script>

在这里插入图片描述


下面是vue3的写法

Demo.vue
<template>
  姓:<input v-model="person.firstName" />
  <br />
  名:<input v-model="person.lastName" />
  <br/>
  <span>全名:{{fullName}}</span>
</template>
<script>
import { reactive ,computed} from "vue";
export default {
  name: "App",
//   //vue2的用法,不建议使用
//   computed: {
//     //vue2中是可以用vue3中的属性的,要使用this
//     fullName() {
//       return this.person.firstName + this.person.lastName;
//     },
//   },
  setup() {
    //数据
    let person = reactive({
      firstName: "张",
      lastName: "三",
    });
    //计算属性
    let fullName=computed(()=>{
        return person.firstName+person.lastName
    })
    return {
      person,
      fullName
    };
  },
};
</script>
App.vue
<template>
  <Demo /> 
</template>
<script>
import Demo from "./components/Demo.vue";

export default {
  components: { Demo },
  name: "App",
};
</script>

在这里插入图片描述


vue3这么写,全名这个属性直接添加到person这个对象上,用的reative是响应式的可以直接追加

<template>
  姓:<input v-model="person.firstName" />
  <br />
  名:<input v-model="person.lastName" />
  <br />
  <span>全名:{{ person.fullName }}</span>
</template>
<script>
import { reactive, computed } from "vue";
export default {
  name: "App",
  setup() {
    //数据
    let person = reactive({
      firstName: "张",
      lastName: "三",
    });
    //计算属性
    //简写,没有考虑计算属性被修改的情况
    person.fullName = computed(() => {
      return person.firstName + person.lastName;
    });
    return {
      person,
    };
  },
};
</script>

在这里插入图片描述

2、 watch函数的使用

在这里插入图片描述

App.vue
<template>
  <Demo /> 
</template>
<script>
import Demo from "./components/Demo.vue";

export default {
  components: { Demo },
  name: "App",
};
</script>

Demo.vue
<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我加1</button>
  <h2>当前信息为:{{ msg }}</h2>
  <button @click="msg += '!'">修改信息</button>
  <br />
  <h2>{{ person.name }}</h2>
  <h2>{{ person.age }}</h2>
  <button @click="person.name += '!'">修改姓名</button>
  <button @click="person.age++">增长年龄</button>
  <br />
  <h2>薪水:{{ person.job.j1.salary }}k</h2>
  <button @click="person.job.j1.salary++">涨薪水了</button>
</template>
<script>
import { ref, reactive, watch } from "vue";
export default {
  name: "App",
  //vue2的简单写法
  //   watch: {
  //     // sum(newValue, oldValue) {
  //     //   console.log("sum的值变化了",newValue,oldValue);
  //     // },
  //     sum: {
  //       immediate: true, //立即监听
  //       deep:true,//深度监视,默认是浅层次的监视
  //       handler(newValue, oldValue) {
  //         console.log("sum的值变化了", newValue, oldValue);
  //       },
  //     },
  //   },
  setup() {
    let sum = ref(0);
    let msg = ref("你好");
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    //vue3
    // 情况一:监视ref所定义的一个响应式数据
    // watch(sum, (newValue, oldValue) => {
    //   console.log("sum的值变化了", newValue, oldValue);
    // },{immediate:true}); //第三个函数可以写immediate和deep

    //情况二:监视ref所定义的多个响应式数据
    // watch([sum, msg], (newValue,oldValue) => {
    //   console.log(newValue,oldValue);
    //   //[1,'你好'][0,'你好']
    // },{immediate:true});

    // 情况三:监视reactive所定义的一个响应式数据的全部属性,
    // 注意:1、此处无法正确的获得oldValue,目前无法解决。
    //     2、默认开启了深度监视(deep配置无效)
    // watch(person, (newValue, oldValue) => {
    //   console.log("person变化了");
    //   console.log(newValue); //坑 新旧数据一样了欸
    //   console.log(oldValue);
    // },{deep:false});//此处的deep配置无效

    //情况四:监听reactive所定义的一个响应式数据中的某个属性(用函数形式)
    // watch(()=>person.age,(newValue,oldValue)=>{
    //     console.log('person的age变化了',newValue,oldValue) //能拿到oldValue
    // })

    //情况五:监听reactive所定义的一个响应式数据中的某些属性
    // watch([() => person.age, () => person.name], (newValue, oldValue) => {
    //   console.log("person的age或者变化了", newValue, oldValue);
    // });
    
    //特殊情况:层次比较深 注意:由于监视的是reactive所定义的对象中的某个属性,所以deep的配置有效(对比情况三监听对象的属性仍然是对象可以用deep)
    // watch(()=>person.job,(newValue,oldValue)=>{
    //     console.log('person的job变化了',newValue,oldValue)
    // },{deep:true}) //不能拿到oldValue

    return {
      sum,
      msg,
      person,
    };
  },
};
</script>


在这里插入图片描述
在这里插入图片描述
特殊情况:层级比较深得
在这里插入图片描述

watch中value值的问题

<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我加1</button>
  <h2>当前信息为:{{ msg }}</h2>
  <button @click="msg += '!'">修改信息</button>
  <br />
  <h2>{{ person.name }}</h2>
  <h2>{{ person.age }}</h2>
  <button @click="person.name += '!'">修改姓名</button>
  <button @click="person.age++">增长年龄</button>
  <br />
  <h2>薪水:{{ person.job.j1.salary }}k</h2>
  <button @click="person.job.j1.salary++">涨薪水了</button>
</template>
<script>
import { ref, watch } from "vue";
export default {
  name: "App",

  setup() {
    let sum = ref(0);
    let msg = ref("你好");
    let person = ref({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    console.log(sum);
    console.log(msg);
    console.log(person);
    // //正确写法
    // watch(sum, (newValue, oldValue) => {
    //   console.log("sum值变化了", newValue, oldValue);
    // });
    // //不对,检测是结构,不能检测0
    // watch(sum.value, (newValue, oldValue) => {
    //   console.log("sum值变化了", newValue, oldValue);
    // });
    
    //监听不到---ref生成的对象,任何属性发生变化能捕获到,value是proxy对象,只有地址变化才能检测到,改变内层数据对象不变化
    //  watch(person, (newValue, oldValue) => {
    //   console.log("person值变化了", newValue, oldValue);
    // });


    //1、监听得到---监听实例对象的 。value属性是proxy实例对象,是reactive生成的,也就是说是reactive所定义的数据,是深层次的
    // watch(person.value,(newValue, oldValue) => {
    //   console.log("person值变化了", newValue, oldValue);
    // });
    
    // 2、监听得到 person。value里面的内容能被监测到了
      watch(person,(newValue, oldValue) => {
      console.log("person值变化了", newValue, oldValue);
    },{deep:true});

    return {
      sum,
      msg,
      person,
    };
  },
};
</script>


3、watchEffect函数

在这里插入图片描述

当前求和为:{{ sum }}

setup() {
let sum = ref(0);
let msg = ref(“你好”);
let person = reactive({
name: “张三”,
age: 18,
job: {
j1: {
salary: 20,
},
},
});

// watch(person, (newValue, oldValue) => {
//   console.log("person值变化了", newValue, oldValue);
// });
watchEffect(() => {
  const x1 = sum.value;
  const x2=person.job.j1.salary
  console.log("watchEffect所指定的回调执行了",x1,x2);
});

return {
  sum,
  msg,
  person,
};

},
};

在这里插入图片描述

8、vue3的生命周期

在这里插入图片描述

beforeDestory 和destoryed变为beforeUnmount和unmounted

App.vue
<template>
  <button @click="isShow = !isShow">是否展示Demo</button>

  <Demo v-if="isShow" />
</template>
<script>
import Demo from "./components/Demo.vue";
import { ref } from "vue";
export default {
  components: { Demo },
  name: "App",
  setup() {
    let isShow = ref(true);
    return {
      isShow,
    };
  },
};
</script>
Demo.vue
<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我加1</button>
</template>
<script>
import { ref } from "vue";
export default {
  name: "demoTest",

  setup() {
    let sum = ref(0);
    return {
      sum,
    };
  },
  //通过配置项的形式使用生命周期钩子
  beforeCreate() {
    console.log("---beforeCreate---");
  },
  created() {
    console.log("---created---");
  },
  beforeMount() {
    console.log("---beforeMount---");
  },
  mounted() {
    console.log("---mounted---");
  },
  beforeUpdate() {
    console.log("---beforeUpdate---");
  },
  updated() {
    console.log("---updated---");
  },
  beforeUnmount() {
    console.log("---beforeUnmount---");
  },
  unmounted() {
    console.log("---unmounted---");
  },
};
</script>


在这里插入图片描述

同一个阶段生命周期的钩子,vue3的先执行

<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我加1</button>
</template>
<script>
import {
  ref,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onUnmounted,
  onBeforeUnmount,
} from "vue";
export default {
  name: "demoTest",

  setup() {
    console.log("--- setup  ---");
    let sum = ref(0);
    //通过组合式API的方式去使用生命周期钩子
    onBeforeMount(() => {
      console.log("--- onBeforeMount  ---");
    }),
      onMounted(() => {
        console.log("--- onMounted  ---");
      }),
      onBeforeUpdate(() => {
        console.log("--- onBeforeUpdate  ---");
      }),
      onUpdated(() => {
        console.log("--- onUpdated  ---");
      }),
      onUnmounted(() => {
        console.log("--- onUnmounted  ---");
      }),
      onBeforeUnmount(() => {
        console.log("--- onBeforeUnmount  ---");
      });

    return {
      sum,
    };
  },
  //#region
  //通过配置项的形式使用生命周期钩子
  //   beforeCreate() {
  //     console.log("---beforeCreate---");
  //   },
  //   created() {
  //     console.log("---created---");
  //   },
  //   beforeMount() {
  //     console.log("---beforeMount---");
  //   },
  //   mounted() {
  //     console.log("---mounted---");
  //   },
  //   beforeUpdate() {
  //     console.log("---beforeUpdate---");
  //   },
  //   updated() {
  //     console.log("---updated---");
  //   },
  //   beforeUnmount() {
  //     console.log("---beforeUnmount---");
  //   },
  //   unmounted() {
  //     console.log("---unmounted---");
  //   },
  //#endregion
};
</script>

9、自定义hook

在这里插入图片描述

Demo.vue
<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我加1</button>
  <hr />
  <h2>当前点击时鼠标的坐标为:x:{{ point.x }},y:{{ point.y }}</h2>
</template>
<script>
import { ref, reactive, onMounted, onBeforeUnmount } from "vue";
export default {
  name: "demoTest",
  setup() {
    let sum = ref(0);
    let point = reactive({
      x: 0,
      y: 0,
    });

    function savePoint(event) {
      point.x = event.pageX;
      point.y = event.pageY;
      console.log(event.pageX, event.pageY);
    }
    onMounted(() => {
      console.log("=");
      window.addEventListener('click', savePoint);
    });
    onBeforeUnmount(() => {
      console.log("777");
      window.removeEventListener('click', savePoint);
    });

    return {
      sum,
      point,
    };
  },
};
</script>


App.vue
<template>
  <button @click="isShow = !isShow">是否展示Demo</button>

  <Demo v-if="isShow" />
</template>
<script>
import Demo from "./components/Demo.vue";
import { ref } from "vue";
export default {
  components: { Demo },
  name: "App",
  setup() {
    let isShow = ref(true);
    return {
      isShow,
    };
  },
};
</script>

在这里插入图片描述
在这里插入图片描述

使用hook可以这么写
在这里插入图片描述

// function savePoint(){
    import {  reactive, onMounted, onBeforeUnmount } from "vue";
    export default function(){

    //实现鼠标打点的相关数据
    let point = reactive({
        x: 0,
        y: 0,
      });
  //实现鼠标打点的相关方法
      function savePoint(event) {
        point.x = event.pageX;
        point.y = event.pageY;
        console.log(event.pageX, event.pageY);
      }
      //实现鼠标打点的钩子
      onMounted(() => {
        console.log("=");
        window.addEventListener('click', savePoint);
      });
      onBeforeUnmount(() => {
        console.log("777");
        window.removeEventListener('click', savePoint);
      });
      return point
      
}
// export default savePoint

在这里插入图片描述

<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我加1</button>
  <hr />
  <h2>当前点击时鼠标的坐标为:x:{{ point.x }},y:{{ point.y }}</h2>
</template>
<script>
import { ref } from "vue";
import usePoint from "../hooks/usePoint";
export default {
  name: "demoTest",
  setup() {
    let sum = ref(0);

    let point = usePoint();
    return {
      sum,
      point
    };
  },
};
</script>


App.vue

<template>
  <button @click="isShow = !isShow">是否展示Demo</button>

  <Demo v-if="isShow" />
</template>
<script>
import Demo from "./components/Demo.vue";
import { ref } from "vue";
export default {
  components: { Demo },
  name: "App",
  setup() {
    let isShow = ref(true);
    return {
      isShow,
    };
  },
};
</script>

效果和上面的写法是一样的,可以对usePoint.js进行复用了
在这里插入图片描述

10、toRef

在这里插入图片描述

<template>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <h2>薪水:{{ person.job.j1.salary }}k</h2>
  <button @click="person.name += '!'">修改姓名</button>
  <button @click="person.age++">增长年龄</button>
  <button @click="person.job.j1.salary++">涨薪水了</button>
</template>
<script>
import { reactive, toRef } from "vue";
export default {
  name: "App",

  setup() {
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    const name1 = person.name;
    console.log("name1", name1);
    const name2 = toRef(person, "name");
    console.log("name2", name2);
    return {
      person,
      name1,
      name2,
    };
  },
};
</script>

在这里插入图片描述
toRef的使用方法

<template>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪水:{{ salary }}k</h2>
  <button @click="name += '!'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="salary++">涨薪水了</button>
</template>
<script>
import { reactive, toRef } from "vue";
export default {
  name: "App",

  setup() {
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    // console.log("person", person);
    // const name1 = person.name; //不是响应式的
    // console.log("name1", name1);
    // const name2 = toRef(person, "name"); //是响应式的,指的就是person中的name属性
    // console.log("name2", name2);
    return {
      //   person,
      //   name1,
      //   name2,
      //   name: ref(person.name),//如果这么写,初始化使用了张三,但修改时改的不是person对象里面的值
      name: toRef(person, "name"),
      age: toRef(person, "age"),
      salary: toRef(person.job.j1, "salary"),
    };
  },
};
</script>

在这里插入图片描述

<template>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪水:{{ salary }}k</h2>
  <button @click="name += '!'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="salary++">涨薪水了</button>
</template>
<script>
import { reactive, toRef,toRefs } from "vue";
export default {
  name: "App",

  setup() {
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    // console.log("person", person);
    // const name1 = person.name; //不是响应式的
    // console.log("name1", name1);
    // const name2 = toRef(person, "name"); //是响应式的,指的就是person中的name属性
    // console.log("name2", name2);
     const x=toRefs(person)//把一个对象的所有属性都变成ref形式
     console.log(x)

    return {
      //   person,
      //   name1,
      //   name2,
      //   name: ref(person.name),//如果这么写,初始化使用了张三,但修改时改的不是person对象里面的值
      name: toRef(person, "name"),
      age: toRef(person, "age"),
      salary: toRef(person.job.j1, "salary"),
    };
  },
};
</script>

在这里插入图片描述
toRefs的使用

<template>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪水:{{ job.j1.salary }}k</h2>
  <button @click="name += '!'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="job.j1.salary++">涨薪水了</button>
</template>
<script>
import { reactive,toRefs } from "vue";
export default {
  name: "App",

  setup() {
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    return {
      ...toRefs(person)
    };
  },
};
</script>

在这里插入图片描述

三、其他的composition api

1、shallowReactive和shallowRef的使用


在这里插入图片描述

<template>
  <h4>当前的x.y值是:{{ x.y }}</h4>
  <button @click="x.y++">修改x的值</button>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪水:{{ job.j1.salary }}k</h2>
  <button @click="name += '!'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="job.j1.salary++">涨薪水了</button>
</template>
<script>
import { reactive, toRefs, shallowRef } from "vue";
export default {
  name: "App",

  setup() {
    //  let person = shallowReactive({//只考虑第一层数据的响应式
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    // let x = ref(0);
    // let x=shallowRef(0)//是基本数据类型时无差别
    let x = shallowRef({//shallowRef处理对象值不好使,ref可以
      y: 0,
    });
console.log(x)
    return {
      x,
      ...toRefs(person),
    };
  },
};
</script>

在这里插入图片描述

<template>
  <h4>当前的x.y值是:{{ x.y }}</h4>
  <button @click="x.y++">修改x的值</button>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪水:{{ job.j1.salary }}k</h2>
  <button @click="name += '!'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="job.j1.salary++">涨薪水了</button>
</template>
<script>
import { reactive, toRefs, ref  } from "vue";
export default {
  name: "App",

  setup() {
    //  let person = shallowReactive({//只考虑第一层数据的响应式
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    // let x = ref(0);
    // let x=shallowRef(0)//是基本数据类型时无差别
    let x = ref({//shallowRef处理对象值不好使,ref可以
      y: 0,
    });
console.log(x)
    return {
      x,
      ...toRefs(person),
    };
  },
};
</script>


在这里插入图片描述

2、readonly与shallowReadonly

在这里插入图片描述
person这个数据不能改
person第一层的数据不能改
数据可能是别人传递的
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3、 toRaw和markRaw

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<template>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪水:{{ job.j1.salary }}k</h2>
  <h2 v-show="person.car">座驾信息:{{person.car}}</h2>
  <button @click="name += '!'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="job.j1.salary++">涨薪水了</button>
  <button  @click="addCar">配一台车</button>
   <button  @click="person.car.name+='?'">换车名</button>
    <button  @click="person.car.price++">换价格</button>
</template>
<script>
import { reactive, toRefs,markRaw} from "vue";
export default {
  name: "App",

  setup() {
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20,
        },
      },
    });

    function addCar(){
        let car ={name:'奔驰',price:'18'}
        // person.car=car //这里添加的信息会自动变成响应式的
        person.car=markRaw(car)//car永远不会成为响应式数据了,但是数据改了,只不过页面不显示而已
        
        console.log(person)
    }
    return {
        person,
      ...toRefs(person),
      addCar
    };
  },
};
</script>


在这里插入图片描述

4、customRef

在这里插入图片描述

<template>
  <input type="text" v-model="keyWord" />
  <h3>{{ keyWord }}</h3>
</template>
<script>
import { customRef } from "vue";
export default {
  name: "App",
  setup() {
    // let keyWord = ref('hello');//使用vue提供的ref
    // 自定义一个ref, 名为myRef;

    function myRef(value, delay) {
      let timer;
      console.log("---", value);
      return customRef((track, trigger) => {
        //customRef定义要传入一个函数,要返回一个对象
        return {
          get() {
            console.log(`有人从myRef这个容器中读取数据了,我把${value}给他了`);
            track(); //通知vue追踪value的变化(提前和get商量了一下,让其认为value是有用的)
            return value;
          },
          set(newValue) {
            console.log(`有人把myRef这个容器中的数据改为了${newValue}`);

            clearTimeout(timer);
            timer = setTimeout(() => {
              value = newValue;
              trigger(); //通知vue去重新解析模板
            }, delay);
          },
        };
      });
    }
    let keyWord = myRef("hello", 500);
    return {
      keyWord,
    };
  },
};
</script>

在这里插入图片描述

5、provide与inject


祖组件传值,后代组件可以接收值
在这里插入图片描述

在这里插入图片描述

6、响应式数据的判断

在这里插入图片描述

四、compositionAPI的优势

在这里插入图片描述

五、新的组件

1、Fragment组件

在这里插入图片描述

2、Teleport

在这里插入图片描述
在这里插入图片描述

3、suspense

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

这么写的话 ,蓝色组件会受到settimeout的影响
(网速慢或者说用promise都能出现加载中这个效果)
在这里插入图片描述

六、其他

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
https://www.bilibili.com/video/BV1Zy4y1K7SH?p=168&vd_source=c2279a533bc837e2d5b9ca3570c0a841
视频观看笔记

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值