VUE3.0知识点

目录

1. vue3.0基本介绍

了解框架优点特点

2.setup组合api

3.组合API-setup函数

4.组合API-reactive函数

5.组合API-ref函数

6.组合API-reactive和ref的选择

7.组合API-toRefs函数

8.组合API-computed函数

9.组合API-watch函数

10.组合API-生命周期函数

11.组合API-父子通讯

12.组合API-provide和inject函数

13.组合API-ref属性

14.总结


1. vue3.0基本介绍

了解框架优点特点

  1. 首次渲染更快
  2. diff算法更快
  3. 内存占用更少
  4. 打包体积更小
  5. 更好的Typescript支持
  6. Composition API组合API

2.setup组合api

data methods是选项API,写在setup里面就是组合api

1.vue2实现

<template>
  <button @click="toggle">显示隐藏图片</button>
  <img v-show="show" alt="Vue logo" src="./assets/logo.png" />
  <hr />
  计数器:{{ count }} <button @click="increment">累加</button>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      show: true,
      count: 0,
    };
  },
  methods: {
    toggle() {
      this.show = !this.show;
    },
    increment() {
      this.count++;
    },
  },
};
</script>

2.组合API实现

<template>
  <button @click="toggle">显示隐藏图片</button>
  <img v-show="show" alt="Vue logo" src="./assets/logo.png" />
  <hr />
  计数器:{{ count }} <button @click="increment">累加</button>
</template>

<script>
import { ref } from 'vue';
export default {
  name: "App",
  setup () {
    // 显示隐藏
    const show = ref(true)
    const toggle = () => {
      show.value = !show.value
    }
    // 计数器
    const count = ref(0)
    const increment = () => {
      count.value ++
    }

    return { show, toggle, count, increment }
  }
};
</script>

3.复用逻辑

<template>
  <button @click="toggle">显示隐藏图片</button>
  <img v-show="show" alt="Vue logo" src="./assets/logo.png" />
  <hr />
  计数器:{{ count }} <button @click="increment">累加</button>
  <hr />
  计数器:{{ count1 }} <button @click="increment1">累加</button>
</template>

<script>
import { ref } from "vue";
// 逻辑抽离
const useCounter = () => {
  const count = ref(0);
  const increment = () => {
    count.value++;
  };
  return { count, increment };
};
export default {
  name: "App",
  setup() {
    // 显示隐藏
    const show = ref(true);
    const toggle = () => {
      show.value = !show.value;
    };

    // 逻辑复用
    const { count, increment } = useCounter();
    const { count: count1, increment: increment1 } = useCounter();

    return { show, toggle, count, increment, count1, increment1 };
  },
};
</script>

总结:体会组合API对逻辑复用和代码维护支撑。

3.组合API-setup函数

  • setup是一个新的配置选项,它是一个函数,该函数是组合API的入口函数
  • setup函数只会在组件初始化执行一次,且在beforeCreate生命周期函数之前执行
<template>
  <div>根组件</div>
</template>

<script>
export default {
  name: "App",
  setup() {
    // 组合API入口函数
    console.log("setup执行了");
    console.log(this);
  },
  beforeCreate() {
    console.log("beforeCreate执行了");
    console.log(this);
  },
};
</script>

总结:setup在beforeCreate之前执行,函数内this是undefined不是组件实例

4.组合API-reactive函数

掌握:使用reactive函数把普通对象转换成响应式数据

使用步骤:

  1. 从vue中导出reactive函数
  2. 在setup函数中,使用reactive函数,传入一个普通对象,返回一个响应式数据对象
  3. 最后setup函数返回一个对象,包含该响应式对象即可,模板中可使用
<template>
  <div>
    <p>姓名:{{state.name}}</p>
    <p>年龄:{{state.age}} <button @click="state.age++">一年又一年</button></p>
  </div>
</template>

<script>
// 1. 导入函数
import { reactive } from "vue"; 
export default {
  name: "App",
  setup() {
    // 2. 创建响应式数据对象
    const state = reactive({ name: 'tom', age: 18 })
    // 3. 返回数据
    return { state }
  }
};
</script>

总结:

  • 使用reactive传入普通对象可以转换成响应式对象
  • 可以转换简单数据吗?不能

5.组合API-ref函数

掌握:使用ref函数创建响应式数据

使用步骤:

  1. 从vue中导出ref函数
  2. 在setup函数中,使用ref函数,传入一个普通数据(简单or复杂),返回一个响应式数据
  3. 最后setup函数返回一个对象,包含该响应数据即可
  4. 注意:使用ref创建的数据,js中需要 .valuetemplate中可省略
<template>
  <div>
    <p>
      计数器:{{ count }}
      <button @click="count++">累加1</button>
      <!-- template中使用可省略.value -->
      <button @click="increment">累加10</button>
    </p>
  </div>
</template>

<script>
// 1. 导入函数
import { ref } from "vue";
export default {
  name: "App",
  setup() {
    // 2. 创建响应式数据对象
    const count = ref(0);
    const increment = () => {
      // js中使用需要.value
      count.value += 10;
    };
    // 3. 返回数据
    return { count, increment };
  },
};
</script>

总结:ref可以把简单数据或者复杂数据转换成响应式数据,注意加上 .value,模板可以省略

6.组合API-reactive和ref的选择

知道:在定义响应式数据的时候如何选择reactive和ref

开始分析:

  • ​​​reactive 可以转换对象成为响应式数据对象,但是不支持简单数据类型
  • ref 可以转换简单数据类型为响应式数据对象,也支持复杂数据类型,但是操作的时候需要 .value
  • 们各有特点,现在也没有最佳实践,没有明显的界限,所有大家可以自由选择

推荐用法:

如果能确定数据是对象且字段名称也确定,可使用 reactive 转成响应式数据,其它一概使用 ref 函数

 // 1. 明确表单对象有两个字段
    const form = reactive({
      username: '',
      password: ''
    })

    // 2. 后台返回的数据对象
    const data = ref(null)
    const res = await axios.get('/user/100')
    data.value = res.data

总结:在定义响应式数据的函数选择上,遵循:确定字段的对象使用 reactive 其他都使用 ref 函数

7.组合API-toRefs函数

掌握:在使用reactive创建的响应式数据被展开或解构的时候使用toRefs保持响应式

大致步骤:

  1. 使用 reactive 创建响应式数据,踩坑
  2. 使用 toRefs 处理响应式数据,爬坑
  3. toRefs 函数的作用,与使用场景
  • 基础案例
<template>
  <div>
    <p>姓名:{{ user.name }}</p>
    <p>年龄:{{ user.age }} <button @click="user.age++">一年又一年</button></p>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
  setup() {
    const user = reactive({ name: "tom", age: 18 });
    return { user };
  },
};
</script>
  • 使用 reactive 创建响应式数据,踩坑
<template>
  <div>
+    <p>姓名:{{ name }}</p>
+    <!-- 响应式丢失 -->
+    <p>年龄:{{ age }} <button @click="age++">一年又一年</button></p>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
  setup() {
    const user = reactive({ name: "tom", age: 18 });
+    return { ...user };
  },
};
</script>
  • 使用 toRefs 处理响应式数据,爬坑
+import { reactive, toRefs } from "vue";
export default {
  name: "App",
  setup() {
    const user = reactive({ name: "tom", age: 18 });
+    // 展开前使用 toRefs 处理    
+    return { ...toRefs(user) };
  },
};

toRefs   函数的作用,与使用场景

  • 作用:把对象中的每一个属性做一次包装成为响应式数据
  • 响应式数据展开的时候使用,解构响应式数据的时候使用

总结:当解构和展开reactive的响应式数据对象使用toRefs保持响应式

8.组合API-computed函数

掌握:使用computed函数定义计算属性

大致步骤:

  1. 从vue中导出 computed 函数
  2. 在setup函数中,使用computed函数,传入一个函数,函数返回计算好的数据
  3. 最后setup函数返回一个对象,包含该计算属性数据即可,然后模板内使用
<template>
  <div>
    <p>分数:{{ scoreList }}</p>
    <p>优秀:{{ betterList }}</p>
  </div>
</template>

<script>
import { ref, computed } from "vue";
export default {
  name: "App",
  setup() {
    const scoreList = ref([80, 100, 90, 70, 60]);
    // 计算属性
    const betterList = computed(() =>
      scoreList.value.filter((item) => item >= 90)
    );

    // 改变数据,计算属性改变
    setTimeout(() => {
      scoreList.value.push(92, 66);
    }, 3000);

    return {
      scoreList,
      betterList,
    };
  },
};
</script>

 总结:使用computed定义计算属性,场景:当需要依赖一个数据得到新的数据使用计算属性

9.组合API-watch函数

掌握:使用watch函数监听数据的变化

大致内容:

  • 使用 watch 监听一个响应式数据
  • 使用 watch 监听多个响应式数据
  • 使用 watch 监听响应式对象中的一个属性(简单)
  • 使用 watch 监听响应式对象数据中的一个属性(复杂),配置深度监听
  • 使用 watch 监听,配置默认执行

  • 使用 watch 监听一个响应式数据
<template>
  <p>计数器:{{ count }}</p>
</template>

<script>
import { ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    const count = ref(0);
    // 1. 监听一个响应式数据
    // watch(数据, 改变后回调函数)
    watch(count, () => {
      console.log("count改变了");
    });
    // 2s改变数据
    setTimeout(() => {
      count.value++;
    }, 2000);
    return { count };
  },
};
</script>
  • 使用 watch 监听多个响应式数据
<template>
  <p>计数器:{{ count }}</p>
  <p>
    姓名:{{ user.name }} 性别:{{ user.info.gender }} 年龄:{{ user.info.age }}
  </p>
</template>

<script>
import { reactive, ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    const count = ref(0);
    const user = reactive({
      name: "tom",
      info: {
        gender: "男",
        age: 18,
      },
    });
    // 2. 监听多个响应式数据
    // watch([数据1, 数据2, ...], 改变后回调函数)
    watch([count, user], () => {
      console.log("数据改变了");
    });
    // 2s改变数据
    setTimeout(() => {
      count.value++;
    }, 2000);
    // 4s改变数据
    setTimeout(() => {
      user.info.age++;
    }, 4000);
    return { count, user };
  },
};
</script>
  • 使用 watch 监听响应式对象数据中的一个属性(简单)
<template>
  <p>
    姓名:{{ user.name }} 性别:{{ user.info.gender }} 年龄:{{ user.info.age }}
  </p>
</template>

<script>
import { reactive, watch } from "vue";
export default {
  name: "App",
  setup() {
    const user = reactive({
      name: "tom",
      info: {
        gender: "男",
        age: 18,
      },
    });
    // 3. 监听响应式对象数据的一个数据,简单类型
    // watch(()=>数据, 改变后回调函数)
    watch(()=>user.name, () => {
      console.log("数据改变了");
    });
    // 2s改变数据
    setTimeout(() => {
      user.name = 'jack';
    }, 2000);
    // 4s改变数据
    setTimeout(() => {
      user.info.age = 60;
    }, 4000);
    return { user };
  },
};
</script>
  • 使用 watch 监听响应式对象数据中的一个属性(复杂),配置深度监听
<template>
  <p>
    姓名:{{ user.name }} 性别:{{ user.info.gender }} 年龄:{{ user.info.age }}
  </p>
</template>

<script>
import { reactive, watch } from "vue";
export default {
  name: "App",
  setup() {
    const user = reactive({
      name: "tom",
      info: {
        gender: "男",
        age: 18,
      },
    });
    // 4. 监听响应式对象数据的一个数据,复杂类型
    // watch(()=>数据, 改变后回调函数, {deep: true})
    watch(
      () => user.info,
      () => {
        console.log("数据改变了");
      },
      {
        // 开启深度监听
        deep: true,
      }
    );
    // 2s改变数据
    setTimeout(() => {
      user.info.age = 60;
    }, 2000);
    return { user };
  },
};
</script>
  • 使用 watch 监听,配置默认执行
  {
        // 开启深度监听
        deep: true,
+        // 默认执行一次
+        immediate: true
      }

总结:

  • watch(’需要监听的数据‘,数据改变执行函数,配置对象)来进行数据的侦听
  • 数据:单个数据,多个数据,函数返回对象属性,属性复杂需要开启深度监听
  • 配置对象:deep深度监听 immediate 默认执行

10.组合API-生命周期函数

掌握:vue3的常用生命周期函数

使用步骤:

  1. 先从vue中导入以on 开头的生命周期钩子函数
  2. 在setup函数中调用生命周期函数并传入回调函数
  3. 生命周期钩子函数可以调用多次
  • Vue2和vue3的生命周期对比
选项式API下的生命周期函数使用组合式API下的生命周期函数使用
beforeCreate不需要(直接写到setup函数中)
created不需要(直接写到setup函数中)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyedonBeforeUnmount
destroyedonUnmounted
activatedonActivated
deactivatedonDeactivated
  •  参考代码
<template>
  <div>生命周期函数</div>
</template>
<script>
import { onMounted } from "vue";
export default {
  name: "App",
  setup() {
    // 生命周期函数:组件渲染完毕
  
    onMounted(()=>{
      console.log('onMounted触发了')
    })

    onMounted(()=>{
      console.log('onMounted也触发了')
    })
  },
};
</script>

总结:常用的 onMounted 组件渲染完毕:发请求,操作dom,初始化表。。。

11.组合API-父子通讯

  • 父传子

父组件

<template>
  <div class="app">
    父组件:{{ money }}
    <hr />
    <SonCom :money="money" />
  </div>
</template>
<script>
import SonCom from "./SonCom.vue";
export default {
  name: "App",
  components: { SonCom },
  setup () {
    const money = ref(10000)
    return { money }
  }
};
</script>

子组件

<template>
  <div class="son">子组件:{{ money }}</div>
</template>
<script>
export default {
  name: "SonCom",
  props: {
    money: {
      type: Number,
    },
  },
  setup(props) {
    console.log("数据money:", props.money);
  },
};
</script>

  • 子传父

子组件

<template>
  <div class="son">
    子组件:{{ money }} <button @click="changeMoney">买手机</button>
  </div>
</template>
<script>
export default {
  name: "SonCom",
  props: {
    money: {
      type: Number,
    },
  },
  // vue3规范,自定义事件需要在这声明
  emits: ["change-money"],
  setup(props, { emit }) {
    console.log("数据money:", props.money);
    // 通过emit触发自定义事件
    const changeMoney = () => {
      emit("change-money", props.money - 3999);
    };
    return { changeMoney };
  },
};
</script>

父组件

<template>
  <div class="app">
    父组件:{{ money }}
    <hr />
    <SonCom :money="money" @change-money="money = $event" />
  </div>
</template>
<script>
import SonCom from "./SonCom.vue";
export default {
  name: "App",
  components: { SonCom },
  setup () {
    const money = ref(10000)
    return { money }
  }
};
</script>

总结:

  • 父传子,通过props传递,setup函数 第一个参数就是props
  • 子传父,通过emit函数,setup函数 第二个参数解构出emit函数,emits选项需要声明自定义事件名称

12.组合API-provide和inject函数

掌握:通过provide和inject函数实现跨级组件通讯

祖先传递后代:

  • provide 和 inject 从vue中导入
  • provide(’数据名称‘,响应式数据)提供数据的祖先组件使用
  • const data=inject('数据名称') 注入数据的后代组件使用

App.vue

<template>
  <div class="app">
    根组件:{{ money }}
    <hr />
    <ParentCom />
  </div>
</template>
<script>
import { ref, provide } from 'vue';
import ParentCom from "./ParentCom.vue";
export default {
  name: "App",
  components: { ParentCom },
  setup () {
    const money = ref(10000)
    // 提供数据给后代
    provide('money', money)
    return { money }
  }
};
</script>

ParentCom.vue

<template>
  <div class="parent-com" style="padding-left:50px">
    父组件:
    <hr />
    <ChildCom />
  </div>
</template>
<script>
import ChildCom from './ChildCom.vue'
export default {
  name: 'ParentCom',
  components: { ChildCom }
}
</script>

ChildCom.vue

<template>
  <div class="child-com" style="padding-left:50px">
    子组件:{{money}}
  </div>
</template>
<script>
import { inject } from 'vue'
export default {
  name: 'ChildCom',
  setup () {
    // 注入祖先组件提供的数据
    const money = inject('money')
    return { money }
  }
}
</script>

后代传递祖先:

  • provide(‘数据名称’,修改函数)提供函数的祖先组件使用
  • const changeMoney=inject(‘数据名称’) 注入函数的后代组件使用
  • 遵循:数据由谁定义,由谁修改。

App.vue

<template>
  <div class="app">
    根组件:{{ money }}
    <hr />
    <ParentCom />
  </div>
</template>
<script>
import { ref, provide } from 'vue';
import ParentCom from "./ParentCom.vue";
export default {
  name: "App",
  components: { ParentCom },
  setup () {
    const money = ref(10000)
    // 提供数据给后代
    provide('money', money)
+    // 提供函数给后代    
+    provide('changeMoney', newMoney => {
+      money.value = newMoney
+    })
    return { money }
  }
};
</script>

ChildCom.vue

<template>
  <div class="child-com" style="padding-left: 50px">
    子组件:{{ money }}
+    <button @click="changeMoney(money - 3999)">买手机</button>
  </div>
</template>
<script>
import { inject } from "vue";
export default {
  name: "ChildCom",
  setup() {
    // 注入祖先组件提供的数据
    const money = inject("money");
+    // 注入祖先组件提供的函数
+    const changeMoney = inject("changeMoney");
+    return { money , changeMoney};
  },
};
</script>

总结:

  • 使用 provide 提供数据,使用 inject 注入数据
  • 可以传递数据(使用数据),可以传递函数(修改数据)

13.组合API-ref属性

掌握:使用ref属性获取DOM元素或者组件实例

大致内容:

  • 通过 ref 属性获取DOM元素
  • 通过 ref s属性获取组件实例

通过 ref 属性获取DOM元素

<template>
  <div class="app">
    <!-- 2. 使用ref属性绑定响应式数据 -->
    <h1 ref="refH">App组件</h1>
  </div>
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
  name: "App",
  setup () {
    // 1. 声明响应式数据并返回给模板使用
    const refH = ref(null)

    // 3. 组件渲染后查看dom
    onMounted(()=>{
      console.log(refH.value)
    })

    return { refH }
  }
};
</script>

通过 ref 属性获取组件实例

App.vue

<template>
  <div class="app">
    App组件
    <!-- 2. 使用ref属性绑定响应式 -->
    <ChildCom ref="refCom" />
  </div>
</template>
<script>
import { ref, onMounted } from 'vue';
import ChildCom from "./ChildCom.vue";
export default {
  name: "App",
  components: { ChildCom },
  setup () {
    // 1. 声明响应式数据并返回给模板使用
    const refCom = ref(null)

    // 3. 组件渲染后查看组件实例,可以调用组件函数
    onMounted(()=>{
      console.log(refCom.value)
      refCom.value.show()
    })

    return { refCom }
  }
};
</script>

ChildCom.vue

<template>
  <div class="child-com">
    子组件
  </div>
</template>
<script>
export default {
  name: 'ChildCom',
  setup () {
    const show = () => {
      console.log('组件内函数执行了')
    }
    return { show }
  }
}
</script>

总结:通过ref函数创建一个数据,给标签或者组件使用ref属性绑定这个数据,组件渲染后可获取dom或者组件实例。

14.总结

  • Vue3 组合API的入口?
    • setup()
  • 如果明确知道数据是对象且知道字段名称,用什么函数什么响应式数据?
    • reactive()
  • 如果不知道数据类和字段,使用什么声明响应式数据?
    • ref()
  • 如果去解构 reactive 声明的数据对象,需要使用那个函数保持响应式特性?
    • toRefs()
  • 组合API中定义计算属性?
    • Computed(()=>计算后的数据)
  • 使用watch进行侦探数据的改变
    • 监听一个数据
      • watch(数据,()=>{})
    • 监听多个数据
      • watch([数据1,数据2],()=>{})
    • 监听对象中的一个属性,简单数据
      • watch(()=>对象.属性,()=>{})
    • 监听对象中的一个属性,复杂数据
      • watch(()=>对象.属性,()=>{},{deep:true})
    • 如果想立即执行
      • watch(()=>对象.属性,()=>{},{deep:true,immediate:true})
  • 声明周期钩子函数,那个钩子发请求?
    • onMounted
  • 父子通讯
    • 父给子:props 传递,模板中直接使用,setup(props){ // 使用props }
    • 子给父:setup(props,{emit}){} 通过emit触发事件,规范:emits选项需要显性声明
  • 跨级组件通讯
    • 祖先到后代
      • 祖先 provide('money', money)
      • 后代 injec('money')
    • 后代到祖先
      • 祖先 provide('修改数据函数', (newVal)=>{ moeny.value=newVal })
      • 后代 inject('修改数据函数') 调用这个函数传递需要改的值
  • 通过获取dom元素和组件实例
    • 通过ref定义一个响应式数据,return 给模板使用,组件或元素上通过ref属性绑定即可
    • 组件渲染完毕后课获取实例和元素

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值