十分钟,带你了解Vue3的新写法

2936次阅读 210人点赞 作者: WuBin 发布时间: 2023-05-16 08:51:09
扫码到手机查看

Vue3 中的script的三种写法

最基本的 Vue2 写法

<template>
  <div>{{ count }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

<script>
export default {
  data() {
    return {
      count: 1,
    };
  },
  methods: {
    onClick() {
      this.count += 1;
    },
  },
}
</script>

setup() 属性

<template>
  <div>{{ count }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

<script>
import { ref } from 'vue';
export default {

  // 注意这部分
  setup() {
    let count = ref(1);
    const onClick = () => {
      count.value += 1;
    };
    return {
      count,
      onClick,
    };
  },
  
}
</script>

script setup

<template>
  <div>{{ count }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

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

const count = ref(1);
const onClick = () => {
  count.value += 1;
};
</script>

正如你看到的那样,无论是代码行数,还是代码的精简度,<script setup>的方式是最简单的形式。

如果你对 Vue 很熟悉,那么,我推荐你使用<script setup>的方式。

这种写法,让 Vue3 成了我最喜欢的前端框架。

如果你还是前端新人,那么,我推荐你先学习第一种写法。

因为第一种写法的学习负担更小,先学第一种方式,掌握最基本的 Vue 用法,然后再根据我这篇文章,快速掌握 Vue3 里最需要关心的内容。

第一种写法,跟过去 Vue2 的写法是一样的,所以我们不过多介绍。

第二种写法,所有的对象和方法都需要return才能使用,太啰嗦。除了旧项目,可以用这种方式体验 Vue3 的新特性以外,我个人不建议了解这种方式。反正我自己暂时不打算精进这部分。

所以,接下来,我们主要介绍的,也就是<script setup>,这种写法里需要了解的内容。

注意:<script setup>本质上是第二种写法的语法糖,掌握了这种写法,其实第二种写法也基本上就会了。(又多了一个不学第二种写法的理由)。

如何用script-setup编写组件

学习 Vue3 并不代表你需要新学习一个技术,Vue3 的底层开发思想,跟 Vue2 是没有差别的。

V3 和 V2 的区别就像是,你用不同的语言或者方言说同一句话。

所以我们需要关心的,就是 Vue2 里的内容,怎么用 Vue3 的方式写出来。

data——唯一需要注意的地方

整个data这一部分的内容,你只需要记住下面这一点。

以前在data中创建的属性,现在全都用ref()声明。

template中直接用,在script中记得加.value

在开头,我就已经写了一个简单的例子,我们直接拿过来做对比。

写法对比

 // Vue2 的写法

<template>
  <div>{{ count }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

<script>
export default {
  data() {
    return {
      count: 1,
    };
  },
  methods: {
    onClick() {
      this.count += 1;
    },
  },
}
</script>
 // Vue3 的写法

<template>
  <div>{{ count }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

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

 // 用这种方式声明
const count = ref(1);

const onClick = () => {
   // 使用的时候记得 .value
  count.value += 1;
};
</script>

注意事项——组合式api的心智负担

aref 和 reactive

Vue3 里,还提供了一个叫做reactiveapi

但是我的建议是,你不需要关心它。绝大多数场景下,ref都够用了。

什么时候用ref()包裹,什么时候不用。

要不要用ref,就看你的这个变量的值改变了以后,页面要不要跟着变。

当然,你可以完全不需要关心这一点,跟过去写data一样就行。

只不过这样做,你在使用的时候,需要一直.value

不要解构使用

在使用时,不要像下面这样去写,会丢失响应性。

也就是会出现更新了值,但是页面没有更新的情况

// Vue3 的写法
<template>
  <div>{{ count }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

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

const count = ref(1);
const onClick = () => {
  // 不要这样写!!
  const { value } = count;
  value += 1;
};
</script>

注意:学习 Vue3 就需要考虑像这样的内容,徒增了学习成本。实际上这些心智负担,在学习的过程中,是可以完全不需要考虑的。

这也是为什么我推荐新人先学习 Vue2 的写法。

methods

声明事件方法,我们只需要在script标签里,创建一个方法对象即可。

剩下的在 Vue2 里是怎么写的,Vue3 是同样的写法。

// Vue2 的写法
<template>
  <div @click="onClick">
    这是一个div
  </div>
</template>

<script>
export default {
  methods: {
    onClick() {
      console.log('clicked')
    },
  },
}
</script>
// Vue3 的写法
<template>
  <div @click="onClick">
    这是一个div
  </div>
</template>

<script setup>

// 注意这部分
const onClick = () => {
  console.log('clicked')
}

</script>

props

声明props我们可以用defineProps(),具体写法,我们看代码。

写法对比

// Vue2 的写法
<template>
  <div>{{ foo }}</div>
</template>

<script>
export default {
  props: {
    foo: String,
  },
  created() {
    console.log(this.foo);
  },
}
</script>
// Vue3 的写法
<template>
  <div>{{ foo }}</div>
</template>

<script setup>

// 注意这里
const props = defineProps({
  foo: String
})

// 在 script 标签里使用
console.log(props.foo)
</script>

注意事项——组合式api的心智负担

使用 props 时,同样注意不要使用解构的方式。

<script setup>
const props = defineProps({
  foo: String
})

 // 不要这样写
const { foo } = props;
console.log(foo)
</script>

emits 事件

props相同,声明emits我们可以用defineEmits(),具体写法,我们看代码。
// Vue2 的写法
<template>
  <div @click="onClick">
    这是一个div
  </div>
</template>

<script>
export default {

  emits: ['click'], // 注意这里
  methods: {
    onClick() {
      this.$emit('click'); // 注意这里
    },
  },
 
}
</script>
// Vue3 的写法
<template>
  <div @click="onClick">
    这是一个div
  </div>
</template>

<script setup>

// 注意这里
const emit = defineEmits(['click']);

const onClick = () => {
  emit('click') // 注意这里
}

</script>

computed

直接上写法对比。
// Vue2 的写法
<template>
  <div>
    <span>{{ value }}</span>
    <span>{{ reversedValue }}</span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 'this is a value',
    };
  },
  computed: {
    reversedValue() {
      return value
        .split('').reverse().join('');
    },
  },
}
</script>
// Vue3 的写法
<template>
  <div>
    <span>{{ value }}</span>
    <span>{{ reversedValue }}</span>
  </div>
</template>

<script setup>
import {ref, computed} from 'vue'
const value = ref('this is a value')

// 注意这里
const reversedValue = computed(() => {
  // 使用 ref 需要 .value
  return value.value
    .split('').reverse().join('');
})

</script>

watch

这一部分,我们需要注意一下了,Vue3 中,watch 有两种写法。一种是直接使用watch,还有一种是使用watchEffect

两种写法的区别是:

  • watch需要你明确指定依赖的变量,才能做到监听效果。

  • watchEffect会根据你使用的变量,自动的实现监听效果。

直接使用watch

// Vue2 的写法
<template>
  <div>{{ count }}</div>
  <div>{{ anotherCount }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

<script>
export default {
  data() {
    return {  
      count: 1,
      anotherCount: 0,
    };
  },
  methods: {
    onClick() {
      this.count += 1;
    },
  },
  watch: {
    count(newValue) {
      this.anotherCount = newValue - 1;
    },
  },
}
</script>
// Vue3 的写法
<template>
  <div>{{ count }}</div>
  <div>{{ anotherCount }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

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

const count = ref(1);
const onClick = () => {
  count.value += 1;
};

const anotherCount = ref(0);

// 注意这里
// 需要在这里,
// 明确指定依赖的是 count 这个变量
watch(count, (newValue) => {
  anotherCount.value = newValue - 1;
})

</script>

使用watchEffect

// Vue2 的写法
<template>
  <div>{{ count }}</div>
  <div>{{ anotherCount }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

<script>
export default {
  data() {
    return {  
      count: 1,
      anotherCount: 0,
    };
  },
  methods: {
    onClick() {
      this.count += 1;
    },
  },
  watch: {
    count(newValue) {
      this.anotherCount = newValue - 1;
    },
  },
}
</script>
// Vue3 的写法
<template>
  <div>{{ count }}</div>
  <div>{{ anotherCount }}</div>
  <button @click="onClick">
    增加 1
  </button>
</template>

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

const count = ref(1);
const onClick = () => {
  count.value += 1;
};

const anotherCount = ref(0);

// 注意这里
watchEffect(() => {
  // 会自动根据 count.value 的变化,
  // 触发下面的操作
  anotherCount.value = count.value - 1;
})

</script>

生命周期

Vue3 里,除了将两个destroy相关的钩子,改成了unmount,剩下的需要注意的,就是在<script setup>中,不能使用beforeCreatecreated两个钩子。

如果你熟悉相关的生命周期,只需要记得在setup里,用on开头,加上大写首字母就行。

// 选项式 api 写法
<template>
  <div></div>
</template>

<script>
export default {
  beforeCreate() {},
  created() {},
  
  beforeMount() {},
  mounted() {},
  
  beforeUpdate() {},
  updated() {},
  
  // Vue2 里叫 beforeDestroy
  beforeUnmount() {},
  // Vue2 里叫 destroyed
  unmounted() {},
  
  // 其他钩子不常用,所以不列了。
}
</script>
// 组合式 api 写法
<template>
  <div></div>
</template>


<script setup>
import {
  onBeforeMount,
  onMounted,

  onBeforeUpdate,
  onUpdated,

  onBeforeUnmount,
  onUnmounted,
} from 'vue'

onBeforeMount(() => {})
onMounted(() => {})

onBeforeUpdate(() => {})
onUpdated(() => {})

onBeforeUnmount(() => {})
onUnmounted(() => {})
</script>

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:vue3,setup
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9119次阅读 589人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3884次阅读 289人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14139次阅读 919人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12947次阅读 445人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    11539次阅读 926人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    15646次阅读 1248人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14843次阅读 1209人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    29040次阅读 2281人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    25064次阅读 1931人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录