Vue3笔记摘录
1.Vue3整体知识概览图
2.ref与reactive具体使用区别
2-1 基本类型处理
const count1 = ref(0) 使用ref自动转化为数字类型const count2 = reactive(0) 参数必须是对象类型
2-2 具体使用过程
// ref 处理对象(自动解包)
const user = ref({name: 'John',address: {city: 'New York'}
})// 等效于 reactive 写法
const user = reactive({name: 'John',address: reactive({city: 'New York'})
})// 访问方式对比
// ref 需要 .value
console.log(user.value.name)
// reactive 直接访问
console.log(user.name)
2-3 数组处理区别
1.ref需要.value.push去修改原数组
const list = ref([1,2,3])
list.value.push(4)2.reactive 可以直接修改
const list_copy = reactive([1,2,3])
list_copy.push(4)
3.传值
3-1 父子组件传值 普通方式(父传子)
3-1-1 父组件<template><Child :msg='msg' :list="list"/></template><script>import Child from './child.vue'import { ref, reactive } from 'vue'export default {components: { Child },setup() {const msg = ref('父组件传递给子组件的信息info')const list = reactive(['苹果', '香蕉', '橘子', '葡萄', '榴莲'])return {msg,list}}}</script>3-1-2 子组件<template><ul><li v-for='(i,index) in list' :key="index">{{ index+1 }}. {{ i }}</li></ul></template><script>export default {props: ['msg', 'list'],setup() {}}</script>
3-2 父子组件传值 setup方式(父传子)
3-2-1 父组件
<template><Child :msg='msg' :list="list"/>
</template>
<script>
import Child from './child.vue'
import { ref, reactive } from 'vue'
export default {components: { Child },setup() {const msg = ref('父组件传递给子组件的信息info')const list = reactive(['苹果', '菠萝蜜', 香蕉', '橘子', '葡萄', '榴莲'])return {msg,list}}
}
</script>3-2-2 子组件
<template><ul><li v-for='(i,index) in list' :key="index">{{ index+1 }}. {{ i }}</li></ul>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({// 第一种写法msg: String,// 第二种写法list: {type: Array,default: () => []}
})
console.log(props)
</script>
3-3 emit传值(子传父)
父组件
<template><Child @myClick='onMyClick' @increase='onIncrease'/>
</template>
<script setup>
import Child from './child.vue'
const onMyClick = (info) => {console.log(info)
}
const onIncrease = (info) => {console.log(info)
}
</script>子组件
<template><button @click="handleClick">按钮</button>
</template>
<script setup>
import { defineEmits, ref } from 'vue'
const info = ref('你好呀')
const emit = defineEmits(['myClick'])
const handleClick = () => {emit('myClick', info)emit('increase', ref('你好呀_copy'))
}
</script>
3-4 defineExpose、ref(父传子)
父组件
<template><div>父组件:拿到子组件的message数量 {{ msg }}</div><button @click='callChildFn'>调用子组件的方法</button><Child ref="com"/>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import Child from './child.vue'
const com = ref(null)
const msg = ref('')
onMounted(() => {console.log(com, 'com==onmounted')msg.value = com.value.message
})
function callChildFn() {console.log(com, 'callChildFn==onmounted')com.value.show()msg.value = com.value.message
}
</script>子组件
<template>
<div>子组件</div>
</template>
<script setup>
import { defineExpose, ref } from 'vue'
const message = ref('子组件传递消息')
const show = () => {console.log('子组件方法')
}
defineExpose({message,show
})
</script>
3-5 attrs(子传父)
父组件
<template><Child :msg='msg' :msgcopy='msgcopy' title='子组件'/>
</template>
<script setup>
import { ref } from 'vue'
import Child from './child.vue'
const msgcopy = ref('我是你呀')
const msg = ref('你猜我是谁')
</script>子组件有俩种写法第一种写法 使用attrs
<template>
<div>子组件: {{ attrs.msg }}--{{ attrs.msgcopy }}--{{ attrs.title }}</div>
</template>
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
console.log(attrs)
</script>第二种写法 使用defineProps
<template><div>子组件: {{ msg }}--{{ msgcopy }}--{{ title }}</div>
</template>
<script setup>import { defineProps } from 'vue'defineProps({msg: String,msgcopy: String,title: String})
</script>
3-6 provide、inject(多层级传值)
父组件
<template><div>祖父组件</div><button @click='fn'>改变location的值</button><br/><div>双向数据绑定:</div><ul><li>{{ userInfo.name }}</li></ul><input v-model='userInfo.name' /><Child />
</template>
<script setup>
import { ref, provide } from 'vue'
import Child from './child.vue'
const location = ref('传递祖父的参数')
const userInfo = ref({name: '张三',age: 18
})
function fn() {location.value = '改变值'
}
provide('location', location)
provide('userInfo', userInfo)
</script>子组件
<template><Sun />
</template>
<script>
import Sun from './sun.vue'
export default {components: { Sun }
}
</script>
<style lang="scss" scoped>
</style>孙组件
<template>
<div><h5>...........孙组件接受参数........</h5><div>1.祖父组件定义provide,孙组件inject接受:{{ location }}</div><p>用户信息:{{ userInfo.name }}</p><br/><br/><div>2.provide inject实现父子组件传值的时候,子组件改变数据也会影响父组件</div><br/>姓名:<input v-model="userInfo.name">
</div>
</template>
<script setup>
import { inject } from 'vue'
const location = inject('location')
const userInfo = inject('userInfo')
</script>再这个里面需要注意的是 readonly
增加readonly后 子组件修改后 不会影响父组件 父组件 子组件和上述一样 唯一区别是孙组件 具体写法如下:
<template><div>祖父组件</div><button @click='fn'>改变location的值</button><br/><div>双向数据绑定:</div><ul><li>{{ userInfo.name }}</li></ul><input v-model='userInfo.name' /><Child />
</template>
<script setup>
import { ref, provide,readonly } from 'vue'
import Child from './child.vue'
const location = ref('传递祖父的参数')
const userInfo = ref({name: '张三',age: 18
})
function fn() {location.value = '改变值'
}
provide('location', location)
provide('userInfo', readonly(userInfo))
</script>
3-7 v-model 是vue一个语法糖 在vue3玩法更多了
3-7-1 单个v-model父组件
<template><Child v-model='message'/>
</template>
<script setup>
import { ref } from 'vue'
import Child from './child.vue'
const message = ref('父传给子')
</script>子组件
<template><button @click='handleClick'>修改model</button>{{ modelValue }}
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
function handleClick() {emit('update:modelValue', '子改变值')
}
</script>
<style lang="scss" scoped>
</style>
3-7-2 多个v-model父组件
<template><Child v-model:msg1='message1' v-model:msg2='message2'/>
</template>
<script setup>
import { ref } from 'vue'
import Child from './child.vue'
const message1 = ref('水果1')
const message2 = ref('水果2')
</script>子组件
<template><div><button @click='handleClick1'>修改msg1</button> {{ msg1 }}</div><div><button @click='handleClick2'>修改msg2</button> {{ msg2 }}</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
defineProps({msg1: String,msg2: String
})
const emit = defineEmits(['update:msg1', 'update:msg2'])
function handleClick1() {emit('update:msg1', '蔬菜1')
}
function handleClick2() {emit('update:msg2', '蔬菜2')
}
</script>
<style lang="scss" scoped>
</style>
3-8 v-model修饰符
1.用法的话是v-model.自定义修饰符 有些自定义修饰符比如trim number lazy
2.具体用法
父组件
<template><Child v-model.uppercasefn='message'/>
</template>
<script setup>
import { ref } from 'vue'
import Child from './child.vue'
const message = ref('水果1')
</script>子组件
<template>{{ modelValue }}
</template>
<script setup>
import { defineProps, defineEmits, onMounted } from 'vue'
const props = defineProps(['modelValue', 'modelModifiers'])
const emit = defineEmits(['update:modelValue'])
onMounted(() => {console.log('modelModifiers', props.modelModifiers)if (props.modelModifiers.uppercasefn) {emit('update:modelValue', '蔬菜')}
})
</script>
<style lang="scss" scoped>
</style>注意:如果在子组件中修改v-model.uppercasefn中的uppercasefn改成其他的 那么页面展示的就是水果1
if (props.modelModifiers.uppercasefn) 这个就是判断自定义修饰符有没有在当前props里
3-9 插槽 slot插槽可以理解为传一段html片段 给子组件
3-9-1 最基础的插槽模版
只需要在子组件中使用标签 就会将父组件传进来的HTML内容渲染出来父组件
<template><Child><div>渲染</div></Child>
</template>
<script setup>
import Child from './child.vue'
</script>子组件
<template><slot></slot>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
3-9-2 具名插槽
具名插槽就是在默认插槽的基础上进行分类,可以理解为对号入座
父组件需要使用标签 但是需要在标签上使用v-slot:+‘名称’。
子组件需要在标签里用name=‘名称’ 对应接收父组件
<template><Child><template v-slot:monkey><div>渲染</div></template><button>我是父组件</button></Child>
</template>
<script setup>
import Child from './child.vue'
</script>子组件
<template><div><!-- 默认插槽 --><slot></slot><!-- 具名插槽 也就是自定义插槽 --><slot name='monkey'></slot></div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
3-9-3 作用域插槽父组件
<template>// v-slot='{scope}' 获取子组件传过来的数据// :list='list' 把list数据传给子组件<Child v-slot='{scope}' :list='list'><div v-if="scope"><div>{{ scope.name }}--职业:{{ scope.occupation }}</div><hr/></div></Child>
</template>
<script setup>
import { reactive } from 'vue'
import Child from './child.vue'
const list = reactive([{ name: '张三', occupation: '学生' },{ name: '李四', occupation: '老师' },{ name: '王五', occupation: '医生' },{ name: '赵六', occupation: '警察' },{ name: '田七', occupation: '军人' }
])
</script>子组件
<template><div><slot v-for='item in list' :scope="item"></slot></div>
</template>
<script setup>
import { defineProps } from 'vue'
defineProps({list: {type: Array,default: () => []}
})
</script>
<style lang="scss" scoped>
</style>
后续还会陆续更新vue3相关文章,敬请期待哈!