侧边栏壁纸
博主头像
分享你我博主等级

行动起来,活在当下

  • 累计撰写 107 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

VUE3 语法糖(script setup)+ts 使用

管理员
2021-11-21 / 0 评论 / 0 点赞 / 5 阅读 / 8118 字

VUE3官方网站:点击访问

VUE3的生命周期和VUE2的区别:点击访问

下面通过两组件和一个辅助文件说明:

<template>
  <div>我的父亲是{{ actionName }}</div>
  <div>我是非响应值{{ `${state.id},${state.attributes.name}` }}</div>
  <div>我是{{ name }},setValue:{{ count }}</div>
  <button @click="setValue">点击</button>
  <button @click="clickThis">给父亲带东西</button>
</template>
<script setup lang="ts" name="actionChild">
/** 
 * 以define开头的api都为编译器宏
 * defineExpose 这个api其实主要是解决传统vue组件过度暴露模板上的东西
 * defineProps 这个api很好理解,就是定义props相关信息
 * defineEmits 这个api也很好理解,就是定义emits相关信息
 * PropType 注解或者是约束 defineProps(props)
 * nextTick 强制刷新
 * ref 接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property .value
 * onDeactivated 
 * reactive 返回对象的响应式副本
 * watch 响应式更改(监听值的变化然后做某些事)
 * onBeforeUpdate 
 * computed 
 * onMounted 
 * useSlots 使用场景少
 * useAttrs 使用场景少
 * withDefaults 解决使用defineProps声明时无法给默认值的問题
 * toRefs 将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref
 */
import {
  defineExpose,
  defineProps,
  PropType,
  nextTick,
  ref,
  onDeactivated,
  reactive,
  watch,
  onBeforeUpdate,
  computed,
  onMounted,
  defineEmits,
  toRefs
} from "vue";
/**声明props */
const props = defineProps({
  user: {
    type: Object as PropType<Users>
  },
  actionName: {
    type: String,
  }
});
/** 有默认值的props声明
* const props = withDefaults(defineProps<Users>(), {
*   UserName: "",
*   Password: "你猜",
* })
 */
/**
 *  ts 专有的声明,约定传递参数的类型
 * const emit= defineEmits<{
 *  (e: 'click', num: number): void
 *}>()
 * 
 */
/**子组件向父组件事件传递 */
const emit = defineEmits(['Handler'])
const clickThis = () => {
  emit('Handler', { code: 1, data: "子类触发父亲方法" })
}
/**声明由ref自行推导的类型 */
const count = ref(0);
/**声明指定类型的ref值 */
const name = ref<string | null | number>(0);
/**声明返回对象的响应式副本 (不需要通过.value 取值和赋值) */
const state = reactive({
  id: 1,
  attributes: {
    name: '',
  }
});
/**这也是可以的哦。 官方推荐使用ref定义基础类型,reactive定义复杂类型
 * 
 *  const data: DataProps = reactive({
      name: "zhangsan",
      birthYear: 2000,
      now: 2020,
      sayName: () => {
        console.log(1111);
        console.log(data.name);
        
        data.name = "I am " + data.name;
        console.log(data.name);
      },
      age: computed(() => {
        return data.now - data.birthYear;
      }),
    });
    const refData = toRefs(data)
 * 
 * 
 */
const setValue = () => {
  name.value = "我是响应式的name";
  count.value++;
}
/**监听值是否发生改变 */
watch(() => props.user, (data) => {
  console.log("prpos 的user对象发生改变", data);
});
watch(() => {
  if (props.user) { return null }
  if (props.user.UserName) { return null }
  return props.user.UserName;
}
  , (data) => {
    console.log("prpos 的user对象的UserName发生改变", data);
  });
watch(
  () => state,
  (state, prevState) => {
    console.log('deep', state.attributes.name, prevState.attributes.name)
  },
  { deep: true }
);
/**侦听多个数据源 */
watch([count, name], (newValues, prevValues) => {
  console.log(newValues, prevValues)
});
/**暴露指定数据,使其在父组件中使用ref可以获取其暴露的数据或者方法 */
defineExpose({
  count,
  name,
  ...toRefs(state)/**通过toRefs 将非响应式的state改成响应式并导出 */
});
onMounted(() => {
  console.log("获取父类传入的user", props.user);
  console.log("获取父类传入的ActionName", props.actionName);
});
</script>
<template>
  <div>action:{{ name }}</div>
  <button @click="getChildData">看一下孩子的东西</button>
  <button @click="setName">设置我的名称</button>
  <actionChildVue :ref="childRef" :action-name="name" :user="user" @handler="triggerChild" />
</template>
<script setup lang="ts" name="action">
import actionChildVue from "@renderer/components/actionChild.vue";//导入子组件
import {
  ref,
} from "vue";
const name = ref("我是父亲组件名称:动作");
/** action.d.ts 声明Users的接口类型 .d是ts中的全局声明 */
const user = ref<Users>({
  UserName: 'Hello',
  Password: '哟,你慢慢猜'
});
const triggerChild = (data) => {
  console.log("我孩子给我带的东西", data);
}
const setName = () => {
  name.value = "动作加1";
}
const childRef = ref(null);//定义接收子组件的refs
const getChildData = () => {
  if (childRef) { return; }
  console.log(childRef.value);
}
</script>

新建一个action.d.ts用于声明接口进行类型约束

interface Users {
  UserName: string | null;
  Password: string | null;
  Age?: number | null;
}
interface DataProps {
  name: string;
  now: number;
  birthYear: number;
  age: number;
  sayName: () => void;
}


插件推荐:

image.png



0

评论区