vue3的学习之路
vue3与vue2对比
1.vue3源码由TS编写,加上react对TS的提倡,TS对于前端来说是有着必学的趋向.
2.vue3采用函数编写,去掉了原来的类的写法
3.重点:去掉了vue2中原有的生命周期函数,并且去掉了data,computed,watch,method等对象,去掉this(这就很舒服)
4.升级后的vue不用担心,他完全兼容vue2的写法,两种写法是可以兼容的.
5.组件中的两种写法,若setup与method中同时存在相同的方法名(会报错),定义的数据,与data中的数据同名,此时的数据会被data的中数据覆盖
setup是所有vue中所有api的入口和出口
setup函数只在生命周期前执行一次,所以是拿不到this的,不能用this.的方式来调用vue2中方法.vue3中同时也去掉了data,但是在setup中给定了return返回来实现模版绑定数据(values),若values是常量,则不会变成响应数据.set函数可以传入两个参数(props,context),之前的this.调用方法的形式可以用context.的方式来调用.
<template>
<div>
<button @click="handleBtn"><button>
<div>{{datat}}</div>
</div>
</template>
export default{
setup(props,context){
function handleBtn(){
......
}
return{
data:data
}
}
}
setup中的生命周期
在setup中的生命周期变成了回掉函数的形式
简单以生命周期执行的过程来列出生命周期函数
<template></template>
<script>
import { onMounted, onUnmounted, onUpdated } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';
export default {
setup(props, context) {
onMounted(() => {
return '组件挂在的时候';
});
onUnmounted(() => {
return '组件卸载的时候';
});
onUpdated(() => {
return '组件更新';
});
onBeforeRouteLeave(() => {
return '组件更新前';
});
onActivated(() => {
console.log('keepAlive 组件 激活');
});
return {
// data不是常量,这里的数据是响应式的
data: data,
};
},
};
</script>
<style scoped></style>
- 使用setup简单的实现响应数据
1.ref可以将某个普通值包装成响应式数据,仅限于简单值,内部是将值包装成对象,再通过defineProperty来处理的
通过ref包装的值,取值和设置值的时候,需用通过value来进行设置
2.可以用ref来获取组件的引用,替代this.$refs的写法
3.主页这里要引入 (自己没引用像个傻逼一样找错误)
import { reactive, ref, toRefs } from ‘vue’;
<template>
<div>
<input v-model="inputValue"/>
<button @click="addValue">添加</button>
<div>{{inputValue}}</div>
<ul>
<li v-for="(item,key) of todoList" :key="key">{{item}}</li>
</ul>
</div>
</template>
<script>
import { reactive, ref, toRefs } from 'vue';
export default {
setup(props, context) {
const inputValue=ref('')
const todoList=ref([])
function addValue(){
todoList.value.push(inputValue.value)
inputValue.value=""
}
return{
addValue,
inputValue,
todoList,
}
}
};
</script>
<style scoped>
</style>
上面用了ref,并且通过value来实现响应数据,现在使用reactive 来实现数据绑定
注意点:
import { reactive, toRefs } from ‘vue’;
function addValue() {
data.todoList.push(data.inputValue);
data.inputValue = ‘’;
}
<template>
<div>
<input v-model="inputValue" />
<button @click="addValue">添加</button>
<div>{{ inputValue }}</div>
<ul>
<li v-for="(item, key) of todoList" :key="key">{{ item }}</li>
</ul>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue';
export default {
setup() {
const data = reactive({
inputVal: '',
todoList: [],
});
function addValue() {
data.todoList.push(data.inputValue);
data.inputValue = '';
}
return {
...toRefs(data),
addValue,
};
},
};
</script>
<style scoped>
.center {
display: flex;
flex-direction: row;
justify-content: center;
}
</style>
1.计算属性,变成了函数写法,当依赖的值发生改变时会重新计算 computed包装后的值,需要用 .value去取值,template中不需要使用.value。
2.响应式API中 computed 和之前的 computed 选项用法类似。
对于任何复杂逻辑,我们都可能使用计算属性。
3.可以使用get() set() 来创建一个可读可写的计算属性
async setup() {
const data = reactive({
a: 10,
b: 20,
});
let sum = computed(() => data.a + data.b);
const computedAge = computed({
get: () => age.value + 1,
set: value => age.value + value
})
return {
sum
computedAge
};
},
<template>
<div>
<h1>{{ text }}</h1>
<button @click="change">count is: {{ state.count }}</button>
<p>Edit <code>components/HelloWorld.vue</code> to test hot module replacement.</p>
</div>
</template>
<script>
import { ref, reactive, computed } from 'vue';
export default {
name: 'HelloWorld',
props: {
msg: String,
},
setup(props) {
let state = reactive({ count: 0 });
let text = computed(() => {
return props.msg.split('').reverse().join('');
});
const change = () => state.count++;
return { state, change, text };
},
};
</script>
watch变成函数后和vue2中的用法差不多
// 侦听一个
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
}
)
// 直接侦听一个ref
const count = ref(0)
watch(count, (count, prevCount) => {
})
//watcheffect 收集依赖,只要count发生改变,就会执行watcheffect中的回掉函数
setTimeout(()=>{count.value+1},1000)
watcheffect(()=>{Consle.log(count)})
wactheffect 和watch的不同点在于wactheffect不需要指定监听属性,他会自动的收集依赖,当我们当中使用响应式属性,当属性发生改变的时候,他会制动的执行其中的回掉函数
使用的时候注意引入就可以了
import {useRoute, useRouter} from 'vue-router'
const route = useRoute(); // 相当于 vue2 中的this.$route
const router = useRouter(); // 相当于 vue2 中的this.$router
route 用于获取当前路由数据
router 用于路由跳转
import {useStore} from 'vuex'
setup(){
const store = useStore(); // 相当于 vue2中的 this.$store
store.dispatch(); // 通过store对象来dispatch 派发异步任务
store.commit(); // commit 修改store数据
let category = computed(() => store.state.home.currentCagegory
return { category }
}
export const AppMenus = defineComponent({
setup() {
return () => {
return (
<div class="app-menus">
<h1>这是一个vue组件</h1>
</div>
);
};
},
});
瞧瞧react的tsx定义组件 (组件逻辑类容删除了)
import React, { useMemo, useCallback, useState, useEffect } from 'react
const LoginLog: React.FC = () => {
const [loading, setLoading] = useState<boolean>(false);
const [userData, setUserData] = useState<[]>([]);
return (
<>
<Title title={'登录日志'} />
<PageWrap>
<SearchForm
onClick={ clickFn }
formList={formList}
actions={actions}
onSearch={onSearch}
onReset={onReset}
></SearchForm>
<BaseTable<any>
data={userData}
page={page}
onChange={onTableChange}
loading={loading}
>
<Table.Column<any>
title="用户"
dataIndex="loginUser"
align="center"
></Table.Column>
<Table.Column<any>
title="登录时间"
dataIndex="loginDate"
align="center"
></Table.Column>
<Table.Column<any>
title="描述"
dataIndex="remark"
align="center"
></Table.Column>
</BaseTable>
</PageWrap>
</>
)
}
export default LoginLog
async setup() {
const data = reactive({
a: 10,
b: 20,
});
let sum = computed(() => data.a + data.b);
return { sum };
}
本文为自己的学习笔记,多为借鉴他人作品,学习作出的总结