一,指令:
操作内容
v-pre vue不会解析{{}} v-html 会解析 v-text 不会解析
操作属性
v-bind:属性='属性值' (:属性='属性值')
操作样式
<p class=''></p>
<p v-bind:{'样式':'控制样式变量'}>
<p :['样式1','样式2',....]></p>
操作事件
v-on:事件='控制事件函数'( @事件='控制事件函数')
条件指令: v-if、v-else-if、v-else v-show
v-if和v-show的区别:
1、v-if是动态添加移出dom元素
2、v-show是通过css的display:none;来控制dom元素的显示,不会移出
v-for : 遍历
v-model : 实现数据与界面的交互,界面修改可以自动更新数据
v-cloak : 用来隐藏刚开始还未完成编译的dom元素
二,修饰符:
事件修饰符
prevent 阻止浏览器的默认行为
stop 阻止冒泡
capture 设置为捕获
样式修饰符
number 转换为数值类型
trim 去空格
lazy 文本框输入完成后,失去焦点再返回输入的值
三,响应式原理
vue2.x 响应式原理基础实现?
通过“Object.defineProperty()”方法来劫持各个属性的setter,getter, 在数据变动时发布消息给订阅者,触发相应的监听回调
计算属性(具有缓存特性)
computed定义成方法,本质上是属性,一定有一个返回值,在computed方法体中定义依赖,当依赖变化重新计算
侦听器 watch
watch: {
username(newValue,oldValue){
console.log('newValue ',newValue, ' oldValue',oldValue);
},
keyword:{
// handler表示侦听器触发执行的方法
handler(newValue,oldValue){
console.log('keyword newValue ',newValue, ' oldValue',oldValue);
},
// 立即执行
immediate:true
},
user:{
handler(newValue,oldValue){
console.log('user newValue ',newValue, ' oldValue',oldValue);
},
// 深度侦听
deep:true
}
},
组件:
全局注册: app.component('ComA', ComA) // 先全局注册,再挂载mount
局部注册:components:{ 组件名 }
生命周期钩子函数:
beforecreate created
beforemount mounted
beforeupdate updated
beforeunmount unmounted
操作dom节点:
vue方式操作dom节点方法(也可以操作子组件)
1.需要操作的dom节点 加上ref属性(ref = "自定义命名")
2. 代码获取节点操作
this.$refs.pRef
$refs:
=> vue实例对象的属性
组件通讯:{(父传子)(子传父)(表单组件的双向绑定)(ref方式)(v2中事件总线)}
父传子:
1,在子组件里用props 接收父组件传过来的属性名
2,在父组件里使用子组件的地方绑定一个属性 (:key = "value")(支持传多个 )
子传父:
1. 父组件使用子组件位置 绑定自定义事件 @someEvent="bindEvent"
* 2. 子组件中定义emits选项接收自定义事件 emits:['someEvent']
* 这步可以不写,但建议写上
* 3. 触发自定义事件 this.$emit('someEvent',参数)
表单组件利用v-modle实现双向绑定:
在父组件里定义一个数据 利用v-model绑定该数据
在表单组件里用props:[ modelValue ] 接收
emits:[ 'update:modelValue' ]
再给input输入框绑定value属性 值为modelValue
给input输入框绑定input事件触发emits事件
或利用computed计算属性的get和set方法实现
透传:
“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute或者 v-on 事件监听器。当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。
对 class 和 style 的合并: 对于已有的样式会两者会被合并, 透传相同属性会使用原有的属性
v-on 监听器继承:事件也会透传
阻止透传: inheritAttrs:true, // 阻止透传
插槽:
* 父组件与子组件之间内容传递
* 1. 子组件使用slot标签接收传入的内容
* 2. 内容由多个标签时使用 template标签包裹
* v-slot指令指定默认名称 v-slot:default
* 默认插槽 <slot></slot>
* 3. 具名插槽 <slot name=""></slot>
*
* 4. 作用域插槽
* 本质:子组件通过插槽传参到父组件
在子组件上插槽位置绑定一个自定义属性,属性值为将要传递的数据,
在父组件具名插槽位置命名后面接上=’自定义名字‘
自定义名字.自定义属性名拿到属性值
依赖注入(跨组件传参(跨组件通讯)){ provide提供参数,inject 接收参数}
* 依赖注入:provide-inject
* 实现方式:
* 1. 父组件提供 provide(){ return { 数据 }}
* 如果希望数据是响应式的, computed(()=>this.msg)
* 2. 子组件 通过inject接收数据
* inject:[''] 接收数据为数组形式
* inject:{ //对象形式
* localmessage:{
* from:'message',
* default:'默认值'
* }
* }
动态组件:让多个组件使用同一个挂载点,并动态切换,这就是动态组件
<component>元素:一个用于渲染动态组件或元素的“元组件”
组件缓存 :<KeepAlive></KeepAlive>
使用include l exclude可以设置哪些组件被缓存,使用max可以设定最多缓存多少个
<KeepAlive>包裹动态组件时,会缓存不活跃的组件实例,而不是销毁它们。
当一个组件在(<KeepAlive>中被切换时,它的 activated和deactivated生命周期钩子将被调用,用来替代mounted和unmounted。这适用于<KeepAlive>的直接子节点及其所有子孙节点。
组件如果想要条件性地被KeepAlive缓存,就必须显式声明一个name选项。
异步组件: 服务端定义的组件,通过网络异步获取到前端,再注册使用
同步组件: 前端客户端定义组件
在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。
Vue 提供了defineAsyncComponent方法来实现此功能
首先从vue里引入defineAsyncComponent方法 在声明一个组件名来接收方法执行返回的结果
<Suspense></Suspense>组件(用于加载组件未完成时,显示加载中,加载完成显示组件)
<Suspense>是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态。
vue3新增,模仿了react中 Portal <Teleport>传送门组件</Teleport> 有个to属性表示 传送到哪里
to=‘body’表示传到body下面
<Teleport>是一个内置组件,它可以将一个组件内部的一部分模板"传送"到该组件的DOM结构外层的位置去。有时我们可能会遇到这样的场景:一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在DOM中应该被渲染在整个Vue应用外部的其他地方。
这类场景最常见的例子就是全屏的模态框。理想情况下,我们希望触发模态框的按钮和模态框本身是在同一个组代中,因为它们都与组件的开关状态有关。但这意味着该模态框将与按钮一起渲染在应用DOM结构里很深的地方。这会导致该模态框的CSS布局代码很难写。
<Transition>
是一个内置组件,这意味着它在任意别的组件中都可以被使用,无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发:
- 由
v-if
所触发的切换 - 由
v-show
所触发的切换 - 由特殊元素
<component>
切换的动态组件
内置组件
KeepAlive 缓存动态组件:可以缓存不活跃的组件实例,而不是销毁
Teleport 传送门:可以把子组件内部的内容传送到父组件的dom位置
Suspense 组件
Transition 过渡动画:实现页面的过度效果
异步组件
Suspense组件 异步依赖处理,可以渲染一个加载状态
动态组件(实现选项卡)
让多个组件使用同一个挂载点,并且可以动态切换
<component :is="currentComponent"></component>
自定义指令: 包含组件生命周期函数的特殊对象
实现:
* 1. 定义指令对象
* const foucs = {
* created(el,binding){},
* mounted(el,binding){
* el.focus()
* },
* unmounted(el,binding){}
* }
* 2. 注册指令
* 全局注册
* 指令可以整个应用所有标签使用
* const app = creatApp()
* app.directive('foucs',focus)
* 局部注册
* 只在当前注册的组件标签中使用
* const App = {
* components:{}
* directives:{
* foucs:foucs
* }
* }
自定义指令:
指令的钩子会传递以下几种参数:
-
el
:指令绑定到的元素。这可以用于直接操作 DOM。 -
binding
:一个对象,包含以下属性。value
:传递给指令的值。例如在v-my-directive="1 + 1"
中,值是2
。oldValue
:之前的值,仅在beforeUpdate
和updated
中可用。无论值是否更改,它都可用。arg
:传递给指令的参数 (如果有的话)。例如在v-my-directive:foo
中,参数是"foo"
。modifiers
:一个包含修饰符的对象 (如果有的话)。例如在v-my-directive.foo.bar
中,修饰符对象是{ foo: true, bar: true }
。instance
:使用该指令的组件实例。dir
:指令的定义对象。
-
vnode
:代表绑定元素的底层 VNode。 -
prevNode
:之前的渲染中代表指令所绑定元素的 VNode。仅在beforeUpdate
和updated
钩子中可用。
自定义插件:
一个插件可以是一个拥有 install()
方法的对象,也可以直接是一个安装函数本身。安装函数会接收到安装它的应用实例和传递给 app.use()
的额外选项作为参数:
-
通过 app.component() 和 app.directive() 注册一到多个全局组件或自定义指令。
-
通过 app.provide() 使一个资源可被注入进整个应用。
-
向 app.config.globalProperties 中添加一些全局实例属性或方法
-
一个可能上述三种都包含了的功能库 (例如 vue-router)。
混入技术(mixins)《v2的技术 兼容了v3》
已有对象内容和混入对象内容相冲突时,混入对象不会起效。
filter过滤器 (V2的,V3已删除)
Vue.filter(过滤器名称,过滤器函数)
调用:
<p>{{ 参数|过滤器名称 }}</p>
组件实例:nextTick:
* 作用: 模板界面异步更新完成后再执行nextTick回调函数中代码
vue实例对象方法
* 语法:
* this.$nextTick(()=>{
* // 执行时间
* // dom节点渲染完成后执行
* })
- 什么是虚拟dom:
- 虚拟dom本质上就是一个普通的JS对象,用于描述视图的界面结构
- 在vue中,每个组件都有一个
render
函数,每个render
函数都会返回一个虚拟dom树,这也就意味着每个组件都对应一棵虚拟DOM树
为什么需要虚拟dom?
在vue中,渲染视图会调用render函数,在组件创建和数据依赖发生变化时直接使用真实dom会造成大量的性能损耗降低渲染效率,因此,vue在渲染时,使用虚拟dom来替代真实dom,主要为解决渲染效率的问题。