前言
版本:vue 3.0.3
最近vue3偷偷的在3.0.3的版本中支持了的实验性的新特性<script setup>
、ref:语法糖
、css v-bind
,现在我们就来尝试一下这几个新特性,最后总结一下目前这几个新特性的问题和优点。
初始化环境
执行命令vue create vue-new-feat
然后选择预设 Default (Vue 3 Preview) ([Vue 3] babel, eslint)
然后cd vue-new-feat
因为eslint-plugin-vue
目前还没有支持新特性的语法检查,所以我们先设置一下eslint
来保证执行的时候不会报错
打开package.json
找到eslintConfig.rules
然后填入以下内容
"no-unused-vars": "off",
"no-unused-labels": "off",
"no-const-assign": "off",
"no-undef": "off",
"vue/no-unused-components": "off"
然后执行npm run serve
探索
script setup
我们先来试试script setup
,首先我们在script标签上写一个setup
绑定变量
我们可以直接在当前的script标签里声明一个ref变量,然后两秒后让他变一个内容
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<span>{{ test }}</span>
</template>
<script setup>
import { ref } from "vue";
const test = ref("new feat");
setTimeout(() => {
test.value = "hello";
}, 2000);
</script>
导入组件并使用
接下来我们试试导入HelloWorld
组件并且使用这个组件
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld :msg="test"></HelloWorld>
<span>{{ test }}</span>
</template>
<script setup>
import HelloWorld from "@/components/HelloWorld";
import { ref } from "vue";
const test = ref("new feat");
</script>
我们发现,我们不需要注册组件就可以直接使用,这波操作还是非常nice的
事件绑定
我们试一下新特性的事件绑定方式
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld :msg="test"></HelloWorld>
<button @click="onClick">点我</button>
</template>
<script setup>
import HelloWorld from "@/components/HelloWorld";
import { ref } from "vue";
const test = ref("new feat");
function onClick() {
alert(123);
}
</script>
点击后成功弹出alert
封装一个组件
接下来我们封装一个MyInput组件看看
MyInput.vue
<template>
<input :value="props.modelValue" @input="onInput" type="text" />
</template>
<script setup>
import { defineEmit, defineProps } from "vue";
const props = defineProps({
modelValue: {
type: String,
},
});
// 这里使用defineProps来实现Options.props的功能
// 并且这个函数的返回值props与setup(props)一样,
// 我们可以在props里访问到用户传来的数据
const emit = defineEmit(["update:modelValue"]);
// 事件的定义使用的是defineEmit来实现Options.emits
// 的功能,他的返回值emit就是ctx.emit,我们可以使用
// emit这个函数发生事件
function onInput(e) {
emit("update:modelValue", e.target.value);
}
console.log(props); // 父组件传来的值
console.log(emit); // 这个和ctx.emit一样,也是用来发事件的
</script>
这个组件的功能是封装的一个输入框来实现双向绑定
我们来使用这个组件
App.vue
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<MyInput v-model="test"></MyInput>
<span>{{ test }}</span>
</template>
<script setup>
import MyInput from "@/components/MyInput";
import { ref } from "vue";
const test = ref("new feat");
</script>
script与script setup一起使用
如果你有想使用script有想使用script setup你可以使用以下的方式,他最后和合并选项
<template>
<input :value="props.modelValue" @input="onInput" type="text" />
</template>
<script>
export default {
name: "MyInput",
};
</script>
<script setup>
import { defineComponent, defineEmit, defineProps } from "vue";
const props = defineProps({
modelValue: {
type: String,
},
});
const emit = defineEmit(["update:modelValue"]);
function onInput(e) {
emit("update:modelValue", e.target.value);
}
</script>
暴露一个属性或方法
新的特性里可以使用ctx.expose(之后可能可以直接到vue里导入expose)来暴露一些方法和属性来供父组件调用。
<template>
<input :value="props.modelValue" @input="onInput" type="text" />
</template>
<script>
export default {
name: "MyInput",
};
</script>
<script setup>
import { defineComponent, defineEmit, defineProps, useContext } from "vue";
const { expose } = useContext();
const props = defineProps({
modelValue: {
type: String,
},
});
const emit = defineEmit(["update:modelValue"]);
function onInput(e) {
emit("update:modelValue", e.target.value);
}
function clear() {
emit("update:modelValue", "");
}
expose({ clear });
//将clear暴露出去
</script>
ref: 语法糖
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<MyInput v-model="test" ref="myInput"></MyInput>
<span>{{ test }}</span>
</template>
<script setup>
import { default as MyInput } from "@/components/MyInput";
import { ref, useContext } from "vue";
ref: myInput = null;
ref: test = "hello";
setTimeout(() => {
myInput.clear();
}, 1000);
</script>
我们可以直接使用ref:
来声明一个Ref类型的变量
在访问的时候可以不使用.value
CSS v-bind
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<div id="app">
<div>{{ test }}</div>
<button @click="color = 'blue'">Blue</button>
<button @click="color = 'red'">Red</button>
</div>
</template>
<script setup>
import { default as MyInput } from "@/components/MyInput";
import { ref, useContext } from "vue";
ref: test = "hello";
ref: color = "red";
ref: mTop = 10;
setTimeout(() => {
mTop = 100;
}, 3000);
</script>
<style>
#app {
text-align: center;
color: v-bind(color);
margin-top: v-bind('mTop + "px"');
}
</style>
我们可以使用v-bind
绑定一个变量或者表达式,注意表达式必须上引号.
总结
经历了一下午的探索,vue3新的特性虽然好用,但还是有一些问题的,如:
script setup
开始就已经说了目前官方的eslint-plugin-vue
还没有支持,所以在团队开发方面目前还是不能使用,所以团队开发不是太推荐,不过个人开发可以用一下,这种新的写法是真的方便
ref: 语法糖
目前在函数作用域内是无法使用的,具体原因请看他的文档,不过未来会支持,而且ref的语法糖可能在未来换另外一种方案,所以不推荐
v-bind
目前感觉不会有太大的变化,在短暂使用后如果项目内想实现主题更换的效果还是比较推荐的
虽然目前还有一些问题没有解决但是我相信在未来时间内vue会越做越好。
最后目前elment3正在处于beta阶段,如果有小伙伴想加入我们,可以访问下面的链接。