1、toRaw
返回一个reactive或readonly包裹的proxy对象
其实就是将一个proxy对象转化成普通对象
<template>
<div>
</div>
</template>
<script>
import {ref,reactive,toRaw,readonly,shallowReactive,shallowReadonly,toRefs} from 'vue'
export default {
name: 'App',
setup (props,context) {
//这是一个普通对象
const obj={
a:1,
b:2
}
const proxyObj=reactive(obj)//转换成代理对象
console.log(proxyObj)//打印成一个proxy对象
const newObj=toRaw(proxyObj)//转换成普通对象
console.log(newObj)//打印成一个普通对象
//包装前和转换后其实是相等的
console.log(newObj===obj)//true
return {
}
}
}
</script>
<style>
</style>
2、markRaw(有点摄影里面那个raw的意思,原始的意思)
返回包裹对象的本身,和原对象是相等的
这种包含是浅度(shallow)的不是深度(deep)的
<template>
<div>
</div>
</template>
<script>
import {ref,reactive,toRaw,markRaw,readonly,shallowReactive,shallowReadonly,toRefs} from 'vue'
export default {
name: 'App',
setup (props,context) {
//这是一个普通对象
const obj={
a:1,
b:2
}
const rawObj=markRaw(obj)//包裹成普通对象
console.log(obj)//打印一个普通对象
console.log(rawObj)//依然打印一个普通对象
console.log(obj===rawObj)//true
const proxyObj=reactive(rawObj)//包装成proxy对象
console.log(proxyObj)//但打印的依然还是普通对象
return {
}
}
}
</script>
<style>
</style>
3、生命周期钩子
钩子参看前篇,略
4、选项式provide,inject
父组件作为数据的提供方:provider
Son.vue
<template>
<h1>{{sonName}} i am son component</h1>
<h1>{{directsonname}} directly provider name</h1>
</template>
<script>
export default {
name: 'Son',
inject:['sonName','directsonname'],
setup(){
return {
}
},
}
</script>
<style scoped>
</style>
Father.vue
<template>
<h1>{{fathername}} i am fahter component</h1>
<hr/>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
export default {
name: 'Father',
setup(){
const sonName='sonname'
return {
sonName
}
},
provide:{
sonName: 'sonName'
},
inject:['fathername'],
components:{
Son
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Father ></Father>
</div>
</template>
<script>
import {ref,reactive} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
const myname=ref('Fathername')
return {
myname
}
},
provide:{
fathername:'Fathername',
directsonname:'directSonName'
},
components:{
Father,
}
}
</script>
<style>
</style>
5、组合式Provide,inject
- 需要在setup内调用
- provide以函数的形式来使用,两个参数,第一个参数是属性名,第二个参数是属性值
- 子组件inject和选项式provide和inject一样使用,也可以通过函数形式来使用
- inject函数也有两个参数,一个是属性值,一个是默认值
Fther.vue
<template>
<h1>{{name}}</h1>
<hr/>
<h1>{{age}}</h1>
<hr/>
<h1>{{hobby}}</h1>
<hr/>
<h1>{{career}}</h1>
<hr/>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
export default {
name: 'Father',
inject:['name','age','hobby','career'],
setup(){
return {
}
},
components:{
Son
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Father ></Father>
</div>
</template>
<script>
import {ref,reactive,provide} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
provide('name','zhangsan')
provide('age',30)
provide('hobby','sing')
provide('career','programmer')
return {
}
},
components:{
Father,
}
}
</script>
<style>
</style>
推荐用法(inject也携程组合式的):
Father.vue
<template>
<h1>{{name}}</h1>
<hr/>
<h1>{{age}}</h1>
<hr/>
<h1>{{hobby}}</h1>
<hr/>
<h1>{{career}}</h1>
<hr/>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
import {inject } from 'vue'
export default {
name: 'Father',
// inject:['name','age','hobby','career'],
setup(){
const name=inject('name','国泰民安')
const age=inject('age','100')
const hobby=inject('hobby','daqiu')
const career=inject('career','dadouduo')
return {
name,
age,
hobby,
career
}
},
components:{
Son
}
}
</script>
<style scoped>
</style>
app.vue
<template>
<div>
<Father ></Father>
</div>
</template>
<script>
import {ref,reactive,provide} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
provide('name','zhangsan')
provide('age',30)
provide('hobby','sing')
provide('career','programmer')
return {
}
},
components:{
Father,
}
}
</script>
<style>
</style>
6、给Provide,inject增加响应式
使用ref或reactive包裹
Father.vue
<template>
<h1>{{name}}</h1>
<hr/>
<h1>{{age}}</h1>
<hr/>
<h1>{{hobby}}</h1>
<hr/>
<h1>{{career}}</h1>
<hr/>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
import {inject } from 'vue'
export default {
name: 'Father',
// inject:['name','age','hobby','career'],
setup(){
const name=inject('name','国泰民安')
const age=inject('age','100')
const hobby=inject('hobby','daqiu')
const career=inject('career','dadouduo')
return {
name,
age,
hobby,
career
}
},
components:{
Son
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Father ></Father>
<button @click="changeNumber">改变</button>
</div>
</template>
<script>
import {ref,reactive,provide} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
const myname=ref('张小三')
provide('name',myname)
provide('age',30)
provide('hobby','sing')
provide('career','programmer')
setTimeout(()=>{
myname.value='王大拿'
},2000)
const changeNumber=()=>{
myname.value='郭晶晶'
}
return {
changeNumber
}
},
components:{
Father,
}
}
</script>
<style>
</style>
- provide不仅可以提供变量,还可以提供函数
- inject可以注入(接受)到provide提供的这个函数,从而不用再子组件中编写这个函数(方法),因为数据是由父组件提供的,所以也建议在父组件中提供方法修改这个数据,子组件只是接收和使用父组件传过来的数据
- 父组件在提供方法的时候最好使用readonly包裹一下
Father.vue
<template>
<h1>{{name}}</h1>
<hr/>
<h1>{{age}}</h1>
<hr/>
<h1>{{hobby}}</h1>
<hr/>
<h1>{{career}}</h1>
<hr/>
<button @click="changeName">改变姓名</button>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
import {inject } from 'vue'
export default {
name: 'Father',
// inject:['name','age','hobby','career'],
setup(){
const name=inject('name','国泰民安')
const age=inject('age','100')
const hobby=inject('hobby','daqiu')
const career=inject('career','dadouduo')
const changeName=inject('changeName')
return {
name,
age,
hobby,
career,
changeName
}
},
components:{
Son
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Father ></Father>
</div>
</template>
<script>
import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
const myname=ref('张小三')
provide('name',readonly(myname))
provide('age',30)
provide('hobby','sing')
provide('career','programmer')
const changeName=()=>{
myname.value='郭小晶'
}
provide('changeName',changeName)
return {
}
},
components:{
Father,
}
}
</script>
<style>
</style>
7、$refs模板引用(vue2)
- 实现了类似jquery的dom操作
- 也就是通过ref=‘子组件名’的形式给子组件命名,在通过$refs.子组件名.方法或者属性来操作子组件上的属性或方法
- $refs只能作用直接子组件
以下例子是使用vue2选项式API
Father.vue
<template>
<h1>{{name}}</h1>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
import {ref,inject } from 'vue'
export default {
name: 'Father',
data(){
return{
name:'zhangan'
}
},
methods:{
changeName(){
this.name='lisi'
}
},
// inject:['name','age','hobby','career'],
setup(){
return {
}
},
components:{
Son
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Father ref="father"></Father>
<hr/>
<button @click="changename">改变名称</button>
</div>
</template>
<script>
import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
return {
}
},
methods:{
changename(){
this.$refs.father.changeName()
}
},
components:{
Father,
}
}
</script>
<style>
</style>
8、refs(vue3)
- 使用组合式api的时候reactive,ref和templates是统一的
- 在setup上声明ref
- 在组件上使用的ref的属性名,必须在setup上定义一个和他名字一致的变量
- 这个变量用来接收一个被ref包裹的null值(默认要求)
- 在方法中使用这个ref(通过这个ref拿到这个dom节点,并进行操作)
Father.vue
<template>
<h1>{{name}}</h1>
<!-- 这里的ref的名字要和setup里面的名字一致-->
<h1 ref="mychild">张三</h1>
<button @click="changeMyName">改变名字</button>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
import {ref,inject } from 'vue'
export default {
name: 'Father',
setup(){
//默认必须要ref一个null值,注意这里的child要和组件上的ref的名字一致
const mychild=ref(null)
const changeMyName=()=>{
//通过mychild拿到子组件节点,并进行dom操作
mychild.value.innerText='lisi'
}
return {
mychild,
changeMyName
}
},
components:{
Son
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Father ref="father"></Father>
</div>
</template>
<script>
import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
return {
}
},
methods:{
},
components:{
Father,
}
}
</script>
<style>
</style>
另外一例
Father.vue
<template>
<!-- 这里的ref的名字要和setup里面的名字一致-->
<h1 >{{name}}</h1>
<button @click="changeMyName">改变名字</button>
<Son></Son>
</template>
<script>
import Son from './Son.vue'
import {ref,inject } from 'vue'
export default {
name: 'Father',
setup(){
const name=ref('zhangsan')
const changeMyName=()=>{
name.value='lilaosi'
}
return {
name,
changeMyName
}
},
components:{
Son
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Father ref="father"></Father>
<button @click="setname">设置名字</button>
</div>
</template>
<script>
import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'
export default {
name: 'App',
setup (props,context) {
const father=ref(null)
const setname=()=>{
father.value.changeMyName()
}
return {
father,
setname
}
},
methods:{
},
components:{
Father,
}
}
</script>
<style>
</style>