vue3 composition API setup(){}的使用
<template>
<div>
setup
<!-- ref创建的数据对象在teplate内不需要.value -->
{{ count }}
double:{{ double }} age: {{ user.age }}
<button ref="btn" @click="handleClick">click</button>
<button @click="handleChangeUserAge">change - age</button>
</div>
</template>
<script>
/* 引入setup中需要用到的方法
ref 创建要使用.value的响应式数据,类似JS中的number string,
ref 创建单一数据对象,来创建对象也需要使用.value来修改
reactive 创建proxy的响应试数据,类似JS中的object,创建对象形数据对象
readonly 创建一个不能修改的reactive
computed 创建计算属性响应式对象
watch 监听响应式数据
watchEffect 监听组件内所有数据的变化,第一次创建会自动执行
*/
import {ref, reactive, readonly, computed, watch, watchEffect} from "vue";
export default {
name: "HelloWorld",
//父组件传进来的props对象
props: {
msg: String,
},
created() {
// ....
},
//setup 内获取到父组件传进来的props,setup(props){},props不能修改
setup(props) {
// 新的 composition api 出现的
// 当前组件初始化的入口
// 响应式数据对象
//ref创建数据对象
let count = ref(1);
// 和 ref 类型一致 ,都要有.value,来读取/修改数据
const double = computed(() => {
return count.value * 2;
});
// 计算属性创建的响应式对象和依赖属于一致
//reactive创建数据对象
// 引入类型 对象 数组
let user = reactive({ name: "xiaohong", age: 18 });
//readonly 创建数据对象
//readonly 不可以修改的
const readonlyUser = readonly({ name: "xiaohong", age: 18 });
//在内部创建的Function,只要return出去,就可以在外部使用
const handleClick = (e) => {
console.log(e);
// console.log(count)
// value 有点心理负担
count.value++;
// eslint
};
//wacth监听ref创建的数据
watch(count,(newValue, oldValue) => {
console.log("watch - count");
console.log(newValue, oldValue);
},{
immediate: true,
}
);
//wacth监听reactive创建的数据对象单值
watch(() => user.age,(newVal, oldVal) => {
console.log("watch -- user.age");
console.log(newVal);
console.log(oldVal);
}
);
watchEffect(() => {
// 函数
// 1. 不需要详细的指定观察谁
// 2. 它获取不到之前的值
console.log("watch-effect");
console.log(user.age);
});
// 必须返回一个对象
// 返回的数据 就是暴露给 template 用的
return {
btn,
handleChangeUserAge,
handleClick,
count,
user,
double,
};
},
};
</script>
vue3 生命周期对比
生命周期使用
<template>
<div>
setup
<button ref="btn" >click</button>
</div>
</template>
<script>
/* 引入setup中需要用到的方法
onMounted 引入的生命周期函数
*/
import {onMounted} from "vue";
export default {
name: "HelloWorld",
created() {
// ....
},
//setup 替代vue2 的created生命周期
setup(props) {
//在vue2中使用created和beforeCreated的函数,可放在这里
// 生命周期函数 onMounted可以有多个
onMounted(() => {
console.log("mounted - 1");
});
onMounted(() => {
console.log("mounted - 2");
});
// refs获取dom元素
const btn = ref(null);
onMounted(() => {
//
console.log(btn);
});
return {
//导出setup的函数
};
},
};
</script>
为什么引入composition api
A、更好的代码组织与逻辑复用 更好的代码组织,可以把同一功能的代码集中到一块。不需要反复横跳。
<template>
<div>
foo
{{ one }}
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
// 在setup中引入代码的组合
// 功能1
// 代码组织方式的全新变更
// 组合的思想
// 多用组合 少用继承
// vue3 函数式编程的思想
// 一个函数 是不是就是可以复用的
const { one } = oneFeature();
// const { two } = twoFeature();
// const { three } = threeFeature();
return {
one,
};
},
};
function oneFeature() {
const one = ref("one");
const oneF = () => {
console.log(one);
};
return {
one,
oneF,
};
}
</script>
<style></style>
更好的逻辑复用 uerMove.js
//引入需要用到的JS
import {ref, onMounted, onUnmounted } from "vue";
export function useMove() {
const x = ref(0);
const y = ref(0);
const handleKeyup = (e) => {
console.log(e.code);
// 上下左右 x y
switch (e.code) {
case "ArrowUp":
y.value--;
break;
case "ArrowDown":
y.value++;
break;
case "ArrowLeft":
x.value--;
break;
case "ArrowRight":
x.value++;
break;
}
};
onMounted(() => {
window.addEventListener("keyup", handleKeyup);
});
onUnmounted(() => {
window.removeEventListener("keyup", handleKeyup);
});
return {
x,
y,
};
}
调用uerMove.js的Foo.vue
<template>
<div>{{ x }} -- {{ y }}</div>
</template>
<script>
import { useMove } from "./useMove";
export default {
// fooMixin x,y
// 1. 来源不清晰
// 2. 命名冲突
// mixins: [MoveMixin, fooMixin, barMixin, otherMixin],
setup() {
// 来源清晰
// 命名冲突
// const { x, y } = useMove();
// const { x: XXA, y: XXB } = useXX();
return {
x,
y,
};
return { x, y };
},
};
</script>
B、更好的类型推导
响应式对象丢失解决方法:
原因:是因为在setup内解构,造成响应对象丢失:
setup(){
let position = reactive(x:0,y:0)
//响应式对象丢失
const { x, y } = position;
return{
x,
y
}
}
解决方法
import { toRefs } from "vue";
setup(){
let position = reactive(x:0,y:0)
//解决响应式对象丢失
const { x, y } = toRefs(position);
return{
x,
y
}
}