建站教程

建站教程

Products

当前位置:首页 > 建站教程 >

VUE框架:基础知识及核心原理(Vue文本模糊匹配功能如何实现)

GG网络技术分享 2025-03-18 16:14 0


VUE框架:基础知识及核心原理

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架

特点:易用、灵活、高效

全家桶:vue + components(vue element / iview...) + vue-router + vuex + vue-cli

类库 vs 插件 vs 组件 vs 框架

  • 类库:jquery、zepto、underscore...
  • 插件:dialog、banner、drag、tab、iscroll...
  • 组件:bootstrap、swiper...
  • 框架:backbone、angular、vue、react、uni-app、react native、flutter...

声明式和命令式

  • 命令式编程:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现,例如for循环
  • 声明式编程:告诉“机器”你想要的是什么(what),让机器想出如何去做(how),例如数组内置方法forEach等

MVC & MVVM

  • 传统操作DOM模式
  • MVC:model view controller
  • MVVM:model view viewModel


点击添加图片描述(最多60个字)


点击添加图片描述(最多60个字)

<div id=\"app\">

{{msg}}

</div>

<!-- IMPORT JS -->

< src=\"node_modules/vue/dist/vue.min.js\"></>

<>

new Vue({

el: \'#app\',

data: {

msg: \'hello world\'

}

});

setTimeout(() => {

vm.msg = \'你好世界\';

}, 1000);

</>

<div id=\"app\">

人民币:¥<input type=\"text\" v-model=\'price\'>元

<br>

美元:${{price/8}}

</div>

<!-- IMPORT JS -->

< src=\"node_modules/vue/dist/vue.min.js\"></>

<>

let vm = new Vue({

el: \'#app\',

data: {

price: 0

}

});

</>

VUE的基础语法

new Vue(options)

  • 返回值vm(viewModel)
  • el:不能挂载到html或者body上 =>querySelector
  • data
  • 数据值对于对象来说要先声明,否则新增属性无效(可以基于vm.$set处理)
  • vm.arr[0]=xxx 改变数组中的某一项视图不会渲染,需要基于内置的方法,例如:push...
  • 对象或者数组可以整体替换值实现数据变视图也变
  • ...

mustache([ˈmʌstæʃ]) 小胡子语法

  • value
  • JS表达式

常用的指令(directive)

  • v-model
  • v-html / v-text:取消小胡子语法刷新中的闪烁问题
  • v-bind(缩写 :)
  • v-once
  • v-if 和 v-show
  • v-for
  • for in循环 & for of循环
  • 遍历数据类型的范围
  • 原型上方法遍历(或者数组新增的xxx:xxx属性遍历)
  • ......
  • Symbol.iteratoer:Array、Set、Map、String、Arguments、NodeList...
  • v-on 事件绑定
  • v-on:xxx
  • methods :和data类似,都会把方法挂载到vm实例上(this都是当前实例)
  • @xxx
  • @xxx=\"func\" & @xxx=\"func($event,...)\"

directive自定义指令

  • Vue.directive([指令名,省略v-], function(el,bindings,vnode){}
  • el当前元素
  • bindings包含很多信息
  • name:指令名,不包括 v- 前缀
  • value:指令的绑定值
  • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用
  • expression:字符串形式的指令表达式
  • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 \"foo\"
  • modifiers:包含修饰符的对象。例如:my-directive.foo.bar 中,修饰符对象 { foo: true, bar: true }
  • vnode虚拟DOM
  • ctx = vnode.context 获取当前元素所在的上下文
  • ctx[bindings.expression]=xxx 获取上下文中的表达式变量,并且把指定的值赋值给它
  • 钩子函数
  • bind:当用户绑定指令时生效(只调一次)
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前(一个函数的方式就是把bind和update合在一起的写法)
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
  • unbind:只调用一次,指令与元素解绑时调用
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
  • 小练习:创建一个自定义指令控制文本框的校验

事件修饰符

  • 常规:.stop / .prevent / .once ...
  • 按键:.enter 或者 .13 / .up / .down / .left / .right ...
  • 组合修饰符
  • ...

表单元素的处理

  • 普通文本框 或者 文本域
  • 单选框
  • 复选框
  • 下拉框
  • 小案例:全选和非全选

计算属性、过滤器、监听器

  • methods 普通方法
  • filters 过滤器
  • 只能应用到胡子语法和v-bind中
  • 小练习:输入内容的单词首字母大写
  • computed
  • getter & setter
  • 相对于普通方法来讲,计算属性是基于它们的响应式依赖进行缓存的
  • 依赖data中的数据变量
  • 小练习:输入内容的单词首字母大写
  • 小练习:全选和非全选
  • watch
  • 当需要在数据变化时执行异步或开销较大的操作时应用监听器
  • 小练习:全选和非全选
  • 小练习:数据异步绑定的处理

data(){

return {

checked:false, //是否全选

checkModel:[]

}

},

watch:{

checkModel(){

if(this.checkModel.length==this.list.length){

this.checked=true;

}else{

this.checked=false;

}

}

}

复制代码

class和style绑定

  • class的处理(对象语法、数组语法)
  • 内联样式的处理
  • ...

生命周期函数(钩子函数)

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestory
  • destory
  • ...

常用的属性方法

  • $set : 设置响应式数据
  • $el : 挂载的元素
  • $destroy : 销毁vue的实例;同时调用beforeDestroy destroyed
  • $mount : 挂载真实DOM的方法
  • $data : 响应式的对象
  • $options: 是Vue的构造函数的参数
  • $refs : 可以用来获取指定的元素对象 (非受控组件)
  • $on : 订阅
  • $emit : 发布
  • $watch:监控
  • ...

案例:选项卡

案例:购物车计算器

案例:商城类别筛选

双向数据绑定的实现原理

  • Object.defineProperty
  • 实现的底层原理

//observer:观察者

function observer(obj) {

if (obj && typeof obj === \'object\') {

for (let key in obj) {

if (!obj.hasOwnProperty(key)) break;

defineReactive(obj, key, obj[key]);

}

}

}

function defineReactive(obj, key, value) {

observer(value);

Object.defineProperty(obj, key, {

get() {

return value;

},

set(newValue) {

observer(newValue);

if (value === newValue) return;

value = newValue;

}

});

}

function $set(data, key, value) {

defineReactive(data, key, value);

}


点击添加图片描述(最多60个字)

  • Vue 主要通过以下 4 个步骤来实现数据双向绑定的:实现一个监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。
  • 实现一个解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。
  • 实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
  • 实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。

VUE中的组件(component)

组件的特点是:

  • 每个组件就是一个自定义标签
  • 可复用
  • 方便维护
  • 方便拆分
  • 每个组件作用域隔离(互不干扰)
  • 有完整的生命周期
  • 有自己的响应式数据和各种方法(事件)
  • ...

1.全局组件 & 组件的基本语法

  • 组件名字中的一点规范
  • kebab-case:只能调用
  • PasalCase:既可类似前种方式调用,也可以方式调用
  • 调用组件的细节规范
  • 采用双闭合方式
  • 单闭合方式不符合w3c规范(只能识别一个)
  • template
  • 每个组件只能有一个根元素
  • 模板字符串方式
  • template标记方式
  • slot插槽处理
  • 基础操作
  • 多插槽的指定
  • data必须是一个函数,保证不同组件之间的数据互不干扰(返回的对象中初始化数据)
  • ...

<my-component>

<template v-slot:xxx 或者 #xxx>

珠峰培训

</template>

</my-component>

{

templete:`<div>

<slot name=\'xxx\'></slot>

</div>`

}

2.局部组件

  • 创建组件:let componenName={...}
  • 基于components属性声明组件:想用哪个组件需要先声明
  • 使用组件

3.组件信息通讯之父传子:props属性传递

  • 父组件调用到的时候

<my-component aa=\'zhufeng\' :bb=\'xxx\'></my-component>

  • 子组件中基于props声明需要接收的属性值

Vue.component(\'my-component\',{

props:[\'aa\',\'bb\'],

})

  • props中声明的属性和data一样,是响应式数据,挂载到vm实例上,可控制视图渲染
  • props中的一些细节问题
  • 命名大小写:传递的是kebab-case格式,props中获取的是camelCase驼峰命名
  • 指定属性的类型:props:{xxx:String,...}
  • 指定属性的默认值:props:{xxx:{type:String,default:\'xxx\',required:true}}
  • type如果是一个数组,意为指定的多类型皆可以
  • default可以是一个函数,函数返回值是默认值
  • validator自定义验证规则函数:必须符合函数中指定的规则,返回true/false
  • 传递的属性值默认都是字符串格式,如果想要让传递的值是数字、布尔、数组、对象等格式,我们需要使用v-bind处理
  • 样式和class自动合并问题

4.vue的单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。

Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:

  • 加载渲染过程:父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
  • 子组件更新过程:父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
  • 父组件更新过程:父 beforeUpdate -> 父 updated
  • 销毁过程:父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。有两种常见的试图改变一个 prop 的情形 :

  • 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。 在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值
  • 这个 prop 以一种原始的值传入且需要进行转换。 在这种情况下,最好使用这个 prop 的值来定义一个计算属性

5.组件信息通讯之子改父:this.$emit

  • 订阅自定义事件:调用组件的时候基于属性传递一个方法 (父)

<my-component @func=\'xxx\'></my-component>

new Vue({

methods:{

xxx(value){

//=>value是this.$emit时候传递的第二个参数值

}

}

});

  • 通知自定义事件执行 (子)

{

methods:{

xxx(){

this.$emit(\'func\',10);

}

}

}

  • 也可以基于此方法实现兄弟组件(父子组件、隔代组件)之间的信息通信

let eventBus=new Vue; //=>创建事件总线

//A组件

eventBus.$on(\'xxxA\',this.func);

//B组件

eventBus.$emit(\'xxxA\');

6.基于ref实现父子组件信息通信

  • ref 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,基于此可以快速获取和操作子组件中的数据
  • parent和children是获取组件和子组件的实例,只不过$children是一个数组集合,需要我们记住组件顺序才可以

7.基于provide和inject实现祖先与后代的通信

  • 祖先组件基于provide注册需要供后代组件使用的数据

{

provide:{ //=>对象或者返回对象的函数都可以(属性值如果是data中的数据,则必须使用函数的方法进行处理)

name:\'zhufeng\',

year:10

},

}

  • 后代组件基于inject声明需要使用的数据并调取使用

{

inject:[\'name\'],

methods:{

func(){

let name=this.name;

}

}

}

VUE中的TRANSITION动画

1. 什么情况下会用动画

  • 条件渲染 v-if
  • 条件展示 v-show
  • 动态组件 例如:vue-router控制组件渲染
  • ...

2. 如何实现动画

  • 修改元素的样式:style & class
  • 使用JS实现动画(前两周在某些场景下都需要自己直接去操作DOM或者更加的麻烦)
  • 使用vue内置的transition & transition-group

3. transition的基础使用

  • v-enter:定义进入过渡的开始状态,在元素被插入之前生效,在元素被插入之后的下一帧移除
  • v-enter-active:定义进入过渡生效时的状态,在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除
  • v-enter-to: 定义进入过渡的结束状态,元素被插入之后下一帧生效 ,在过渡/动画完成之后移除
  • v-leave: 定义离开过渡的开始状态,在离开过渡被触发时立刻生效,下一帧被移除
  • v-leave-active:定义离开过渡生效时的状态,在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除
  • v-leave-to: 定义离开过渡的结束状态,在离开过渡被触发之后下一帧生效,在过渡/动画完成之后移除
  • 基于 transiton 标记中的 name 属性来进行动画样式区分
  • .demo-enter 等
  • 自定义过渡类名(例如:结合animate.css使用)
  • <transition
  • enter-active-class=\"animated xxx\" leave-active-class=\"animated xxx\"

4.JAVA中的动画钩子函数

  • Velocity.js函数

<transition

@before-enter=\"beforeEnter\"

@enter=\"enter\"

@after-enter=\"afterEnter\"

@before-leave=\"beforeLeave\"

>

</transition>

methods:{

beforeEnter: function (el,done) {

},

}

5. transition-group 处理多组元素动画

  • 如果在transition-group中使用v-for,需要设置:key唯一值
  • 小练习:关键词模糊匹配搜索

综合实战案例

1. 轮播图的实现

2. TASK OA任务管理系统(俗称TODO)

Vue文本模糊匹配功能如何实现

模糊匹配功能在下拉菜单的组件中用的非常多,于是打算写几个demo看看细节上是如何实现的。

一、最简单的模糊匹配:计算属性

<!DOCTYPE html>

<html lang=\"zh-CN\">

<head>

<meta charset=\"UTF-8\">

<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">

<meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">

<title>Document</title>

</head>

<body>

<div id=\"app\">

<input type=\"text\" v-model=\"message\">

<ul>

<li v-for=\"(option, index) in matchedOptions\" :key=\"index\">{{ option }}</li>

</ul>

</div>

<script src=\"./vue.js\"></script>

<script>

new Vue({

el: \'#app\',

data: {

message: \'\',

options: [\'html\', \'css\', \'javascript\']

},

computed: {

matchedOptions() {

if (this.message !== \'\') {

return this.options.filter(option => option.includes(this.message))

}

return this.options

}

}

})

</script>

</body>

</html>

在上面的例子中,计算属性matchedOptions会在文本框内容message变化时筛选options里的数据,效果图如下所示:

Vue文本模糊匹配功能如何实现 (https://www.wpmee.com/) javascript教程 第1张

二、使用作用域插槽实现

使用插槽主要是为了使该功能组件化:在select组件中插入option,然后option通过作用域插槽从select中获取文本值:

<!DOCTYPE html>

<html lang=\"zh-CN\">

<head>

<meta charset=\"UTF-8\">

<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">

<meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">

<title>Document</title>

</head>

<body>

<div id=\"app\">

<my-select>

<template #default=\"{ message }\">

<ul>

<li v-for=\"(option, index) in options\" :key=\"index\" v-show=\"option.includes(message)\">{{ option }}</li>

</ul>

</template>

</my-select>

</div>

<script src=\"./vue.js\"></script>

<script>

Vue.component(\'my-select\', {

template: `

<div class=\"my-select\">

<input type=\"text\" v-model=\"message\">

<slot :message=\"message\"></slot>

</div>

`,

data() {

return {

message: \'\'

}

}

})

new Vue({

el: \'#app\',

data: {

options: [\'html\', \'css\', \'javascript\']

}

})

</script>

</body>

</html>

全局注册了my-select组件后,可以删除app里的message数据,使用v-show来控制选项的显示,运行效果和计算属性方式相同。缺点就是无法单文件化(刚学vue没多久,不知道怎么在单文件里使用作用域插槽,试过直接把template里的东西封装成my-option好像并不管用)

三、混入广播和派发方法在独立组件中实现模糊匹配

首先需要一个emitter文件:

/**

* 子组件广播事件

* @param {string} componentName 子组件名

* @param {string} eventName 事件名

* @param {...any} params 事件参数

*/

function _broadcast(componentName, eventName, ...params) {

this.$children.forEach(child => {

if (child.$options.name === componentName) {

child.$emit(eventName, ...params)

}

_broadcast.call(child, componentName, eventName, ...params)

})

}

/**

* 父组件派发事件

* @param {string} componentName 父组件名

* @param {string} eventName 事件名

* @param {...any} params 事件参数

*/

function _dispatch(componentName, eventName, ...params) {

if (this.$parent) {

if (this.$parent.$options.name === componentName) {

this.$parent.$emit(eventName, ...params)

}

_dispatch.call(this.$parent, componentName, eventName, ...params)

}

}

/**

* mixin

*/

export default {

methods: {

broadcast(componentName, eventName, ...params) {

_broadcast.call(this, componentName, eventName, ...params)

},

dispatch(componentName, eventName, ...params) {

_dispatch.call(this, componentName, eventName, ...params)

}

}

}

注意,这里的$children和$parent都是指具有dom父子关系的vue组件。

最后,通过设置查询条件来控制子组件的显示与隐藏即可实现实时模糊搜索。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

Vue文本模糊匹配功能如何实现 (https://www.wpmee.com/) javascript教程 第2张

标签:

提交需求或反馈

Demand feedback