前言
项目版本:vue3.0.4
vue3.0.3新增的试验性功能
- compiler-sfc: compileScript inline render function mode
- compiler-sfc: new script setup implementation
- compiler-sfc: new SFC css varaible injection implementation
- compiler-sfc: support kebab-case components in
<script setup>
sfc template - runtime-core: explicit expose API
sfc地址
初始化环境
git clone https://github.com/taosiqi/vue3.0.4-demo.git
cd vue3.0.4-demo
yarn
yarn serve
复制代码
script setup
给script添加setup后, 相当于直接在setup()里面写代码,也无需return
<template>
<!-- 案例1-->
<div class="example">
<button @click="reduce">-</button>
<div>{{num}}</div>
<button @click="add">+</button>
</div>
</template>
<script setup>
import { ref } from "vue";
let num=ref(0)
// 这里onMounted没有导入依然可以使用
onMounted:{
num.value=100
}
function reduce(){
num.value-=1
}
function add(){
num.value+=1
}
</script>
<style scoped lang="scss">
.example{
display: flex;
height: 25px;
line-height: 25px;
justify-content: center;
button{
width: 50px;
height: 25px;
}
div{
padding: 0 10px;
}
}
</style>
复制代码
尝试把example的父组件Home修改成script setup
导入组件后,我们并没有components该组件,但是可以正常使用
<template>
<div class="home">
<example :msg="msg"/>
</div>
</template>
<script setup>
import example from '@/components/example.vue'
import { ref } from "vue";
let msg=ref('Welcome to Your Vue.js App')
</script>
复制代码
使用props
props需要用到defineProps
<template>
<!-- 案例2-->
<h1>{{props.msg}}</h1>
</template>
<script setup>
import {defineProps } from "vue";
const props = defineProps({
msg: {
type: String,
},
});
</script>
复制代码
暴露一个方法给父组件
使用ctx.expose来暴露一些方法和属性来供父组件调用。
//父组件
<template>
<div class="home">
<example/>
<example2 :msg="msg"/>
<example3 :ref="(ref)=>{example3Ref=ref}"/>
</div>
</template>
<script setup>
import example from '@/components/example.vue'
import example2 from '@/components/example2.vue'
import example3 from '@/components/example3.vue'
import { ref } from "vue";
let msg=ref('Welcome to Your Vue.js App')
let example3Ref=ref(null)
console.log(example3Ref)
</script>
复制代码
//子组件
<template>
<!-- 案例3-->
<div class="example">
<button @click="reduce">-</button>
<div>{{ num }}</div>
<button @click="add">+</button>
</div>
</template>
<script setup>
import {ref,useContext} from "vue";
const { expose } = useContext();
let num = ref(0)
function reduce() {
num.value -= 1
}
function add() {
num.value += 1
}
expose({
reduce,
})
</script>
<style scoped lang="scss">
.example {
display: flex;
height: 25px;
line-height: 25px;
justify-content: center;
button {
width: 50px;
height: 25px;
}
div {
padding: 0 10px;
}
}
</style>
复制代码
子组件使用expose暴露reduce方法后,父组件只能访问到reduce方法
ref: 语法糖
使用ref:声明一个变量,我们可以直接访问变量的值,不需要加个value,是不是方便了很多。
<template>
<!-- 案例4-->
<div class="example">
<div>{{ num }}
<button @click="check" >check</button>
</div>
</div>
</template>
<script setup>
//其实这里不用导入ref也可以使用
import {ref} from "vue";
ref:num=100
function check(){
num=1
}
</script>
<style scoped lang="scss">
.example {
display: flex;
height: 50px;
width: 50px;
justify-content: center;
align-items: center;
color: red;
background-color: black;
}
</style>
复制代码
CSS v-bind(比var更方便的写法)
当我尝试使用var声明css变量时(var),eslint给出了错误提示(新的提案)。
我们可以使用新的v-bind声明css变量,语法更加简洁,不必在style声明过多的属性。
/* eslint-disable */
<template>
<!-- 案例4-->
<div class="example">
<div>{{ num }}
<button @click="check" >check</button>
</div>
</div>
</template>
<script setup>
import {ref} from "vue";
ref:num=100
ref:color1='red'
ref:color2='green'
const colorArr=['red','green','aquamarine','aquam']
function check(){
const index = Math.floor(Math.random() * colorArr.length)
const index2 = Math.floor(Math.random() * colorArr.length)
color1=colorArr[index]
color2=colorArr[index2]
}
</script>
/* eslint-disable */
<style scoped lang="scss">
.example {
display: flex;
height: 150px;
width: 150px;
justify-content: center;
align-items: center;
color: v-bind(color1);
background-color:v-bind(color2);
}
</style>
复制代码
总结
优点:
- 新的ref语法糖更加方便。
- css v-bind写换肤功能爽的不要不要的
缺点:
- 新的语法糖存在大量不确定性,后期存留是个问题
- 在3.0.4版本中使用var声明css变量,eslint会报错,忽略vue文件检查都无法解决(这锅谁背???)
- eslint-plugin-vue还不支持新语法的检查,后期会修复(可以先关掉)。