文章目录
二、 setup的两个注意点
2-1-1 set的两个参数: props,context
-
setup执行的时机:
- 在beforeCreate之前执行一次,this是undefined
-
setup的两个参数:
- props: 值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性
- attrs帮忙兜底
- context: 上下文对象
- attrs: z值为对象,包含: 组件外部传递过来,但没有在props配置中声明的属性,相当于
this.$attrs
- slots:收到的插槽内容,相当于:
this.$slots
- emit: 分发自定义事件的函数,相当于
this.$emit
- attrs: z值为对象,包含: 组件外部传递过来,但没有在props配置中声明的属性,相当于
- props: 值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性
-
两个参数
setup(props, context) {
console.log("--setup--", props);
console.log("--setup--", context);
}
2-1-2 props与emits【子像父传递参数,父向子传递参数】
2-1-2-1 父组件App.vue
<template>
<div id="app">
<h1>我是Vue2写的效果</h1>
<Demo @hello="showHelloMsg" msg="信息" school="TYUT">
<template v-slot:qwe>
<span>具名插槽一</span>
</template>
<!-- <template v-slot="test2">
<div>
<h2>剧名插槽2</h2>
</div>
</template> -->
</Demo>
</div>
</template>
<script>
import Demo from "./components/Demo.vue";
export default {
name: "App",
components: { Demo },
setup() {
function showHelloMsg(value) {
alert(`你好啊,我出发了hello事件,我收到的参数是${value}`);
}
return {
showHelloMsg,
};
},
};
</script>
2-1-2-2 子组件Demo.vue
<template>
<div>
<h1>一个人的信息</h1>
<button @click="test">测试触发一下Demo组件的Hello事件</button>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "Demo",
props: ["msg"],
emits: ["hello"],
setup(props, context) {
console.log("--setup--", props);
console.log("--setup--", context); // attrs,emit,slots
// 数据
let person = reactive({
name: "张三",
age: 18,
});
// 方法
function test() {
context.emit("hello", 777);
}
return {
person,
test,
};
},
};
</script>
三、计算属性computed + watch
3-1 computed
-
import {reactive,computed} from 'vue' export default { name: 'Demo', setup() { let person = reactive({ fN: '张', lN: '三' }) // 计算属性:没有考虑计算属性被修改的情况 person.fullName = computed(() => { return person.firstName + '-' + person.lastName }) // 计算属性-完整写法 person.fullName = computed({ get() { return person.fN + '_' + person.lN }, set(value) { const nameArr = value.split('_') person.fN = nameArr[0] person.fN = nameArr[1] } }) } }
3-2 watch
3-2-1 两个小坑
-
两个小坑
-
监视reactive所定义的一个响应式数据时:
- oldValue无法获取、强制开启了深度监视(deep配置失效)
-
监视reactive定义的响应式数据中某个属性时:deep配置有效
-
3-2-2 监视的几种情况及结果展示
- 监视的几种情况【总的例子】
<template>
<div>
<h1>当前求和为: {{ sum }}</h1>
<h1>msg:{{ msg }}</h1>
<button @click="sum++">点我+1</button>
<h2>姓名: {{ person.name }}</h2>
<h2>年龄: {{ person.age }}</h2>
<button @click="person.age++">增长年龄</button>
</div>
</template>
<script>
import { ref, watch, reactive } from "vue";
export default {
name: "Demo",
// vue2
// watch: {
// sum(oldValue, NewValue) {
// console.log("sum的值改变了,newValue,oldValue");
// },
// // sum: {
// // immediate: true,
// // deep: true,
// // handler(newValue, oldValue) {},
// // },
// },
setup() {
// 数据
let sum = ref(0);
let msg = ref("你好");
let person = reactive({
name: "张三",
age: 18,
});
// 监视
// 情况一:监视ref所定义的多个响应式数据
watch(
[sum, msg],
(newValue, oldValue) => {
console.log("sum变了", newValue, oldValue);
},
{ immediate: true }
);
// 情况二:监视reactive所定义的一个响应式数据的全部属性
// 此处无法正确获取oldValue
// 强制开启了深度监视(deep配置无效)
watch(person, (nV, oV) => {
console.log("person变化了", nV, oV);
});
// 情况三:监视reactive所定义的一个响应式数据中的某个属性
watch(
() => person.age,
(nV, oV) => {
console.log("person变化了", nV, oV);
},
{ deep: false }
);
// 情况四:监视reactive所定义的一个响应式数据中的某些属性
watch([() => person.name, () => person.age], (newValue, oldValue) => {
console.log("person的name或age变化了", newValue, oldValue);
});
// 特殊情况,监视person.job
watch(
() => person.job,
(nV, oV) => {
console.log("person的job变化了", newValue, oldValue);
},
{ deep: true } // 此处由于监视的时reactive定义的对象中的某个属性,所以deep配置有效
);
// 返回一个对象
return {
sum,
msg,
person,
};
},
};
</script>
- 情况一:监视ref所定义的多个响应式数据
watch(
[sum, msg],
(newValue, oldValue) => {
console.log("sum变了", newValue, oldValue);
},
{ immediate: true }
);
- 情况二:监视reactive所定义的一个响应式数据的全部属性
// 此处无法正确获取oldValue
// 强制开启了深度监视(deep配置无效)
watch(person, (nV, oV) => {
console.log("person变化了", nV, oV);
},{deep:false}); // deep配置无效
- 情况三:监视reactive所定义的一个响应式数据中的某个属性
watch(
() => person.age,
(nV, oV) => {
console.log("person变化了", nV, oV);
},
{ deep: false }
);
- 情况四:监视reactive所定义的一个响应式数据中的某些属性
watch([() => person.name, () => person.age], (newValue, oldValue) => {
console.log("person的name或age变化了", newValue, oldValue);
});
3-2-3 watch时value的问题
3-3 watchEffect
-
watchEffect(() => { const x1 = sum.value; const x2 = person.job; console.log("watchEffect所指定的回调执行了"); });
-
- watch的套路: 既要指明监视的属性,也要指明监视的回调
- watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
- watchEffect有点像computed:
- 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值
- 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值
四、生命周期
4-1-1
-
- beforeCreate —> setup()
- created —> setup()
- beforeMount ===> onBeforeMount
- mounted —> onMounted
- beforeUpdate —>onBeforeUpdate
- updated —> onUpdated
- beforeUnmount —> onBeforeUnmount
- unmounted-----> onUnmounted
4-1-2
- 配置项及组合API的生命周期钩子
<template>
<div>
<h1>当前求和为: {{ sum }}</h1>
<h1>msg:{{ msg }}</h1>
<button @click="sum++">点我+1</button>
</div>
</template>
<script>
import {
ref,
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
} from "vue";
export default {
name: "Demo",
setup() {
let sum = ref(0);
let msg = ref("你好");
onBeforeMount(() => {
console.log("---beforeMount--");
});
onMounted(() => {
console.log("---mounted--");
});
onBeforeUpdate(() => {
console.log("---beforeUpdata--");
});
onUpdated(() => {
console.log("---updated--");
});
onBeforeUnmount(() => {
console.log("---beforeUpdata--");
});
onUnmounted(() => {
console.log("---updated--");
});
return {
sum,
msg,
};
},
// // 通过配置项的形式使用生命周期钩子函数
// beforeCreate() {
// console.log("---beforeCreate--");
// },
// created() {
// console.log("---created--");
// },
// beforeMount() {
// console.log("---beforeMount--");
// },
// mounted() {
// console.log("---mounted--");
// },
// beforeUpdate() {
// console.log("---beforeUpdata--");
// },
// updated() {
// console.log("---updated--");
// },
// beforeUnmount() {
// console.log("---beforeUpdata--");
// },
// unmounted() {
// console.log("---updated--");
// },
};
</script>