vue3学习
Posted 房东家的猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3学习相关的知识,希望对你有一定的参考价值。
安装
npm install -g @vue/cli@next
子传父
父
<One :titles="msg1" @oneTwo="clickMethod"/>
子
export default {
name: "One",
emits: [\'oneTwo\'],
methods: {
updatedOne() {
this.$emit(\'oneTwo\', 12)
}
}
}
update方面的修改
父 <One v-model="msg1" ></One>
子
updatedOne() {
// 内部把v-model 封装到 modelValue
this.$emit(\'update:modelValue\',10)
}
动态组件
<component :is="currentTabComponent"></component>
<component :is="condition ? \'FooComponent\' : \'BarComponent\'"></component>
watch
obj: {
name: 12
}
watch:{
// 正常的基本类型的监听
nums(val) {
console.log(val);
},
obj:{
handler(newName, oldName) {
console.log(newName, oldName);
},
immediate: true,//立即执行触发回调
deep: true // 深度监听
}
},
可以改成字符串的形式,可以理解为铺平
obj: {
name: 12
}
\'obj.name\': {
handler(newName, oldName) {
console.log(newName, oldName);
},
}
我们知道deep:true
很消耗性能
created() {
this.fn = this.$watch(\'obj\', (newVal) => {
console.log(newVal);
}, {immediate: true, deep: true})
},
unmounted() {
this.fn();
}
vue3.0
// 监听title发生改变
watch(
() => props.title,
(newTitle, oldTitle) => {
console.log(\'newTitle, oldTitle :>> \', newTitle, oldTitle);
context.emit(\'change-title\', title);
}
);
监听多个值得变化
const r = ref(1)
const s = ref(1)
const t = ref(1)
watch([r, s, t], val => {
console.log(\'watch\', val)
})
$forceUpdate
强制刷新,只会影响实例本身和插入了插槽内容的子组件
@
@click.stop
等修饰符
.stop
阻止事件冒泡event.stopPropagation()
.prevent
阻止事件的默认行为``event.preventDefault()`
.self
自身元素触发
Keep-alive
缓存组件
include
-string | RegExp | Array
。仅具有匹配名称的组件将被缓存。exclude
-string | RegExp | Array
。名称匹配的任何组件都不会被缓存。max
-number | string
。要缓存的组件实例的最大数量。
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>
条件匹配
<keep-alive :include="[\'a\', \'b\']">
<component :is="view"></component>
</keep-alive>
最大缓存组件
<keep-alive :max="10">
<component :is="view"></component>
</keep-alive>
setup
- 参数,
props
,context
setup(props, context) {
// Attributes (Non-reactive object)
console.log(context.attrs)
// Slots (Non-reactive object)
console.log(context.slots)
// Emit Events (Method)
console.log(context.emit)
}
setup(props, { attrs, slots, emit }) {
...
}
ref
ref
的本质是拷贝,与原始数据没有引用关系
reactive
复杂类型的响应
toRef
toRef
将单个reactive
对象属性转换为保持与父对象的连接的ref:
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, \'foo\')
// 这样进行修改值,因为转化为ref类型啦
foos.value=100
toRefs
toRefs
将所有属性转换为具有refs属性的普通对象:
<h1>{{foo}}</h1>
setup() {
const state = reactive({
foo: 1,
bar: 2
})
const clickMethod = () => {
state.foo=100
}
return {
clickMethod,
...toRefs(state)
}
},
computed
const twiceTheCounter = computed(() => counter.value * 2)
get/set
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
slot
命名插槽
父
<One>
<h1>223223</h1>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
</One>
子
// 默认插槽
<slot></slot>
// 命名插槽
<slot name="header"></slot>
生命周期
选件API | 钩在里面 setup |
---|---|
beforeCreate |
不需要* |
created |
不需要* |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeUnmount |
onBeforeUnmount |
unmounted |
onUnmounted |
errorCaptured |
onErrorCaptured |
renderTracked |
onRenderTracked |
renderTriggered |
onRenderTriggered |
activated |
onActivated |
deactivated |
onDeactivated |
提供/注入
父
provide: {
location: \'North Pole\',
geolocation: {
longitude: 90,
latitude: 135
}
}
子
inject: [\'location\', \'geolocation\']
vue3.0
父
setup() {
provide(\'location\', \'North Pole\')
provide(\'geolocation\', {
longitude: 90,
latitude: 135
})
}
setup() {
const location = ref(\'North Pole\')
const geolocation = reactive({
longitude: 90,
latitude: 135
})
const updateLocation = () => {
location.value = \'South Pole\'
}
provide(\'location\', location)
provide(\'geolocation\', geolocation)
provide(\'updateLocation\', updateLocation)
}
子/孙
setup() {
const userLocation = inject(\'location\', \'The Universe\')
const userGeolocation = inject(\'geolocation\')
return {
userLocation,
userGeolocation
}
}
dom查找
<div ref="root">This is a root element</div>
setup() {
const root = ref(null)
onMounted(() => {
console.log(root.value) // <div>This is a root element</div>
})
return {
root
}
}
toRaw
拿到原始的值, 类似于表单表单的提交给后面的值
const foo = {name:\'xx\'}
const reactiveFoo = reactive(foo)
console.log(toRaw(reactiveFoo) === foo) // true
watchEffect
- 没有过多的参数 只有一个回调函数
- 立即执行,没有惰性,页面的首次加载就会执行。
- 自动检测内部代码,代码中有依赖 便会执行
watchEffect
当我想观察多个反应特性而我不在乎旧值时
watchEffect能够监视在回调函数中引用的任何反应变量。
watchEffect(() => {
console.log(root.value);
})
setTimeout(() => {
root.value = 10
},1000)
// 1 默认执行一次
// 10
watch
当单个电抗值更改时,如果您想触发副作用,请使用此命令。
watch(user, () => doSomething({ user: user.value, profile: profile.value }))
使用watchEffect
时,你需要看多个反应值,并引发副作用,只要任何人被更新。
watchEffect(() => doSomething({ user: user.value, profile: profile.value }))
清除监听
我们知道监听会有副作用, 我们可以发现这个跟react的useEffect
很像
const stop = watchEffect(() => {
/* ... */
})
// 离开后,我们可以执行清除监听
stop()
更新策略
flush: \'post\'
设置后是DOM更新后运行效果
<div ref="root">This is a root element</div>
setup() {
const root = ref(null)
watchEffect(() => {
console.log(root.value) // => <div></div>
},
{
flush: \'post\'
})
return {
root
}
}
teleport
<teleport>
并告诉Vue将这个html传送到body
标签
<teleport to="body">
<div v-if="modalOpen" class="modal">
xxxxxxx
</div>
</teleport>
我们可以把两个组件添加到同一个目标
<teleport to="#modals">
<div>A</div>
</teleport>
<teleport to="#modals">
<div>B</div>
</teleport>
<div id="modals">
<div>A</div>
<div>B</div>
</div>
render
resolveComponent
用于全局注册的组件。
const { h, resolveComponent } = Vue
// ...
render() {
const ButtonCounter = resolveComponent(\'ButtonCounter\')
return h(ButtonCounter)
}
ts 的写法
<script lang="ts">
import { defineComponent } from \'vue\'
export default defineComponent({
// type inference enabled
})
</script>
全局刷新
const {ctx: _this}: any = getCurrentInstance()
_this.$forceUpdate();
防抖节流
全局添加
Vue.createApp({
methods: {
// Debouncing with Lodash
click: _.debounce(function() {
// ... respond to click ...
}, 500)
}
}).mount(\'#app\')
另一种形式
生命周期挂钩中添加去抖动功能
app.component(\'save-button\', {
created() {
// Debouncing with Lodash
this.debouncedClick = _.debounce(this.click, 500)
},
unmounted() {
// Cancel the timer when the component is removed
this.debouncedClick.cancel()
},
methods: {
click() {
// ... respond to click ...
}
},
template: `
<button @click="debouncedClick">
Save
</button>
`
})
这种方式才是computed的精华所在
const vm = Vue.createApp({
data() {
return {
firstName: \'Foo\',
lastName: \'Bar\'
}
},
computed: {
fullName() {
return this.firstName + \' \' + this.lastName
}
}
}).mount(\'#demo\')
vue3
https://cli.vuejs.org/core-plugins/typescript.html#injected-commands
vue add typescript
别用vue-component-class 感觉不是很成熟
reactive
const book = reactive({ title: \'Vue 3 Guide\' })
book.title 使用就可以啦, 不能用 .value
最后上一个,刚开始学习的小案例
import {ref, watch, onMounted, computed,toRefs} from \'vue\'
export default {
name: "One",
props:[\'sex\'],
setup(props) {
let {sex} = toRefs(props);
console.log(sex.value);
let sex1=toRefs(props,\'sex\')
console.log(sex1.sex.value);
let a = ref(0)
// 监听
watch(a, (newVal, val) => {
console.log(newVal, val);
}, {deep: true})
//如果还需要监控一个就继续写一个
watch(b, (newValue, oldValue) => {
console.log(newValue, oldValue);
})
const add = () => {
// 类似请求修改值
a.value = [1, 2, 3, 4]
};
// 计算属性
const b = computed(() => a.value[0] + 100)
// 生命周期
onMounted(add)
return {a, b}
}
}
html
<input type="text" v-model="a[0]">
{{ a }} <br>
{{ b }}
{{sex}}
以上是关于vue3学习的主要内容,如果未能解决你的问题,请参考以下文章