写点什么

不习惯的 Vue3 起步一

作者:空城机
  • 2022 年 7 月 08 日
  • 本文字数:3462 字

    阅读完需:约 11 分钟

不习惯的Vue3起步一

Vue3 虽然说是 Vue2 的升级版,但里面不一样的地方还是挺多的,并且相比 Vue2 能更好的使用typescript


先从网上找视频学习:https://www.bilibili.com/video/BV1gf4y1W783


目录:

  1. Vue + TS 技术历史变革

  2. Vite 还是 Webpack

  3. Typescript 你还不熟?

  4. 本套实战课程总结

Vue + TS 技术历史变革

对于 vue 和 typescript 的结合使用,在 vue2 中就已经出现了,那就是vue-class-component,但使用起来其实不是很方便,还不如不用 typescript


在 Vue2 --> Vue3 过渡阶段出现了 @vue/composition-apivuex-composition-helpers


vue3 时代: xxx@next + Vite


Vue3中性能提升较大:

  • 打包大小减少

  • 初次渲染快,更新渲染快

  • 内存减少

  • 使用 Proxy 代替 definePropery 实现数据响应式

  • 重写虚拟 DOM 的实现(把没有用到的 DOM 干掉)和 Tree-Shaking(摇树:在程序中会有一个入口文件作为树的树干,会有很多依赖文件像树的树枝,在打包过程中,会将一些没有用到的代码或文件删掉,让代码变得更紧密)


Vue3 新增特性:

  • 新增 CompositionAPI

  • setup

  • ref 和 reactive

  • computed 和 watch

  • 新的生命周期函数

  • provide 和 inject

  • 新组件

  • Fragment 文档碎片

  • Teleport 瞬移组件的位置

  • Suspense 异步加载组件的 loading 界面

Vite 还是 Webpack

Vite 是 vue3 本身推荐的构建工具,编译速度非常快


webpack 是老牌构建工具,vue2 时代 vue cli 这样的打包都是需要用到


如果就是要用 vue 开发,并且针对的浏览器版本较高,不需要兼容开发的,那么推荐使用 Vite


Vite 的世界

Vite 中文网 https://vitejs.cn/


先在 vs code 中打开终端,使用 yarn 创建一个 vite 项目: yarn create vite first-vite-demo --template vue


PS: 在视频教程中使用的 vue3 版本比我的要早一些了,我的是 vue3.2.x 了,所以会有一些不同。

错误 1

我这里遇到了一个警告和一个错误,警告是 yarn 版本过低了,错误是


警告通过升级 yarn 即可消除,npm install --global yarn


错误是说C:\Program 不是内部或外部命令,也不是可运行的程序或批处理文件


这里解决的方式有挺多的,不过我选择了重新安装 node,具体安装可参考:https://www.jianshu.com/p/30ba1da2bde1 。这里需要把 yarn 全局位置也配置一下。


现在就可以使用命令正确创建了:


创建出来的项目结构:




然后可以使用yarn dev运行项目,打开默认的 url 地址



可以看到页面正常运行出来了,不过当我打开 src 文件夹中的 App.vue 时会在界面上出现一个红色波浪线报错,虽然不会影响程序的运行,但是还是看着很不舒服


错误 2

这主要是因为插件vetur的关系,在 vue2 中,template 只能有一个根元素,但是在 vue3 中则没有这个限制,所以可以对vetur检查语法功能设置进行修改。


将里面的 Template 勾选取消,然后重启 vs code,这样重新打开App.vue就不会出现红色波浪线了




入口文件

在程序中,依旧还是以 main.js 为主干,是程序的入口文件。在 vue2 中,创建 vue 实例使用new Vue,而在 vue3 中则是可以直接使用createApp方法


// 程序入口文件,主干// createApp用来创建vue3的实例import { createApp } from 'vue'// 引入App组件import App from './App.vue'// 创建App应用返回对应的实例对象,调用mount方法进行挂载createApp(App).mount('#app')
复制代码

引入组件

在 Vue3 中,使用 vite 创建的示例里,App.vue 中引入使用HelloWorld组件,并没有写components包括,这是因为使用了setup


setup 语法糖

关于单文件组件<script setup>介绍:



基本语法:<script setup>,在原始的 script 标签上附加上 setup

改变 1: 组件自动注册

像上面示例所说,使用了 setup 语法糖之后,组件直接 import 引入进来就可以使用了

改变 2:属性和方法直接在template中使用,无需 return 返回

之前 vue3.0 中会有一个setup函数,要暴露变量必须 reutrn 出来,这样才能在template中使用。(当然目前 3.2 也是同样支持这样写的)

<template>    <h1>{{ num1 }}</h1>
</template>
<script>import { ref } from 'vue'
export default { name: 'Basic', setup() { let num1 = ref(123) return { num1 } }}</script>
复制代码


现在使用了语法糖之后就不需要写returnexport default了,直接定义使用即可。同样也能达到上面的效果:


<template>    <h1>{{ num1 }}</h1>
</template>
<script setup> import { ref } from 'vue'
let num1 = ref(123);</script>
复制代码

改变 3:关系组件的数据传递

在 3.0 版本中,因为使用的是 setup 函数,可以将 props 数据存放作为参数传入。

export default {    name: 'Basic',    props: {        name: String,        age: Number    },    setup(props) {        console.log(props.name, props.age)        return { }    }}
复制代码


PS: 这里对于 props 数据的解析,使用 es6 的解构方式有问题,会消除 prop 的响应性。


这里举一个例子,点击按钮改变数值,但是在子组件中,使用 es6 解构出来的数值不会随之改变,需要使用toRefs方法进行解构。


父组件:

<template>  <Basic name="张三" :age="age"></Basic>  <button @click="change()">改变</button></template>
<script setup> import Basic from './components/Demo/Basic.vue' import { ref } from 'vue' let age = ref(15) function change() { age.value++ }</script>
复制代码


子组件:


<template>    <h1>{{ age1 }} : {{ age2 }}</h1></template>
<script>import { ref, toRefs } from 'vue'export default { name: 'Basic', props: { name: String, age: Number }, setup(props) { // es6解构 let { name: name1, age: age1 } = props;
// 响应式状态解构toRefs let { name: name2, age: age2 } = toRefs(props)
return { age1, age2, } }}</script>
复制代码


效果:可以看到 es6 解构出来的数值只是固定的,不会随父组件中数值变化而响应式改变。


说完 3.0,现在来看看 3.2 使用语法糖之后的用法:


对于 props 的接收可以使用defineProps方法,如果需要给父组件传值可以使用defineEmits方法。definePropsdefineEmits在语法糖中可以不用引入,不过我在下面的示例中还是写了一下。


子组件:

<template>    <h1>{{ age }}</h1>    <button @click="setupChange"> setup语法糖改变 </button></template>
<script setup> import { ref, defineProps, defineEmits } from 'vue' // 获取props let props = defineProps({ age: Number }) // 传值 let emits = defineEmits(['father-change']) let setupChange = () =>{ emits('father-change', props.age + 2) }</script>
复制代码


父组件:

<BasicSetup :age="age" @fatherChange="fatherChange"></BasicSetup>
复制代码


效果:


改变 4:获取 attrs 和 slots

一般而言,在<script setup> 使用 slotsattrs 的情况应该是很罕见的。可以在模板中通过 $slots$attrs 来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlotsuseAttrs 两个辅助函数


这里关于$attrs使用可参考:https://juejin.cn/post/7103271635783778311


这里就不详细展开了

改变 5: defineExpose

在 setup 语法糖中,外部父组件默认是不能使用refs 了)。这里<script setup>类似于形成了一个闭包,所以为了外部能够使用,可以使用defineExpose将外部需要的属性暴露出去。


父组件:

<template>  <BasicSetup :age="age" @fatherChange="fatherChange"    dataStatus="activated" ref="basic2"  ></BasicSetup>
<button @click="change()">改变</button></template>
<script setup> import BasicSetup from './components/Demo/BasicSetup.vue' import { ref, onMounted } from 'vue'
...... // 这里basic2名称要与上面子组件定义的ref名称相同 let basic2 = ref() // 这里需要在onMounted中,否认是undefined onMounted(() => { console.log(basic2.value.setupchild); // 100 });
</script>
复制代码


子组件:

<script setup>    ......    let setupchild = 100;    defineExpose({        setupchild    });</script>
复制代码




暂时先告一段落,看<script setup>语法糖就花了好久。


可能是我刚刚开始学习Vue3的关系吧,<script setup>感觉代码量多了会很复杂,看起来更加不清晰了,而且可能从setup函数看还有点 vue2 的影子,这个语法糖真的就和 vue2 完全不一样了。


挺多东西要推翻重来的,没有 this 真的不习惯了。

发布于: 刚刚阅读数: 5
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
不习惯的Vue3起步一_Vue3_空城机_InfoQ写作社区