vue3新特性总结

191 阅读1分钟

组件化

SFC组件

常规sfc写法

<template>
  <h1>{{ titleInfo.color }}</h1>
  <div>
    {{ $store.state.counter }}
  </div>
  <div>
    {{ doubleCounter }}
  </div>
  <div v-for="item in todos" :key="item.id">
    {{ item.name }}
  </div>
  <input
    type="text"
    v-model="todoName"
    @keydown.enter="addTodo(newTodo(todoName))"
  />
</template>

<script lang="ts">
import { defineComponent, PropType, ref } from "vue";
import { TitleInfo, Todo } from "../types";
const ConstPropType= {
    titleInfo: {
      type: Object as PropType<TitleInfo>, // 使用PropType<T>定义类型类型校验才能生效
      required: true,
    },
  } as const // 断言为const才能放入props中
export default defineComponent({
  props: ConstPropType,
  data() {
    return {
    //   counter: 1,
    //   counter: this.s,
      todos: [] as Todo[],
      todoName: "",
    };
  },
  computed: {
    doubleCounter(): number {
      return this.$store.state.counter * 2;
    },
  },
  created() {
    this.todos.push({
      id: 123,
      name: "vue3",
      completed: false,
    });
  },
  methods:{
      newTodo(todoName:string):Todo{
          return {
              id:12344325,
              name:todoName,
              completed:false
          }
      },
      addTodo(todo:Todo):void{
          this.todos.push(todo)
          this.todoName=''
      }
  },
//   setup(){
//       const counter=ref(1)
//       return {counter}
//   }
});


</script>

<style scoped>
</style>

2.setup写法

<template>
  <h1>{{ titleInfo.color }}</h1>
  <div @click="$store.commit('add')">
    {{ counter }}
  </div>
  <div>
    {{ doubleCounter }}
  </div>
  <div v-for="item in todos" :key="item.id">
    {{ item.name }}
  </div>
</template>
<script lang="ts" setup>  
// 此处标记为setup写法 
// setup函数没有this
// 则script中的所有变量可以直接在template模板中使用
// 在script标签内需要读取value属性
import { defineComponent, ref,computed, reactive,defineProps } from "vue";
import type {PropType} from 'vue' 
import { TitleInfo, Todo } from "../types";
import {useStore} from 'vuex'
import { key } from "../store";

const store=useStore(key)
console.log(store);
const counter=computed(():number=>store.state.counter)
//使用defineProps定义props
defineProps({
  titleInfo: {
    type: Object as PropType<TitleInfo>,
    required: true,
  },
})

const doubleCounter=computed(():number=>counter.value*2)
// const todos=ref([] as Todo[])
const todos=computed(()=>store.state.todos?.todos_c)
</script>
<style scoped>
</style>

jsx写法


import { defineComponent, PropType } from 'vue'

const PropType = {
 msg: String,
 age: {
   type: Number as PropType<number>,
   required: true,
 },
} as const

export default defineComponent({
 props: PropType,
 setup(props) {
   
   return () => {
     return (
       <div>
         <div>Hello World{props.age}</div>
       </div>
     )
   }
 },
})

vue3迁移指南

v3.cn.vuejs.org/guide/migra…

vue3的setup函数

v3.cn.vuejs.org/guide/compo…

vue3 的 composition api

v3.cn.vuejs.org/guide/compo…

常见官方文档面试题

如何注册局部组件和全局组件

v3.cn.vuejs.org/guide/compo…

如何侦听一个深度嵌套的响应式对象

v3.cn.vuejs.org/guide/react…

创建一个应用实例

v3.cn.vuejs.org/guide/insta…

reactive与ref区别

1、 从定义数据方面: ref通常用来定义基本类型数据
reactive用来定义:对象(或者数组)类型数据
ref也可以用来定义对象或者数组类型的数据,内部会通过reactive转为代理对象
2、从原理方面:
ref通过Object.defineProperty()的get和set实现数据代理。
reactive使用Proxy实现数据代理,并且通过Reflect操作源对象内部的数据。
3、从使用方面:
ref操作数据需要.value,template模板中不需要。
reactive都不需要,value

vue3组件自定义事件

vue3中组件发送的自定义事件需要定义在emits选项中 emits.vue

<template>
	<div @click="$emit('my-click')"></div>
</template>
<script>
	export default {
	// 这里一定要注册,不然会触发两次,原生的点击事件也会触发
		emits: ['my-click']
	}
</script>

helloworld.vue

<template>
	<div>
		<emits @my-click="onclick"></emits>
	</div>
</template>
<script>
import emits form './emits.vue'
	export default {
		methods:{
			onclick(){
				console.log('自定义事件触发')
			}
		}
	}
</script>

vue3.x 语法糖 defineEmits defineExpose父子组件传参 以及 调用方法

defineExpose

defineExpose可以将方法主动暴露出来

父组件

//通过ref
      <tree :show="show" 
      ref="treeRef">
      </tree>
// ref      
const treeRef = ref()
const handleClick = () => {
//获取ref中的子组件方法handleNodeClick()
 treeRef.value.handleNodeClick()
}

子组件

import { ref defineExpose } from 'vue'
const handleNodeClick = () => {
 console.log('要执行的方法')
}
//将方法暴露出
defineExpose({ handleNodeClick})

defineEmits

父组件

//getGatewayData要获取的参数
<tree :show="show" 
@gatewayData="getGatewayData">
</tree>
//执行方法获取参数
const getGatewayData = (e) => {
  console.log('getGatewayData', e)
}

子组件

import { ref, defineEmits } from 'vue'
const emits = defineEmits(['handleNodeClick'])
const handleNodeClick = (e) => {
 emits('gatewayData', label.value)
}