vue基础+高级用法

发布于:2024-05-15 ⋅ 阅读:(255) ⋅ 点赞:(0)

一、vue基础用法

mvvm的了解/认知

  • 语义化模板
  • mvc - model view controller
  • mvvm - model view view-model

vue是如何利用mvvm思想进行开发

双向数据绑定

  • 花括号,构建了数据与视图的双向绑定
  • 通过视图绑定事件,来处理数据

生命周期-vue示例

  • 建立:beforeCreate=>created=>beforeMount=>mounted
  • 更新:beforeUpdate=>updated
  • 销毁:beforeDestory=>destoryed

生命周期-过程

  • bC:new Vue() - 实例挂载功能
  • c:data、props、methods、computed - 数据操作,不涉及vdom和dom
  • bM:vDom - 围绕vDom做的数据操作,但是不涉及dom
  • m:dom-任何操作
  • bU:bDom更新了的,但是dom还没更新-可以更新数据
  • u:dom已经更新了,但是谨慎操作数据
  • bD:实例vm尚未被销毁-eventBus、store、计时器销毁
  • d:实力完全被销毁-收尾

定向监听 (watch和computed)

相同点

  • 基于vue的依赖收集机制
  • 都是被依赖的数据发生变化触发,进而进行改变
    、处理计算

不同点

  1. 入和出
    computed:多入单出-多个值变化,组成一个值的变化
    watch:单入多出-单个值的变化,进而影响一系列的变更。(这里的多出指的是,在声明的watch变量中,可以针对某一个变量的变化,改变其他变量的值)
  2. 性能上
    computed:会自动diff依赖,如果依赖没有变化,则直接从缓存中读取值
    watch:无论监听值是否变化,只能通过回调获取值
  3. 写法上
    computed:必须有return
    watch:可有可无,有的话也不影响
  4. 时机上
    computed:从首次生成就赋值,开始运行了
    watch:首次默认不执行,可以通过immediate:true

条件v-if & v-show & v-else & v-else-if

  • v-if无dom,不会渲染实际节点和其子节点
  • v-show存在实际节点和其子节点,但不展示、不占位

v-for+key

v-for & v-if 循环的优先级

在vue2.x中,v-if和v-for同时使用,v-for优先级更高
在vue3中,v-if始终高于v-for

key的作用
  1. 模板编译原理 - template => dom
    template=>匹配语法 — 生成AST(虚拟树) : 静态 + 动态 => 转换AST为可执行方法 => render() => dom
  2. key作用
    dom diff - 单层复用、双向指针、优先服用
    key => 快速识别节点的可复用

默认指令

v-once - 只渲染一次
v-text - 只渲染字符串
v-html -渲染html,慎用,防止攻击脚本的注入
v-model - 双向绑定 => :value + @input

二、vue进阶

特征一:模板化

插槽:组件外部维护参数以及结构,内部安排位置
  • 面试点 => 默认插槽实现的方式 => 整个插槽的聚合(将所有的节点整合在一起,插入到对应默认插槽的位置)
  • 问题 => 多个插槽节点分开布局 => 具名插槽
具名插槽 - 通过name标识插槽身份,从而在组件内部区分
  • 面试点 => 所有插槽都是通过name索引,默认插槽其实通过”default“索引。name索引的其实是一段解析上下文的空间
  • 参数的传递、参数的隔离
  • 问题 => 插槽参数自管理 => 作用域插槽
作用域插槽

外部做结构描述勾勒,内部做传参

  • 结构化的传递(jsx)
//具名插槽
let slotNode_header = (
        <div>vue header</div>
    )
//作用域插槽
let scope_slot_content = slotProps => {
        return (
            <div>{slotProps}</div>
        )
    }

render() {
   return (
        // slotNode_header
        scope_slot_content()
    )
}

App.vue

<template>
	<div>
		<HelloWorld>
			//默认插槽
			<p>{{msg1}}</p>
 			<p>{{msg2}}</p>
			<p>{{msg3}}</p>
			//具名插槽
			<template v-slot:header>{{headerMsg}}</template>
			//作用域插槽
			<template slot="content" slot-scope="{slotProps}">{{slotProps}}</template>
			//作用域插槽新版本写法
			<template v-slot:slotProps="slotProps">{{slotProps}}</template>
		</HelloWorld/>
	</div>
<template>

HelloWorld.vue

<template>
	<div>
	    //默认插槽
		<slot></slot>
		//具名插槽
		<slot name="header"></slot>
		//作用域插槽
		<slot name="content" :slotProps="slotProps"></slot>
	</div>
<template>













模板的二次加工
  • watch 、computed => 数据与数据之间的加工
  • 复杂的模板相关数据计算
    • 方案一:函数(methods) | 过滤器(filters) => 过滤器拿不到实例
    • 方法二:v-html - 逻辑运算 + 结构拼装 => 安全性
    • 方案三:jsx优点和劣势 => template=>render=>vm.render() diff key 直接绕过template使用render渲染,但是强更新,如果稍微有变量等变化的话,会重新更新render函数
      语法糖实现
options : [{value:1},{value:2}]
render(h){
	 const Node = (
		<p>{this.num>100?100:this.num}</p>
	 )
	 const handleChange = ()=>{}
	 // return Node

return (
	    <ul>
	      {
	        //v-for
	        this.options.map(item=>{
	          return (
	            //嵌入
	            // <itemNode></itemNode>
	            //v-model
	            <itemNode item={item} value={item.value} onInput={this.handleChange}>
	              <Node/>  
	            </itemNode>
	          )
	        })
	      }
	    </ul>
	  )
}

特征二:组件化

Vue.component('component',{
	template:'<h1>xxx</h1>'
})
new Vue({
	el:'#app'
})
  1. 抽象复用
  2. 精简
混入mixin - 逻辑混入
  1. 应用:抽离公共逻辑(逻辑相同,模板不同,可复用mixin)
  2. 合并策略:
    • 变量补充不会被覆盖
    • 生命周期在引用该mixin组件之前
    • 同样被引入的两个mixin,根据引用顺序安排加载顺序
继承拓展extends-逻辑上的共同扩展
  1. 应用:核心逻辑的功能继承
  2. 合并策略:
    • 变量补充,不会覆盖
    • 无论是业务代码还是mixin都在extends之后

extend.js

export default{
	data(){
		return {
			msg:'xxx'
		}
	},
	created(){
		console.log('extend')	
	}
}

helloword.vue

export default{
	mixins:['mixin1'],
	extends:['extend']
	data(){
		return {
			msg:'xxx'
		}
	},
	created(){
		console.log('extend')	
	}
}

执行顺序:extends > mixin > 引入组件

整体拓展类 - extend

从预定的配置中拓展出来一个独立的配置项进行合并
main.js

xxxxxx
new Vue({
	el:'#app',
	component:{App},
	template:'<App/>'
})
//构造一个扩展器
let _baseOptions = {
	data:function(){
		return {
			course:'xx',
			session:'vue'
		}
	}
}
const BaseComponent = Vue.extend(_baseOptions)
new BaseComponent({
	created(){
		console.log('extend componets')
	}
})
以上方法基于vue2的写法,vue3写法如下,不再使用mixin,extends等拓展

addon.js

import {reactive} from 'vue'
export default function addon(){
	const title = 'xxx'
	const obj = reactive({
		name:'xxx',
		value:'xxx'
	})
	return {
		title,obj
	}
}

引入方

<script setup>
import addon from 'addon.js'
const {title:title1,obj:obj1} = addon
</script>

网站公告

今日签到

点亮在社区的每一天
去签到