Setup函数
Setup函数 vue 3.0setup是一个新的组件选项,作为组件中使用组合API的起点。从组件生命周期来看,它的执行在组件实例创建之前vue2.x的beforeCreate执行。这就意味着在setup函数中this还不是组件实例,this此时是undefined在模版中需要使用的数据和函数,需要在setup返回。<template><div class="container"
Setup vue 3.0
- setup是一个新的组件选项,作为组件中使用组合API的起点。
- 从组件生命周期来看,它的执行在组件实例创建之前vue2.x的beforeCreate执行。
- 这就意味着在setup函数中this 还不是组件实例,this此时是undefined
-
在模版中需要使用的数据和函数,需要在setup返回。
<template> <div class="container"> <h1 @click="say()">{{msg}}</h1> </div> </template> <script> export default { setup () { console.log('setup执行了') console.log(this) // 定义数据和函数 const msg = 'hi vue3' const say = () => { console.log(msg) } return { msg , say} }, beforeCreate() { console.log('beforeCreate执行了') console.log(this) } } </script>
总结:setup组件初始化之前执行,它返回的数据和函数可在模版使用
Setup vue 3.2
script setup 语法糖
<script setup></script>
1. 属性和方法无需返回,直接使用
在添加了setup的script标签中,我们不必声明和方法,这种写法会自动将所有顶级变量、函数,均会自动暴露给模板(template)使用 。
<template>
<div>
// 调用方法
<button @click='changeName'>name</button>
</div>
</template>
<script setup>
import { ref} from 'vue'
const name= ref('Jerry')
// 声明method方法
const changeName = () => {
name.value = 'Tom'
}
</script>
reactive
, computed
, 也一样可以使用:
<template>
<div>{{msg}}</div>
<div>{{obj.a}}</div>
<div>{{sum}}</div>
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
const msg = ref('hello vue3');
const obj = reactive({
a: 1,
b: 2
})
const sum = computed(() => {
return obj.a + 3;
});
</script>
2. 组件自动注册
<template>
<Child />
</template>
<script setup>
import Child from '@/components/Child.vue'
</script>
组合API-父子通讯 vue3.0
父传子:
<template>
<div class="container">
<h1>父组件</h1>
<p>{{money}}</p>
<hr>
<Son :money="money" />
</div>
</template>
<script>
import { ref } from 'vue'
import Son from './Son.vue'
export default {
name: 'App',
components: {
Son
},
// 父组件的数据传递给子组件
setup () {
const money = ref(100)
return { money }
}
}
</script>
<template>
<div class="container">
<h1>子组件</h1>
<p>{{money}}</p>
</div>
</template>
<script>
import { onMounted } from 'vue'
export default {
name: 'Son',
// 子组件接收父组件数据使用props即可
props: {
money: {
type: Number,
default: 0
}
},
setup (props) {
// 获取父组件数据money
console.log(props.money)
}
}
</script>
子传父:
<template>
<div class="container">
<h1>父组件</h1>
<p>{{money}}</p>
<hr>
+ <Son :money="money" @change-money="updateMoney" />
</div>
</template>
<script>
import { ref } from 'vue'
import Son from './Son.vue'
export default {
name: 'App',
components: {
Son
},
// 父组件的数据传递给子组件
setup () {
const money = ref(100)
const updateMoney = (newMoney) => {
money.value = newMoney
}
return { money , updateMoney}
}
}
</script>
<template>
<div class="container">
<h1>子组件</h1>
<p>{{money}}</p>
<button @click="changeMoney">花50元</button>
</div>
</template>
<script>
export default {
name: 'Son',
// 子组件接收父组件数据使用props即可
props: {
money: {
type: Number,
default: 0
}
},
// props 父组件数据
// emit 触发自定义事件的函数
setup (props, {emit}) {
// 获取父组件数据money
console.log(props.money)
// 向父组件传值
const changeMoney = () => {
// 消费50元
// 通知父组件,money需要变成50
emit('change-money', 50)
}
return {changeMoney}
}
}
</script>
扩展:
- 在vue2.x的时候
.sync
除去v-model实现双向数据绑定的另一种方式
<Son :money='money' @update:money="fn" />
<Son :money.sync='money' />
- 在vue3.0的时候,使用
v-model:money="money"
即可
<Son v-model:money="money" />
总结:
- 父传子:在setup种使用props数据
setup(props){ props就是父组件数据 }
- 子传父:触发自定义事件的时候emit来自
setup(props,{emit}){ emit 就是触发事件函数 }
- 在vue3.0中
v-model
和.sync
已经合并成v-model
指令
组合API-父子通讯 vue3.2
因为没有了setup函数,那么props,emit怎么获取呢
setup script语法糖提供了新的API来供我们使用
defineProps
如果只是单纯在 template 里使用,那么其实就这么简单定义就可以了:
import { defineProps } from 'vue'
defineProps(['name', 'userInfo', 'tags'])
如果 script 里的方法要拿到 props 的值,你也可以使用字面量定义:
const props = defineProps(['name', 'userInfo', 'tags'])
console.log(props.name)
如果不显性的指定 prop 类型的话,很容易在协作中引起程序报错,所以跟我们平时定义 prop 类型时一样, Vue 会通过 instanceof 来进行 类型检查 。
使用这种方法,需要通过一个 “对象” 入参来传递给 defineProps,比如:
defineProps({
name: {
type: String,
required: false,
default: 'Petter',
},
userInfo: Object,
tags: Array,
})
父传子:
<template>
<div class="container">
<h3>我是父组件</h3>
<Son :name="name"></Son>
</div>
</template>
<script setup>
import Son from "./Son"
import {ref} from "vue"
let name = ref("张三")
</script>
子组件代码:
<template>
<div>
我是子组件{{name}}
</div>
</template>
<script setup>
import {defineProps} from "vue"
defineProps({
name:{
type:String,
default:"我是默认值"
}
})
</script>
defineEmits
defineEmit 也是一个方法,它接受的入参格式和标准组件的要求是一致的。
由于 emit 并非提供给模板直接读取,所以需要通过字面量来定义 emits,最基础的用法也是传递一个 string[] 数组进来,把每个 emit 的名称作为数组的 item 。
重复定义的话,事件就会不生效。
// 获取 emit
const emit = defineEmit(['chang-name'])
// 调用 emit
emit('chang-name', 'Tom')
子传父:
<template>
<div>
我是子组件{{name}}
<button @click="ziupdata">按钮</button>
</div>
</template>
<script setup>
import {defineEmits} from "vue"
//自定义函数,父组件可以触发
const em=defineEmits(["updata"])
const ziupdata=()=>{
em("updata","我是子组件的值")
}
</script>
父组件代码:
<template>
<div class="container">
<h3>我是父组件</h3>
<Son @updata="updata"></Son>
</div>
</template>
<script setup>
import Son from "./Son"
const updata = (data) => {
console.log(data); //我是子组件的值
}
</script>
defineExpose
- 在标准组件写法里,子组件的数据都是默认隐式暴露给父组件的,但在 script-setup 模式下,所有数据只是默认 return 给 template 使用,不会暴露到组件外,所以父组件是无法直接通过挂载 ref 变量获取子组件的数据。
- 如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能够正确的拿到,这个操作,就是由 defineExpose 来完成。
<template>
<div class="list-card">
这是子组件
</div>
</template>
<script setup>
import { defineExpose, reactive, ref } from 'vue'
let sonNum = ref(0)
let sonName = reactive({
name: '小明'
})
defineExpose({
sonNum,
sonName
})
</script>
父组件代码:
<template>
<List ref="sonRef"></List>
<button @click="getSonData">获取子组件暴漏的值</button>
</template>
<script setup>
import List from '../components/list.vue'
import { ref } from 'vue'
const sonRef = ref()
function getSonData() {
console.log('子组件中ref暴漏的数值', sonRef.value.sonNum)
// 子组件中ref暴漏的数值 0
console.log('子组件中reactive暴漏的字符串', sonRef.value.sonName.name)
// 子组件中reactive暴漏的字符串 小明
}
</script>
vue指令变化
v-text,v-html,v-show,v-on,v-bind,v-slot,v-pre,v-cloak,v-once,v-is都和之前用法一样
v-if v-for 指令
vue3.0中
vue3.2中
v-memo 指令
v-memo 是一个vue3.2 新增的自定义指令,用于提升渲染性能。
记忆模板的子树(子组件或者子元素),用数组存储,被记忆的在下次虚拟dom渲染的时候如果没有发生过任何改变,则跳过这个子组件或子元素,不会触发更新渲染
<div ref="parent" v-memo="[componentA, componentB]">
<!-- 倘若被记忆的 componentA和componentB 其中一个或全部
没有任何更改,则生成这个parent节点不会触发内部节点的更新-->
<componentA />
<componentB />
<div />
vue3.x中不支持filters过滤器的解决方法
在3.x中,过滤器被删除,不再受支持。相反,我们建议用方法调用或计算属性替换它们。
使用计算属性
更多推荐
所有评论(0)