1.插槽
- 具名插槽:
//接收name="h"
<template v-slot:h><p>sdfsdf</p></template>
<template #h><p>sdfsdf</p></template>
- 作用域插槽
<template v-slot:default="strProps"><p>{{strProps.str.job}}</p></template>
//接收
<slot v-bind:str="strData"></slot>
插槽:v-slot:header 可以被重写为 #header:,插槽名明确后才能进行简写,否则不可以简写
动态插槽:
<template v-slot:[dynamicSlotName]>
...
</template>
插槽:定义方法
<todo-list v-slot="{ item }">
<i class="fas fa-check"></i>
<span class="green">{{ item }}</span>
</todo-list>
插槽重名名
<todo-list v-slot="{ item: todo }">
<i class="fas fa-check"></i>
<span class="green">{{ todo }}</span>
</todo-list>
2.new Vue()实例方法
$data
$el
$watch
当一个 Vue 实例被创建时,它将 `data` 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
3.vuex
方法:dispatch触发action->action commit触发mutations修改state
- modules:可以划分模块
modules:{
m1:{
namespaced:true, //开启命名空间
state:{
aa:'11'
},
getters:{},
mutations:{
bb(){
}
},
actions:{}
}
}
//使用
{{$store.state.m1.aa}}
this.$store.commit('m1/bb')
- map系列方法
import {mapMutatons} from 'vuex'
methods:{
...mapMutations('m1',['loginMutation'])
<!-- 使用 -->
add(){
this.loginMutation()
}
}
- vue的修饰符特别有用
v-once 一次更新不再更新
v-html html转换指令
动态指令:<a v-bind:[attributeName]="url"> ... </a>,
attributeName变化 指令变化,动态参数null值会移除绑定,其他非字符串会警告,
动态指令中空格和引号是无效的,指令名称的大写都会自动转换为小写
v-on:submit.prevent//调用 event.preventDefault():
//防抖
Vue 没有内置支持防抖和节流,但可以使用 [Lodash](https://lodash.com/) 等库来实现:
<script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>
created() {
// 用 Lodash 的防抖函数
this.debouncedClick = _.debounce(this.click, 500)
},
//计算属性存在get和set:
computed: {
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue) {
const names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
//动态样式
:class="[isActive ? activeClass : '', errorClass]"
:class="[{ active: isActive }, errorClass]"
:style="[baseStyles, overridingStyles]"
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div> //兼容性
//访问原始的Dom事件
@click="warn('Form cannot be submitted yet.', $event)"
//执行多个方法用逗号分隔
@click="one($event), two($event)"
<!-- 阻止单击事件继续传播 -->
<a @click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form @submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a @click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form @submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div @click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div @click.self="doThat">...</div>
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div @scroll.passive="onScroll">...</div>
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
动态组件:
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component :is="currentTabComponent"></component>
非字符串模板:为写在html中的组件不能使用驼峰的形式引入组件,需要用下划线的形式
字符串模板:template中引入可以使用驼峰
使用组件的时候定义的状态值和定义的方法,会直接作用于组件内部的根节点上
如果你不希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false
通过将 inheritAttrs 选项设置为 false,你可以访问组件的 $attrs property,该 property 包括组件 props 和 emits property 中未包含的所有属性 (例如,class、style、v-on 监听器等)。
app.component('date-picker', {
inheritAttrs: false,
template: `
<div class="date-picker">
<input type="datetime-local" v-bind="$attrs" />
</div>
`
})
provide inject:跨越多级子级传递数据
provide没发访问data中动态数据,需要使用return的返回形式:
provide() {
return {
todoLength: this.todos.length
}
},
provide是单项的数据传递,类似于props,并且provide不是响应式的,需要用计算属性实现响应式
provide() {
return {
todoLength: Vue.computed(() => this.todos.length)
}
}
异步组件:const { createApp, defineAsyncComponent } = Vue,defineAsyncComponent 异步加载组件;配合Suspense使用实现加载动画
transform硬件加速可以设定一些参数,任何一个即可
perspective: 1000px;
backface-visibility: hidden;
transform: translateZ(0);
动画class规则:如果你使用了 <transition name="my-transition">,那么 v-enter-from会替换为 my-transition-enter-from。
:duration="{ enter: 500, leave: 800 }" //过度效果
添加 :css="false",也会让 Vue 会跳过 CSS 的检测,除了性能略高之外,这可以避免过渡过程中 CSS 规则的影响。
需要注意的是使用 FLIP 过渡的元素不能设置为 display: inline。作为替代方案,可以设置为 display: inline-block 或者将元素放置于 flex 布局中。
setUP组件中无法获取到this;setup中定义的方法都是非响应式的,需要用到ref进行操作
// src/components/UserRepositories.vue `setup` function
import { fetchUserRepositories } from '@/api/repositories'
import { ref, onMounted, watch, toRefs } from 'vue'
// 在我们的组件内
setup (props) {
let repositories = []
// 使用 `toRefs` 创建对prop的 `user` property 的响应式引用
const { user } = toRefs(props)
const getUserRepositories = async () => {
repositories = await fetchUserRepositories(props.user)
}
onMounted(getUserRepositories)
// 在 user prop 的响应式引用上设置一个侦听器
watch(user, getUserRepositories)
return {
repositories,
getUserRepositories // 返回的函数与方法的行为相同
}
}
watch监听user变化执行后面的方法
setup可以进行组合式的api拆分,传递两个参数context,props
setup中props是响应式的,无法解构,所以需要toRefs取进行解析,const { title } = toRefs(props),如果title是非出现的则使用const title = toRef(props, 'title')
context是非响应式的,所以可以直接解构
export default {
setup(props, { attrs, slots, emit }) {
...
}
}
attrs 和 slots 是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.x 或 slots.x 的方式引用 property。请注意,与 props 不同,attrs和 slots 是非响应式的。如果你打算根据 attrs 或 slots 更改应用副作用,那么应该在 onUpdated生命周期钩子中执行此操作。
执行 setup 时,组件实例尚未被创建。因此,你只能访问以下 property:
propsattrsslotsemit
换句话说,你将无法访问以下组件选项:
datacomputedmethods
setup中除了beforecreate created,和选项式api都有对应的钩子,只是前面添加了on,例如onMounted
因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写
setup中使用provide inject,
1.都需要从vue实例中引入
2.为了增加 provide 值和 inject 值之间的响应性,我们可以在 provide 值时使用 ref 或 reactive
3.为了防止inject修改值,可以使用只读写法 provide('location', readonly(location))
ref和reactive的区别:
ref是定义一些基本的数据类型,reactive定义一些复杂的数据类型
reactive需要借助torefs来进行响应式的转换
setup中watchEffect
watchEffect(() => {
// 这个副作用在 DOM 更新之前运行,因此,模板引用还没有持有对元素的引用。
console.log(root.value) // => null
})
watchEffect(() => {
console.log(root.value) // => <div>This is a root element</div>
},
{
flush: 'post'
})
使用flush:‘post’来进行监听才可以获取真实的dom,
flush 选项还接受 sync,这将强制效果始终同步触发。然而,这是低效的,应该很少需要。
mixin和组件数据冲突,以mixin的数据优先,mixin的钩子会在组件钩子之前运行,并且合并,其他的有冲突以组件的为主
注册自定义组件:directive
<div id="dynamicexample">
<h3>Scroll down inside this section ↓</h3>
<p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>
const app = Vue.createApp({
data() {
return {
direction: 'right'
}
}
})
app.directive('pin', {
mounted(el, binding) {
el.style.position = 'fixed'
// binding.arg 是我们传递给指令的参数
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
}
})
app.mount('#dynamic-arguments-example')
teleport 可以将标签放置到某个元素的子集
app.component('modal-button', {
template: `
<button @click="modalOpen = true">
Open full screen modal! (With teleport!)
</button>
<teleport to="body">
<div v-if="modalOpen" class="modal">
<div>
I'm a teleported modal!
(My parent is "body")
<button @click="modalOpen = false">
Close
</button>
</div>
</div>
</teleport>
`,
data() {
return {
modalOpen: false
}
}
})
放置到body下
插件的使用
import i18nPlugin from './plugins/i18n'
app.use(i18nPlugin, i18nStrings)
watch API 完全等同于组件侦听器 property。watch 需要侦听特定的数据源,并在回调函数中执行副作用。默认情况下,它也是惰性的,即只有当被侦听的源发生变化时才执行回调。
- 与 watchEffect 比较,
watch允许我们:-
懒执行副作用;
-
更具体地说明什么状态应该触发侦听器重新运行;
-
访问侦听状态变化前后的值。
-
Vue3.0
setup包裹所有,传入props root(对应this) torefs 转换数据为响应式数据 reactive 创建类似于data对象 所有data和方法都需要用扩展运算返回