Vue3 setup syntax sugar usage

1. Life cycle

In the life cycle of Vue3, create() is deleted and replaced by other life cycles plus on, as shown below

 In addition, the setup attribute is added, which is executed earlier than created. At the same time, this in setup does not point to the instance. This method is called before onBeforeMounted. At the same time, vue3 also deletes the this point in the life cycle, and all methods must be created by themselves. Called in the vue instance.

Grammatical sugar writing, as follows:

/**
*作者:星辰38
*链接:https://juejin.cn/post/7044823063027941389
*来源:稀土掘金
**/
<template>
  <div>123</div>
</template>
<script setup>
  //setup写法,自带语法糖(推荐)
  //在setup中没有this,所有的方法必须引入后使用
  import {ref,onMounted,onUnmounted} from 'vue'
  let up =ref(123)
  import {} from 'vue'
    //所有的生命周期用法均为回调函数
   onMounted(()=>{
      console.log('我创建了');
   })
    // 销毁实例变为onUnmounted,与vue2的destroy作用一致
   onUnmounted(()=>{
      console.log('我销毁了');
   })

</script>

The original writing is as follows:

<template>
  <div>123</div>
</template>
<script>
import {ref} from 'vue'
export default{
  setup() {
    //定义数据需要在数据前面加ref包裹,后面会具体详解
    let up=ref(123)
    return{
      up
    }
  }
}
</script>

2. Data Binding

ref is a kind of converting data into responsive data structure in vue3, because there is no data(){} in vue3, it is impossible to hijack data to make responsive data. Note that .value must be added to the data fetched from ref

<template>
  <div>
    <div>{
   
   { num }}</div>
    <button @click="addNum">num+1</button>
  </div>
</template>
<script setup>
import { ref } from "vue";
let num = ref(1);
let addNum = () => {
  //注意,使用ref变成响应式数据的时候,必须通过.value才可以拿到定义的数据
  num.value = num.value + 1;
  console.log("我执行了,现在的num是" + num.value);
  console.log(num);
};
</script>

3. Dom element acquisition

The dom can only be retrieved after the rendering is completed. The dom has not been rendered during the setup, so it needs to be
retrieved after the onMounted() cycle.

<template>
  <div>
    <!-- 模板中无需使用.value,会被自动编译转换成真实数据 -->
    <div ref="box">{
   
   { num }}</div>
  </div>
</template>
<script setup>
import { ref,nextTick ,onMounted} from "vue";
let num = ref(1);
// 需要拿取box这个元素,那么只需要定义一个名字为上方ref相同的名字即可
let box =ref();
// 这么拿取的话会是undefined,需要等dom渲染完成后才能拿取到,因为setup时候dom还没渲染
console.log(box.value);//undefined
nextTick(()=>{
  console.log('我是nextTIck执行');
  console.log(box.value);
})
onMounted(()=>{
  console.log('我是mouted执行');
  console.log(box.value);
})
</script>

4. reactive definition data

reactve can turn the entire object into responsive data, eliminating the trouble of using .value to fetch data.

<template>
  <div>
    <div ref="box">{
   
   { data.name }}</div>
    <button @click="setName">修改名字</button>
  </div>
</template>
<script setup>
import { reactive } from "vue";
let data = reactive({
  name: "张三",
  age: 13,
  sex: "男"
});
function setName() {
  // 调用时更像vue2,不用.value去调用
  data.name = "李四";
  data.age = 35;
  data.sex = "女";
}
</script>

5. Method binding

Both anonymous functions and normal functions can be used.

template>
  <div>
    <button @click="setFn"></button>
  </div>
</template>
<script setup>
// 以下方法都可以定义函数,按自己开发习惯定义一种即可
let setFn = ()=>{
  console.log("我是匿名函数");
}
function setFn(){
  console.log('我是普通函数');
}
</script>

6. Computed to use

<template>
  <div class="box">
    <!-- 在上方调用即可,结果为169 -->
    {
   
   {add}}
  </div>
</template>
<script setup>
import { computed, ref } from "vue";
let num1 = ref(13);
let num2 = ref(13);
// 设置个变量接收
let add = computed(() => {
  return num1.value * num2.value;
});

7. Single attribute monitoring

<template>
  <div class="box">
    <input type="text" v-model="user" />
  </div>
</template>
<script setup>
import { watch, ref } from "vue";
// 用户名
let user = ref();
// watch监听接收两个或者三个匿名函数,第一个是监听的数值,第二个是处理监听函数,第三个是否开启深监听(可选)
watch(
  () => user.value,
  (newVal, oldVal) => {
    console.log("新值:" + newVal + "旧值:" + oldVal);
  },
  // 可选项,是否开启深监听
  {
    deep: true
  }
);
</script>

8. Multi-attribute monitoring

<template>
  <div class="box">
    <input type="text" v-model="user" />
    <input type="password" v-model="password" />
  </div>
</template>
<script setup>
import { watch, ref } from "vue";
// 用户名
let user = ref();
let password = ref();
// 监听user
watch(
  () => user.value,
  newVal => {
    console.log("用户名:" + newVal);
  },
  // 可选项,是否开启深监听
  {
    deep: true
  }
);
// 监听password
watch(
  () => password.value,
  newVal => {
    console.log("密码:" + newVal);
  }
);
</script>
<template>
  <div class="box">
    <input type="text" v-model="user" />
    <input type="password" v-model="password" />
  </div>
</template>
<script setup>
import { watch, ref } from "vue";
// 用户名
let user = ref();
let password = ref();
// 同时监听多个值,只要有一个值变化就会触发方法
// 同时监听user和password,只要user或者password其中一个值变化,就会触发下面的方法
watch(()=>[user.value, password.value],([newUser, newPassword],[oldUser, oldPassword])=>{
  console.log('我是新的user值'+newUser);
  console.log('我是旧的的user值'+oldUser);
  console.log('我是新的pass值'+newPassword);
  console.log('我是旧的的pass值'+oldPassword);
})
</script>

9. Routing jump

Use this.$router.push in vue2 to jump, but in vue3, useRouter needs to be introduced for use.

<template>
  <div>
    <button @click="jumpNewPage">跳转首页</button>
  </div>
</template>
<script setup>
// 切记是在vue-router中引入useRouter
import {useRouter} from 'vue-router'
  const router = useRouter()
let jumpNewPage = ()=>{
  // 切记不可将router定义在方法中,这样他不是响应式数据,会报错
  // const router = useRouter()
  router.push({path: '/'})
}
</script>

10. Routing parameters

Note: When using query to pass parameters, the parameters will be reflected in the path, such as 8080/?name=XX, but params will not

<template>
  <div>
    <button @click="jumpNewPage">跳转首页</button>
  </div>
</template>
<script setup>
// 记住是在vue-router中引入useRouter
import {useRouter} from 'vue-router'
  const router = useRouter()
let jumpNewPage = ()=>{
  // 有两种传参方式,query和params,两者写法不一样,请注意
  // query更像get传参,是显性传参,前面跳转加path路径即可,刷新也还在,
  router.push({path: '/',query: {name:'首页'}})
  // params更像post,是隐性传参过去,跳转需注意,不使用path跳转,而是用路由中跳转组件的name进行跳转,否则拿不到params
  router.push({name: 'Home',params: {name:'首页'}})
}
</script>

The home object in the route is:

const router = [
    {
        path:'/',
        name:'Home',
        component:()=> import('../views/Home.vue')
        meta:{title:'首页'}
    }
]

 11. Route receiving parameters

//#1 params接收
<script setup>
// 引入useRoute,获取是route
import {useRoute} from 'vue-router'
import {onMounted} from 'vue'
  const route = useRoute()
  onMounted(()=>{
    console.log(route.params);//结果为{name:'首页'}
  })
</script>


//#2 query接收
<script setup>
// 引入useRoute,获取是route
import {useRoute} from 'vue-router'
import {onMounted} from 'vue'
  const route = useRoute()
  onMounted(()=>{
    console.log(route.query);//结果为{name:'首页'}
  })
</script>

12. Components

Components can be directly used in the template after they are directly introduced in props, without further registration.

<template>
  <div class="box">
    <!-- 子组件引用 -->
   <v-child></v-child>
  </div>
</template>
<script setup>
// 引入后无需注册
import vChild from '../components/child.vue'
</script>

13. Father-to-son defineProps pass parameters

The parent element passes the data to the child element, and the child element uses defineProps to receive it.

//父元素
<template>
  <div class="box">
    <!-- 子组件引用 -->
   <v-child msg='我给子元素带的一段话'></v-child>
  </div>
</template>
//子元素
<template>
    <div class="child">
        我是子组件
    </div>
</template>
<script setup>
import {defineProps} from 'vue'
// 在接收时候也得注意,vue3 props接收必须规定数据类型,如果父元素数据类型出错,那么会报错
const props = defineProps({msg:String})
console.log(props); //  Proxy {msg: '我给子元素带的一段话'}
</script>

14. Pass value from child to parent defineEmits

//子组件
<template>
    <div class="child">
        我是子组件
    </div>
</template>
<script setup>
import {defineEmits,onMounted} from 'vue'
const emit = defineEmits()
onMounted(()=>{
    emit('getChildMsg','我是子元素,给父元素传的话')
})
</script>
//父组件
<template>
  <div class="box">
    <!-- 接收子组件的方法 -->
    <v-child @getChildMsg="getMsg"></v-child>
  </div>
</template>
<script setup>
// 引入后无需注册
import vChild from "../components/child.vue";
let getMsg = e => {
  console.log(e); //我是子元素,给父元素传的话
};
</script>

15. The parent takes the child method defineExpose

//子组件
<template>
    <div class="child">
        {
   
   {val}}
    </div>
</template>
<script setup>
import {ref,defineExpose} from 'vue'
let val = ref('我是子组件')
let fn = ()=>{
    val.value='我改变了子组件'
}
// 暴露val和fn
defineExpose({
    val,fn
})
</script>
//父组件
<template>
  <div class="box">
    <!-- 接收子组件的方法 -->
    <v-child ref ='child'></v-child>
  </div>
</template>
<script setup>
// 引入后无需注册
import vChild from "../components/child.vue";
import {ref,onMounted} from 'vue';
// 获取child实例
let child = ref()
onMounted(()=>{
  console.log(child.value.val);//直接打印:我是子组件,并不需要加.value
  // 执行子组件的fn函数
  child.value.fn()
})
</script>

Guess you like

Origin blog.csdn.net/qq_45020145/article/details/130478738