在vue2中我們可以使用計算屬性 computed 去定義一個計算屬性并且去計算
代碼片段:
data() {
return {
num1: 0,
num2: 0,
};
},
computed: {
result() {
return parseInt(this.num1) + parseInt(this.num2);
},
},
我們可以知道是 num1和num2的和等于result
在vue3中我們如何使用computed
代碼:
<template>
<div class="hello">
<h1>{{msg}}</h1>
<input type="text" v-model="state.num1" >
<span> + </span>
<input type="text" v-model="state.num2" >
<span> = </span>
{{state.result}}
</div>
</template>
<script>
import { reactive, computed } from "vue";
export default {
name: "HelloWorld",
props: {
msg: String,
},
setup() {
let state = reactive({
num1: 0,
num2: 0,
result: computed(() => {
return parseInt(state.num1) + parseInt(state.num2);
}),
});
return { state };
},
};
// 方法單獨抽離
// function reacFun() {
// // 聲明
// let state = reactive({
// num1: 0,
// num2: 0,
// result: 0,
// });
// // 邏輯
// let add = () => {
// console.log("123");
// state.result = parseInt(state.num1) + parseInt(state.num2);
// };
// // 傳回
// return { state, add };
// }
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped >
</style>
我們可以看到可以直接在定義的reactive中直接使用computed
let state = reactive({
num1: 0,
num2: 0,
result: computed(() => {
return parseInt(state.num1) + parseInt(state.num2);
}),
});
父子傳值:
vue2 是通過 this.$emit()
vue3是如何傳值呢?
setup()方法接受兩個參數
setup()方法接受兩個參數
- 入參:
-
{Data} props
-
{SetupContext} context
-
interface Data {
[key: string]: unknown
}
interface SetupContext {
attrs: Data
slots: Slots
emit: (event: string, ...args: unknown[]) => void
}
function setup(props: Data, context: SetupContext): Data
我們可以給set傳兩個參數 setup(props,ctx) ,因為es6可以解構 是以我們可以這樣寫 setup(props,{emit})
setup(props,{emit}) {
console.log("setup---props",props)
let state = reactive({
num1: 0,
num2: 0,
result: computed(() => {
return parseInt(state.num1) + parseInt(state.num2);
}),
});
let send = ()=>{
console.log("send",state.result)
emit('sendMsg',state.result)
}
return { state,send };
},
這樣我們就可以把我們父元件傳遞來的 props 直接可以在setup中拿到 直接列印,子元件通過emit向父元件傳參 和vue2方法一樣
父元件:
<template>
<div class="home">
<HelloWorld msg="Welcome to Your Vue.js App" @sendMsg="handler" />
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
setup(){
//子元件傳參
let handler = value => {
console.log("handler",value)
}
return {handler}
}
}
</script>
結論:
父元件 ——> 子元件 :props setup(props,ctx)
子元件 ——> 父元件 :emit setup(props,{emit}){ emit('sendMsg',state.result) } 或 setup(props,ctx) { ctx.emit('sendMsg',state.result) }
注意:
在vue3中使用 emit可能會報錯警告:
Extraneous non-emits event listeners (sendMsg) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option.
問題解決:
export default {
name: "HelloWorld",
emits: ["sendMsg"],//添加這一行解決
props: {
msg: String,
},
setup(props, ctx) {
console.log("setup---props", props);
let state = reactive({
num1: 0,
num2: 0,
result: computed(() => {
return parseInt(state.num1) + parseInt(state.num2);
}),
});
let send = () => {
console.log("send", state.result);
ctx.emit("sendMsg", state.result);
};
return { state, send };
},
};