1. setup 函数有哪些参数--props
1.1 父组件App.vue
<template>
<div>
<home-page id="aaa" class="bbb" :message="'哈哈我是胡振楚'">
<template>
<div>我是胡振楚</div>
</template>
</home-page>
</div>
</template>
<script>
import HomePage from "@/01_setup函数的基本使用/01_setup 函数有哪些参数--props.vue";
export default {
name: "App",
components: {
HomePage,
},
};
</script>
<style>
</style>
1.2 子组件
<template>
<div>Home Page</div>
<h2>{{ message }}</h2>
<h2>{{ messageInfo }}</h2>
</template>
<script>
export default {
name: "homePage",
props: {
// 在Vue3.0 中这个也是需要写的
message: {
type: String,
required: true,
},
},
/**
*
* setup 函数有哪些参数? 他主要是有两个参数
* -- 第一个参数: props 父组件传递过来的属性
* -- 第二个参数: context
*
* **/
setup(props, context) {
console.log(props); // 从父组件中传递过来的数据
console.log(context);
const messageInfo = props.message
return {
messageInfo
}
},
// setup函数有什么样的返回值
};
</script>
<style>
</style>
实际截图:
image.png
2.setup 函数有哪些参数--context
2.1 子组件
<template>
<div>Home Page</div>
</template>
<script>
export default {
name: "homePage",
/**
*
* setup 函数有哪些参数? 他主要是有两个参数
* -- 第二个参数: context: 参数是context,我们也称之为是一个SetupContext,它里面包含三个属性:
* -- 1. attrs:所有的非prop的attribute;
* -- 2. slots:父组件传递过来的插槽
* -- 3. emit:当我们组件内部需要发出事件时会用到emit
* **/
setup(props, context) {
console.log(context);
// 1.attrs:所有的非prop的attribute;
console.log(context.attrs); // {id: 'aaa', class: 'bbb', __vInternal: 1}
// 2.slots:父组件传递过来的插槽
console.log(context.slots);
// 3. emit 事件
console.log(context.emit);
},
};
</script>
<style>
</style>
实际截图
image.png
3.setup函数的返回值
<template>
<div>
<h1>setup函数的返回值</h1>
<h2>{{ message }}</h2>
<hr />
<h2>当前计数: {{ counter }}</h2>
<!-- 1. 如何在setup中去定义一个功能函数 -->
<button @click="add"> + 1 </button>
</div>
</template>
<script>
export default {
name: "HomePage",
setup() {
/**
* setup函数的返回值,它的返回值用来做什么呢?
* -- 也就是说我们可以通过setup的返回值来替代data选项;
* -- setup的返回值可以在模板template中被使用;
*
* **/
// 1. 如何在setup中去定义一个功能函数
let counter = 100
const add = ()=> {
counter ++; // 这种直接++ 是不会更新界面的
}
return {
message: "Hello Setup function!",
counter,
add
};
},
};
</script>
<style>
</style>
实际截图
image.png
4. setup 函数中没有this
<template>
<h1>setup不可以使用this</h1>
</template>
<script>
export default {
/**
* setup不可以使用this
* -- 表达的含义是this并没有指向当前组件实例;
*
* -- 并且在setup被调用之前,data、computed、methods等都没有被解析;
*
* -- 在setup中你应该避免使用this,因为他不会找到组件实例.setup的调用发生在data property,computed 或methods被解析之前,
* 所以他们无法在setup中被获取
*
* -- 所以无法在setup中获取this;
* **/
setup() {
console.log(this); // undefined
}
}
</script>
<style>
</style>
实际截图
image.png
5.setup函数中实现响应式-Reactive的使用
<template>
<div>
<!-- PS: 这种return出去的是一个对象,所以上面template模板中的话需要 state.counter取值 -->
<!-- <h1>当前计数:{{ state }}</h1> -->
<h1>当前计数:{{ state.counter }}</h1>
<button @click="add">实现 + 1 的响应式处理</button>
</div>
</template>
<script>
// 1.想要是响应式的话需要引入一个vue内置函数-reactive函数
import { reactive } from "vue";
export default {
setup() {
// 1. 使用这个reactive内置函数
const state = reactive({
counter: 100,
});
console.log(state); // 这种打印拿到的是一个对象 {counter: 100}
// 定义一个 add 函数
const add = () => {
state.counter++; // 这种就可以做到响应式的了
};
return {
state, // 这种return出去的是一个对象,所以上面template模板中的话需要 state.counter取值
add,
};
},
};
</script>
<style>
</style>
实际截图
image.png
6.setup函数中实现响应式-Ref的使用
<template>
<div>
<!-- 这个地方 其实vue 做了一个解包的过程,不需要state.value 直接写state他会给你自动解包 -->
<!-- 在template中是有自动解包功能的,在setup中是没有自动解包功能的 -->
<h1>当前计数:{{ state }}</h1>
<button @click="add">实现 + 1 的响应式处理</button>
</div>
</template>
<script>
// 1.想要是响应式的话需要引入一个vue内置函数-Ref函数
import { ref } from "vue";
export default {
setup() {
// 1. 使用这个Ref内置函数
let state = ref(100);
console.log(state); // 这种打印拿到的是一个对象 {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: 100, _value: 100}
// 定义一个 add 函数
const add = () => {
// PS: 在template中是有自动解包功能的,在setup中是没有自动解包功能的
state.value++; // 这种就可以做到响应式的了,所以这里必须要state.value
};
return {
state,
add,
};
},
};
</script>
<style>
</style>
实际截图
image.png
7.setup函数-refAPI浅层解包
<template>
<div>
<h1>当前计数:{{ counter }}</h1>
<button @click="add">实现 + 1 的响应式处理</button>
<hr>
<!-- 2. 理解浅层解包,如果里面套的层级超过两层就不会自动解包了,这种情况就叫做浅层解包 -->
<h1>理解浅层解包:{{info}}</h1>
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
// 1.属于浅层解包
let counter = ref(100);
// 2. 理解浅层解包 把counter放入到一个info对象中
let info = {
counter
}
const add = () => {
counter.value++;
};
return {
counter,
info, // 2. 理解浅层解包,如果里面套的层级超过两层就不会自动解包了,这种情况就叫做浅层解包
add,
};
},
};
/**
*
* PS: ref的解包只能是一个浅层的解包
*
*
* **/
</script>
<style>
</style>
实际截图
image.png
8.setup函数-refAPI浅层解包-可以深层解包
<template>
<div>
<h1>当前计数:{{ counter }}</h1>
<button @click="add">实现 + 1 的响应式处理</button>
<hr />
<!-- 2. 理解浅层解包,如果里面套的层级超过两层就不会自动解包了,这种情况就叫做浅层解包 -->
<h1>理解浅层解包:{{ info }}</h1>
<!-- 3.这种情况是可以解包的 -->
<h1>使用reactive是可以解包的:{{ reactiveInfo.counter }}</h1>
</div>
</template>
<script>
import { reactive, ref } from "vue";
export default {
setup() {
// 1.属于浅层解包
let counter = ref(100);
// 2. 理解浅层解包 把counter放入到一个info对象中
let info = {
counter,
};
// 3.这种情况是可以解包的
const reactiveInfo = reactive({
counter,
});
const add = () => {
counter.value++;
};
return {
counter,
info, // 2. 理解浅层解包,如果里面套的层级超过两层就不会自动解包了,这种情况就叫做浅层解包
add,
reactiveInfo, // 3.这种情况是可以解包的
};
},
};
/**
*
* PS: ref的解包只能是一个浅层的解包
*
*
* **/
</script>
<style>
</style>
实际截图
image.png
9. setup函数-readOnly
<template>
<div>
<h2>{{ readonlyInfo1.name }}</h2>
<button @click="updateState1">readonly只读方法一</button>
<hr />
<h2>{{ readonlyInfo2.name }}</h2>
<button @click="updateState2">readonly只读方法二</button>
<hr />
<h2>{{ readonlyInfo3 }}</h2>
<button @click="updateState3">readonly只读方法三</button>
</div>
</template>
<script>
/**
* 1. 只读方法 readonly
* 需求: 我们通过reactive或者ref可以获取到一个响应式的对象,但是某些情况下,我们传入给其他地方(组件)的这个
* 响应式对象希望在另外一个地方(组件)被使用,但是不能被修改,这个时候如何防止这种情况的出现呢?
* -- Vue3为我们提供了readonly的方法;
*
* readonly会返回原生对象的只读代理(也就是它依然是一个Proxy,这是一个proxy的set方法被劫持,并且不
* 能对其进行修改);
*
*
* 2.在开发中常见的readonly方法会传入三个类型的参数:
* -- 类型一:普通对象;
* -- 类型二:reactive返回的对象;
* -- 类型三:ref的对象;
* **/
import { ref, readonly, reactive } from "vue";
export default {
setup() {
// 1. 普通对象
const info1 = { name: "hzc" };
const readonlyInfo1 = readonly(info1);
const updateState1 = () => {
readonlyInfo1.name = "chuchuhu"; // 报警告:Set operation on key "name" failed: target is readonly. {name: 'hzc'}
};
// 2.响应式对象
const info2 = reactive({
name: "huzhenchu",
});
const readonlyInfo2 = readonly(info2);
const updateState2 = () => {
readonlyInfo2.name = "胡振楚"; // 报警告: Set operation on key "name" failed: target is readonly. Proxy {name: 'huzhenchu'}
};
// 2.响应式对象
const info3 = ref("huzhenchu");
const readonlyInfo3 = readonly(info3);
const updateState3 = () => {
readonlyInfo3.value = "胡振楚"; // 报警告:Set operation on key "value" failed: target is readonly.
};
/**PS: 不管你是响应式的还是普通的对象 只要是用了readonly的话他就不可以修改**/
return {
updateState1,
updateState2,
readonlyInfo1,
readonlyInfo2,
readonlyInfo3,
updateState3,
};
},
};
</script>
<style>
</style>
实际截图
image.png
网友评论