1. 声明式和命令式编程
2. MVVM模型
view--ViewModel(事件监听、数据绑定)--Model
3. options
data属性:
vue2
中可以是一个对象,推荐函数
vue3
中必须是一个函数,否则会报错
methods属性
不能是箭头函数,因为this指向window,不能获取data中的数据
this指向Proxy对象,即代理对象
对methods中所有函数做了一个遍历,并且通过bind绑定了this
props属性
computed属性
有缓存,基于依赖关系进行缓存,数据不变的时候不会进行重新计算
{
}
...
computed:{
name(){
return firstName + lastName
},
name:{
get:Funciton
set:Function
}
}
...
watch属性
this.$watch(source,()=>{},{deep:true})
...
watch:{
message(newValue,oldValue){
},
message:{
handler(newValue,oldValue){
// do thing
},
deep:true // 深度监听
immediate:true // 立即执行
}
b: '方法名'
f:[
'handle1',
'handle2'
]
}
...
4. 指令
v-once
只渲染一次
v-html
渲染html标签,防止xss攻击
v-cloak
先遮盖起来,等渲染完在渲染,不会显示出
{{xxx}}
需要和css连用:
在css中 [v-cloak]
v-text
渲染文本
v-bind
简写
:
,绑定属性
v-pre
显示原始的标签内容,跳过编译过程,如果标签中需要有
{{}}
,那么不加的会进行编译
v-memo 3.2
react中有memo函数
性能优化
在父节点中定义一个v-memo,列表
列表中的值和上次渲染的值相同,则整个子树的更新会被跳过
v-on
绑定事件,简写方式
@
v-on:click == @click
绑定多个事件:
v-on="{click: divClick,mousemove:mousemoveDiv}"
修饰符
.stop
: 阻止冒泡.prevent
:阻止默认行为.capture
:使用事件捕获模式.self
.once
left
.right
.middle
.passive
v-if
v-if
v-else-if
v-else
v-show
与v-if不同的v-show是控制css的display显示,v-if 如果为false,压根不会渲染在DOM中
不支持
tempalte
模块频繁渲染的时候使用
v-for
对象:(value,key,index)in obj
key属性
有key
patchKeyedChildren
VNode复用 无key
patchUnkeyedChildren
v-model
双向绑定
@input='value=$event.targe.value'
:value='value'
多选框和单选框
checkbox
- 单选框 显示true和false
- 多选框需要绑定value值
- 绑定同一个值,可以省略name
radio
- 需要绑定value
- 绑定同一个值,可以省略name
自定义指令
const app= createApp(App)
// 简易版v-if
app.directive('my',{
created(el,binding,vnoe,prevnoe) {
if(binding.value==0){
el.parentNode.removeChild(el)
}
},
})
app.mount('#app')
修饰符
.lazy
:将默认的input
事件改为change
事件.number
:将内容自动转为数字.trim
:去除首位空格
5. template
本身没有特殊含义的,不会渲染的
类似小程序中的block
属性:
6. 数组更新监听
push
pop
unshift
shift
splice
sort
reverse
7. 组件
全局组件:
局部组件:
8. 脚手架
Vue-cli: vue create 项目名
- 底层是webpack
npm init vue@latest
- create-vue
- 使用create-vue创建一个vue项目
- 底层是vite
9. 组件间通信
父传子
子组件中
props
inheritAttrs:false
禁止父组件将非props属性加到更节点上
$attrs
拿到非props的属性对象
v-bind='$attrs'
// 父组件,通过属性的形式传递
// 子组件中
...
props:{
name:{
type:Object, // 数据类型
required: true // 是否必须
default:()=>{ // 默认值 如果是对象类型必须是一个函数,返回
return {}
},
validator(value){
// 自定义验证
}
}
}
子传父
子组件:
emits:[事件名1] 注册的话可以有提示并且内部查找更快
this.$emit(事件名1,参数1,参数2)
父组件
@事件名1='fn'
fn(arg1,arg2){}
插槽
slot 标签
具名插槽:name='插槽名称'
默认default
父组件中
#插槽名称
v-slot:插槽名称 template 标签上
动态插槽 v-slot:[参数名]
作用域:
Provide和Inject
非父子组件的通信
provide 写成函数形式才能获取通过this获取data中的参数
如果希望是响应式,需要使用computed
...
// 父级
provide(){ // 如果要获取this,需要返回一个函数
return {
name:'xx',
age:this.age
dd:computed(()=>this.name.length)
}
}
...
...
// 子组件或子子组件
inject:['name','age','dd'] dd.value
...
事件总线
Vue3中移除了$on、$off、$once的方法,如果想使用事件总线,需要使用第三方库
第三方:mitt、tiny-emitter
hy-event-store的使用
10. 组件化
生命周期
Vue3
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeUnmount
- unmounted
ref的引用
获取DOM或组件对象
this.$refs
动态组件
keep-alive
属性
include="home1,组件2" include绑定的是组件内的name属性
子组件中
{
name:'home1'
}
exclude
max: 最大缓存组件的个数
生命周期
- activated
- deactivated
异步组件的使用
webpack分包处理
import('xxx').then(res=>{}) 异步,不会阻塞DOM解析
webpack会对import进行分包
import {defineAsyncComponet} from 'vue'
const Home = defineAsyncComponent(()=>import('./views/Home.vue'))
...
components:{
Home
}
组件的v-model
<Home v-model='msg'/>
<Home :modelValue='msg' @update:modelValue='newValue=>msg=newValue'>
子组件中
<input :value='modelValue' @input='inputChange'/>
<script>
emits:['update:modelValue'],
props:['modelValue']
methods:{
inputChange(event){
this.$emit('update:modelValue',event.target.value)
}
}
</script>
<---自定义v-model名称-->
<Home v-model:自定义名='msg'/>
<script>
emits:['update:自定义名'],
props:['自定义名']
methods:{
inputChange(event){
this.$emit('update:自定义名',event.target.value)
}
}
</script>
组件的混入Mixin
对相同代码逻辑的抽取
合并规则
- data中的数据会进行合并,并且如果发生冲突就保留组件本身的数据
- 生命周期钩子函数会被合并到数组中,都会被调用
- 如method中的,发生冲突会使用组件本身的函数
// mixins/msgMixin
export default {
data(){
return {
msg:'测试'
}
},
created(){
console.log(msg)
}
}
// 组件中
import msgMixin from 'mixins/msgMixin'
mixins:['msgMixin']
11. Option API弊端
一个逻辑功能,会被拆分到多个属性中,拆的会很散
12. CompositionAPI
setup
不能使用this
需要在setup函数中返回 {变量1,变量2},才能在template中使用
需要进行响应式绑定: reactive/ref
参数:
- props: 父组件传递的数据
- context:
- attrs
- slots
- emit
生命周期函数:
onX 如onMounted、onUnmouted
reactive
定义一些复杂数据, object,array
不能定义普通类型
ref
既可以定义复杂数据,也可以定义普通数据
返回的是ref对象,需要取ref对象的value属
获取元素:
在template中 使用ref=‘arg1’
在setup中
arg1 = ref()
onMounted(()=>{
console.log(arg1.value) // html标签
})
return {
arg1
}
readonly
数据也是响应式的,不允许修改
isProxy
reactive函数返回的数据就是 proxy对象
isReactive
判断对象是否是reactive创建的响应式代理
如果 readonly包裹了reactive生成的对象,则true
isReadonly
toRaw
返回(reactive/ref 数据的)原始对象,
shallowReactive
进行浅层次的响应式监听
shallowReadonly
toRefs
解构赋值时,保持响应式
const {name,age} = toRefs(info)
toRef
const {name} = toRef(info,‘name’)
unref
unref(name) 相当于 name.value
内部进行判断 isRef
shallowRef
创建一个浅层的ref对象
triggerRef
手动触发,shallowRef相关的响应式
computed
计算属性
const name1 = computed(()=>{name.value+'aa'})
watch
watch(name,(newValue,oldValue)=>{
// 默认深度监听 newValue===oldValue
},{
immediate:true // 立即执行
})
// 侦听数据变化,返回一个普通对象
watch(()=>({...info}),(newValue,oldValue)=>{
// 默认深度监听 newValue===oldValue
},{
immediate:true // 立即执行
deep:true
})
watchEffect
自动收集依赖
- 传入的函数默认直接执行
- 在执行的过程中自动收集依赖
const stop_watch = watchEffect(()=>{
// 传入的函数默认直接执行
// 在执行的过程中自动收集依赖
console.log(name.value)
if (name.value==='hyf'){
stop_watch() // 停止监听
}
})
provide
provide('name','hyf') 非响应式的
let age = ref(0)
provide('age',age ) 响应式的
inject
let name = inject(“name”,'默认值')
defineProps
不需要导入
defineProps({name:{type:String,default:0}})
defineEmits
const emits = defineEmits([event1,event2])
emits(event1,参数)
defineExpose
标签:...,Vue,name,绑定,基础,value,组件,ref From: https://www.cnblogs.com/hyf120/p/17255920.html通过组件实例获取方法,对象
在子组件中需要使用 defineExpose({foo})