不习惯的Vue3起步 の 一:<script setup>
Posted 空城机
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不习惯的Vue3起步 の 一:<script setup>相关的知识,希望对你有一定的参考价值。
序
Vue3虽然说是Vue2的升级版,但里面不一样的地方还是挺多的,并且相比Vue2能更好的使用typescript
了
先从网上找视频学习:https://www.bilibili.com/video/BV1gf4y1W783
目录:
- Vue + TS技术历史变革
- Vite还是Webpack
- Typescript你还不熟?
- 本套实战课程总结
Vue + TS技术历史变革
对于vue和typescript的结合使用,在vue2中就已经出现了,那就是vue-class-component
,但使用起来其实不是很方便,还不如不用typescript
在Vue2 --> Vue3 过渡阶段出现了 @vue/composition-api
和vuex-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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TA5MFe3F-1655814635107)(./img/a_01_vue3/vue3基础-进阶.png)]
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>
现在使用了语法糖之后就不需要写return
和export 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
方法。defineProps
和defineEmits
在语法糖中可以不用引入,不过我在下面的示例中还是写了一下。
子组件:
<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>
使用 slots
和 attrs
的情况应该是很罕见的。可以在模板中通过 $slots
和 $attrs
来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlots
和 useAttrs
两个辅助函数
这里关于$attrs
使用可参考:https://juejin.cn/post/7103271635783778311
这里就不详细展开了
改变5: defineExopse
在setup语法糖中,外部父组件默认是不能使用
r
e
f
s
来
获
取
子
组
件
内
定
义
的
属
性
值
或
调
用
方
法
的
(
在
v
u
e
3
中
,
不
可
以
直
接
使
用
t
h
i
s
.
refs来获取子组件内定义的属性值或调用方法的(在vue3中,不可以直接使用this.
refs来获取子组件内定义的属性值或调用方法的(在vue3中,不可以直接使用this.refs了)。这里<script setup>
类似于形成了一个闭包,所以为了外部能够使用,可以使用defineExopse
将外部需要的属性暴露出去。
父组件:
<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真的不习惯了。
以上是关于不习惯的Vue3起步 の 一:<script setup>的主要内容,如果未能解决你的问题,请参考以下文章