Vue3 setup语法糖

257 阅读2分钟

1. setup语法糖使用

在.vue文件的script标签上加入setup即可使用组合式编程写法,我们不再需要export组件,无需再写选项式编程中的data、methods、components(引入组件时不用再声明注册)等,以及不再需要用this获取实例

<script setup>

</script>

2.数据实时响应ref、reactive

  1. 在组合式编程中对象数据使用reactive()函数包装,获取时直接使用对象名
<script setup>
import { reactive } from 'vue'

let obj = reactive({
    a: 1
})
console.log(obj) // { a: 1 }
</script>
  1. 与reactive不同的是,除对象类型以外的其他类型数据都用ref()函数包装,获取时用数据名.value
<script setup>
import { ref } from 'vue'

let str = ref('123')
console.log(str.value); // 123

let bool = ref(true)
console.log(bool.value); // true
</script>

这里再说明一下ref()函数的另一个用处,我们在操作dom元素时,如果想获取某个节点的时候同样也可以使用ref()来获取节点的信息

<template>
    <div ref='thisDiv'></div>
</template>

<script setup>
import { ref } from 'vue'

let thisDiv = ref() // 获取目标dom元素
</script>

3.生命周期钩子函数

在组合式编程中,所有编写的代码实际上都运行在beforeCreate()created()生命周期函数中,因此如果我们想在页面渲染完后执行某些函数可以使用onMounted()

<script setup>
import { ref, onMounted } from 'vue'

let str = ref('123')

function print() {
    console.log(str.value);
}

onMounted(() => {
    print(); // 123
})
</script>

4.监听、计算属性

与分布式相似,这里举一个例子使用watchcomputed来监听某个变量并打印值

<script setup>
import { ref, watch, computed } from 'vue'

let str = ref('123')

str.value = '321'

watch(str, (newValue, oldValue) => {
  console.log(str.value); // 321
})

computed(() => {
    console.log(str.value); // 321
})
</script>

5.提供与注入

在开发中往往会嵌套一定深度的组件,为了让更深层级的组件获取到上层组件的数据和方法我们可以使用provide()inject()函数来实现

// 上层组件
<script setup>
import { ref, provide } from 'vue'

let str = ref('123)
function print() {
    console.log(str.value);
}
provide('parent', { str: str, print })
</script>

// 下层组件
<script setup>
import { inject } from 'vue'

const { str, print } = inject('parent')
// 注入的数据也是实时响应的
console.log(str.value); // 123
print(); // 123
</script>

6.实现一个父子组件通信实例

具体是将父组件input标签中输入的值双向绑定到子组件上显示,同理,将子组件的input标签中输入的值双向绑定到父组件上显示。(注:本章我们没有再去探讨分布式组件通信中的propsemit,因为这其中的用法还是一样的)

接下来我们看看如何实现吧

  1. 父组件
<template>
  <div>
    <div>
      <div v-text="getChildData.value"></div>
      <el-input type="text" v-model="parentData" />
    </div>
    <component ref="childComponent" :is="child" :setChild="parentData"></component>
  </div>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";
import child from "./components/index.vue";

let parentData = ref("🍒🍉🍊");

const childComponent = ref();
let getChildData = ref("");

onMounted(() => {
  // 之所以在上面的v-text加上.value,大概是defineExpose返回的是一个ref对象
  getChildData.value = computed(() => childComponent.value.childData);
});
</script>
  1. 子组件
<template>
  <div>
    <span>{{ getParentData }}</span>
    <input type="text" v-model="childData" />
  </div>
</template>

<script setup>
import { computed, ref } from "vue";

const props = defineProps(["setChild"]); // 通过defineProps获取父组件传递的数据
let getParentData = computed(() => props.setChild);

let childData = ref("🍊🍉🍒");
defineExpose({ // 通过defineExpose暴露子组件的数据
  childData
});
</script>

效果图 (上述代码为实现核心,如果想获取源代码请访问 github.com/xy0411/trea… 下载)

父子组件双向绑定.png