Vue3.0系列——「vue3.0学习手册」第一期
一、项目搭建
vite是尤大大开发的一款意图取代webpack的工具。其实现原理是利用ES6的import发送请求加载文件的特性。拦截这些请求,做一些编译,省去webpack冗长的打包时间。并将其与Rollup捆绑在一起用于生产。
在开发过程中没有捆绑。源代码中的ES Import语法直接提供给浏览器,浏览器通过本机<script module>支持对其进行解析,从而为每次导入发出HTTP请求。开发服务器拦截请求,并在必要时执行代码转换。例如,对*.vue文件的导入会在发送回浏览器之前即时进行编译。
1、全局安装vite脚手架
npm install -g create-vite-app
2、使用脚手架创建项目
create-vite-app projectName
3、进入项目文件夹
cd projectName
4、安装依赖
npm install
5、启动vue3.0项目
npm run dev
二、vue2.x存在的问题
2.x中的一点问题是当业务不断增多时,数据跟逻辑分散,会很难维护。
<template>
<div>
<div>
<input type="text" v-model="obj.id">
<input type="text" v-model="obj.con">
<button @click="submit">提 交</button>
</div>
<ul>
<li v-for="(item,index) in list" :key="item.id" @click="cli(index)">
{{item.id}}-{{item.con}}
</li>
</ul>
</div>
</template>
<script>
export default {
name:"filterBox",
data(){
return {
list:[
{
id:1,
con:"a"
},
{
id:2,
con:"b"
}
],
obj:{
id:"",
con:""
}
// 代码数据1
// 代码数据2
// ...
}
},
methods:{
cli(index){
this.list = this.list.filter((item,idx)=>idx!==index);
console.log(this.list);
},
submit(){
// const obj = Object.assign({},this.obj);
this.list.push(this.obj);
this.obj.id = "";
this.obj.con = "";
},
// 执行代码代码逻辑3
// ...
},
computed:{
// 执行代码代码逻辑1
},
watch:{
// 执行代码逻辑2
}
}
</script>
<style>
</style>
三、组合API
ref
<template>
<div>
<p>{{count}}</p>
<button @click="add">add</button>
</div>
</template>
<script>
import {ref} from "vue"
export default {
name: 'App',
setup(){
// 定义一个名称叫做count变量,这个变量的初始值是0
// 这个变量发生该改变之后,vue会自动更新页面。
const count = ref(0);
// 在组合API中,如果想定义方法,不用定义到methods中,直接在setup函数中定义即可。
const add = () => {
count.value+=1;
}
// 在组合API中定义的变量/方法,要想在外界使用,必须return出去。
return {
count,
add
}
}
}
</script>
ref只能监听简单类型的变化,不能监听复杂类型的变化(对象/数组)。
它的本质是reactive,当我们给ref函数传递一个值时,ref函数会自动将ref转换成reactive。
ref(0) --> reactive({
value:0
})
另外,需要注意的是,如果是通过ref创建出来的数据,那么在template中使用的时候不用通过.value来获取。因为Vue会自动给我们添加.value 。
那么vue是如何决定是否需要自动添加.value的。vue在解析数据之前,会自动判断这个数据是否是ref类型的,如果是就自动添加.value,如果不是就不自动添加.value。
vue是如何判断当前的数据是否是ref类型的?
通过当前数据的__v_ref来判断的,如果有这个私有的属性,并且取值为true,那么就代表是一个ref类型的数据。
那么我们开发者也有自己api来判断。isRef(数据),返回true或者是false。
import {isRef} from 'vue'
reactive
reactive 可以监听复杂类型的变化,如对象或者数组。
let state = reactive({
name:"maomin"
});
// 或
let arr = reactive([1,2,3]);
<template>
<div>
<ul>
<li v-for="(item,index) in state.list" :key="item.id" @click="removeItem(index)">{{item.id}}--{{item.con}}</li>
</ul>
</div>
</template>
<script>
import {reactive} from "vue"
export default {
name: 'App',
setup(){
const state = reactive({
list:[
{
id:1,
con:"A"
},
{
id:2,
con:"B"
},
{
id:3,
con:"C"
}
]
});
const removeItem = (index) => {
state.list = state.list.filter((item,i)=>i!==index)
}
return {
state,
removeItem
}
}
}
</script>
我们可以改变下,把数据跟逻辑放在一块,这样就解决了vue2.x的数据跟逻辑分散的问题。
<template>
<div>
<ul>
<li
v-for="(item, index) in state.list"
:key="item.id"
@click="removeItem(index)"
>
{{ item.id }}--{{ item.con }}
</li>
</ul>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "App",
setup() {
let {state,removeItem} = userReturn();
return {
state,
removeItem,
};
},
};
function userReturn(params) {
const state = reactive({
list: [
{
id: 1,
con: "A",
},
{
id: 2,
con: "B",
},
{
id: 3,
con: "C",
},
],
});
const removeItem = (index) => {
state.list = state.list.filter((item, i) => i !== index);
};
return {state,removeItem}
}
</script>
我们实现了上面的删除功能,那我们在实现一个添加的功能。
<template>
<div>
<input type="text" v-model="state2.items.id">
<input type="text" v-model="state2.items.con">
<button @click="addItem">添加</button>
<ul>
<li
v-for="(item, index) in state.list"
:key="item.id"
@click="removeItem(index)"
>
{{ item.id }}--{{ item.con }}
</li>
</ul>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "App",
setup() {
let {state,removeItem} = userRemove();
let {state2,addItem} = userAdd(state);
return {
state,
removeItem,
state2,
addItem
};
},
};
// 添加
function userAdd(state) {
const state2 = reactive({
items:{
id:"",
con:""
}
});
const addItem = () => {
const items = Object.assign({},state2.items);
state.list.push(items);
state2.items.id = "";
state2.items.con = "";
};
return {state,state2,addItem}
}
// 删除
function userRemove(params) {
const state = reactive({
list: [
{
id: 1,
con: "A",
},
{
id: 2,
con: "B",
},
{
id: 3,
con: "C",
},
],
});
const removeItem = (index) => {
state.list = state.list.filter((item, i) => i !== index);
};
return {state,removeItem}
}
</script>
如果是其他对象,默认情况下修改对象,界面不会更新。
<template>
<div>
<p>{{state.time}}</p>
<button @click="add">加一天</button>
</div>
</template>
<script>
import {reactive} from 'vue'
export default {
name:"Demo4",
setup(){
const state = reactive(
{
time:new Date()
}
);
function add () {
state.time.setDate(state.time.getDate()+1);
console.log(state);
}
return {
state,
add
}
}
}
</script>
<style>
</style>
如果想更新,可以通过重新赋值的方法。
<template>
<div>
<p>{{ state.time }}</p>
<button @click="add">加一天</button>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "Demo4",
setup() {
const state = reactive({
time: new Date(),
});
function add() {
const newTime = new Date(state.time.getTime());
newTime.setDate(state.time.getDate() + 1);
state.time = newTime;
console.log(state);
}
return {
state,
add,
};
},
};
</script>
<style>
</style>
同样,我们开发者如果要是检测一个数据是否是reactive类型的。可以用isReactive(数据),返回true或者false。
import {isReactive} from 'vue'
四、组合API本质
compositionAPI与optionAPI可以混合使用。其本质是注入。
<template>
<div>
<p>Vue2.x</p>
<button @click="cli1">点击</button>
<p>Vue3.0</p>
<button @click="cli2">点击</button>
</div>
</template>
<script>
import {ref} from "vue"
export default {
name:"Demo2",
data(){
return {
msg:"Vue2.x"
}
},
methods:{
cli1(){
alert(this.msg);
}
},
setup(){
let txt = ref("Vue3.0"); // 注入到data函数内
function cli2() { // 注入到methods属性内
alert(txt.value);
}
return {
txt,
cli2
}
}
}
</script>
<style>
</style>
五、setup执行时机与注意事项
setup函数,是在beforecreate钩子之前完成的。所以无法使用data跟methods。
另外要注意的是setup是同步的,不是异步的。
<template>
<div>
<button @click="name">打开</button>
</div>
</template>
<script>
export default {
name:"Demo3",
data(){
return {
msg:"hello"
}
},
setup(){
function name() {
console.log(this.msg); // undefined
}
return {
name
}
}
}
</script>
<style>
</style>
作者:Vam的金豆之路
主要领域:前端开发
我的微信:maomin9761
微信公众号:前端历劫之路