Vue再次接触后

这篇具有很好参考价值的文章主要介绍了Vue再次接触后。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

  • 看了几天的若依java,最近准备动手《企业数字化平台》中的组织管理部分内容的设计和开发,数据库很快就设计出来了,下步就要动手干活了,发现前端竟然不会,疯了,好在以前看过vue的一点东西,没有写过内容,马上就开始了,工欲善其事必先利其器,把Vue3看一边,然后拿ruoyi前端读一读,如果能看懂,基本就可以动手了。估计得2-3个小时的时间吧,开始整理。

Vue原理

MVVM设计模式

Vue再次接触后,前端,vue.js,前端,javascript

解释

View是视图,就是DOM;对应视图也就是HTML部分--代表UI组件,它负责将数据模型转化成UI展现出来。 Model是模型,就是vue组件里的data,或者说是vuex里的数据;--代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。 ViewModel--监听模型数据也就是data的的改变和控制视图行为、处理用户交互,简单理解就是一个同步View和Model的对象,连接Model和View。

总结

在MVVM架构下,View和Model之间并没有直接的联系,而是通过ViewMode进行交互,Model和ViewModel之间的交互是双向的,因此View数据的变化会同步到Model中,而Model数据的变化也会立即反应到View上。

ViewModel通过双向数据绑定把View层和Model层连接了起来,而View和Model之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。由此,我们可以引出vue是响应式的

响应式

说明

Vue 的响应式原理是核心是通过 ES5 的保护对象的 Object.defindeProperty中的访问器属性中的 get和 set方法,data 中声明的属性都被添加了访问器属性,当读取 data 中的数据时自动调用 get 方法,当修改 data 中的数据时,自动调用 set 方法,检测到数据的变化,会通知观察者 Wacher,观察者 Wacher自动触发重新render 当前组件(子组件不会重新渲染),生成新的虚拟 DOM 树,Vue 框架会遍历并对比新虚拟 DOM 树和旧虚拟 DOM 树中每个节点的差别,并记录下来,最后,加载操作,将所有记录的不同点,局部修改到真实 DOM 树上。

双向数据绑定原理

检测data变化的核心APIObject.defindeProperty

基本使用

const data = {}; 
let name = "张三"; 
Object.defineProperty(data,'name',{ 
          get:function(){ console.log('触发get') return name }, 
          set:function(newVal){ console.log('触发set') name=newVal }
          }) 
//测试 
console.log(data.name) // 触发get 张三 
data.name = '李四' // 触发set

这样就是可以实现数据的获取和赋值的监听

接下来看看vue是如何监听data变化的
//触发更新视图
function updateView() {
    console.log('视图更新')
}
//重新定义数组原型
const oldArrayProperty = Array.prototypo
//创建新对象,原型指向oldArrayProperty,在拓展新的方法(这样不会影响原型)
let arrayProto = Array.prototype
let methods = ['pop', 'shift', 'unshift', 'sort', 'reverse', 'splice', 'push']
methods.forEach(methodName => {
    arrayProto[methodName] = function () {
        updateView ()
        oldArrayProperty[methodName].call(this,...arguments)
    }
})
//监听对象属性
function observer(target){
    if(typeof target !=='object' || target === null) {
        //不是对象或者数组
        return target
    }
    //重新定义数组原型
    if (Array.isArray(target)) {
        target.__proto__ = arrProto
    }
    
    //重新定义各个属性(for in 对象/数组都可以遍历)
    for(let key in target) {
        defineReactive(target,key,target[key])
    }
}
//重新定义属性,监听起来
function defineReactive (target, key, value){
    //递归深度监听
    observer(value)
    //核心API 
    Object.defineProperty(target,key,{
        get(){
            return value
        },
        set(newValue){
            if(newValue !== value) {
                 // 深度监听
                observer(newValue)
                //设置新值
                value = newvalue
                //触发更新视图
                updateView()
            }
        }
    })
}
// 准备数据
const data = {
    name: 'zhangsan',
    age: 20,
    info: {
        address: '北京' // 需要深度监听
    },
    nums: [10, 20, 30]
}
 data.name = 'lisi' //视图更新
 data.age = 21      //视图更新
 console.log('age', data.age) //age 21
 data.x = '100' // 新增属性,监听不到 —— 所以有 Vue.set
 delete data.name // 删除属性,监听不到 —— 所以有 Vue.dete
 data.info.address = '上海' // 深度监听
 data.nums.push(4) // 视图更新

缺点

  • 深度监听obj,需要递归到底,一次性计算量大,如果数据过大页面,页面可能会卡死
  • 无法监听新增属性/删除属性(所以vue提供了Vue.setVue.delete)
  • 无法原生监听数组,需要做特殊处理

在解析Vue3的响应式原理之前,首先需要了解两个ES6新增的API:Porxy与Reflect。

Proxy

Proxy: 代理,顾名思义主要用于为对象创建一个代理,从而实现对对象基本操作的拦截和自定义。可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

Reflect

Reflect: 反射,就是将代理的内容反射出去。Reflect与Proxy一样,也是 ES6 为了操作对象而提供的新 API。它提供拦截JavaScript操作的方法,这些方法与Proxy handlers 提供的的方法是一一对应的,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。且 Reflect 不是一个函数对象,即不能进行实例化,其所有属性和方法都是静态的。

  • 对于基础数据类型只能通过ref来实现其响应式,核心还是将其包装成一个RefImpl对象,并在内部通过自定义的get value() 与 set value(newVal)实现依赖收集与依赖更新。
  • 对于对象类型,ref与reactive都可以将其转化为响应式数据,但其在ref内部,最终还是会调用reactive函数实现转化。reactive函数,主要通过创建了Proxy实例对象,通过Reflect实现数据的获取与修改。

vdom和diff

背景

DOM操作是非常耗时的,Vue 和React 是数据驱动视图,就是 通过 虚拟DOM(vdom)来解决的这个问题

vdom

vdom就是一段js形式的html代码 用 js 模拟 DOM 结构

<div id ='app' class='box'>
    <p>p标签的文本</p>
    <ul style='font-size:20px'>
        <li>li标签文本</li>
    </ul>
</div>

    {
        tag: 'div',
        props: {
            id: 'app',
            className: 'box'
        },
        children: [
            {
                tag: 'p',
                children: 'p标签的文本'
            },
            {
                tag: 'ul',
                props: {
                    style: 'font-size:20px'
                },
                children: [
                    {
                        tag: 'li',
                        children:'li标签文本'
                    }
                ]
            }
        ]
    }
  • tag 标签
  • props 属性(包括 id、className 、 style、事件等)
  • children 子元素,数组或者字符串

拓展
 

可以通过学习snabbdom 进一步了解

var snabbdom = require('snabbdom');
var patch = snabbdom.init([ // Init patch function with chosen modules
  require('snabbdom/modules/class').default, // makes it easy to toggle classes
  require('snabbdom/modules/props').default, // for setting properties on DOM elements
  require('snabbdom/modules/style').default, // handles styling on elements with support for animations
  require('snabbdom/modules/eventlisteners').default, // attaches event listeners
]);
var h = require('snabbdom/h').default; // helper function for creating vnodes

var container = document.getElementById('container');

var vnode = h('div#container.two.classes', {on: {click: someFn}}, [
  h('span', {style: {fontWeight: 'bold'}}, 'This is bold'),
  ' and this is just normal text',
  h('a', {props: {href: '/foo'}}, 'I\'ll take you places!')
]);
// Patch into empty DOM element – this modifies the DOM as a side effect
patch(container, vnode);

var newVnode = h('div#container.two.classes', {on: {click: anotherEventHandler}}, [
  h('span', {style: {fontWeight: 'normal', fontStyle: 'italic'}}, 'This is now italic type'),
  ' and this is still just normal text',
  h('a', {props: {href: '/bar'}}, 'I\'ll take you places!')
]);
// Second `patch` invocation
patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state

解析

  • h 是一个函数,接收三个参数(标签或选择器,属性,子节点数组),返回一个vnode结构;
  • patch 补丁的意思;
  • patch(containerro/容器, vnode/虚拟dom) ,表示把vnode渲染到DOM结构中
  • patch(vnode, newVnode); 表示更新已有的内容(具体怎么计算更新对应的内容就是使用diff算法)
  • patch(containerro, null); 清空DOM结构
diff算法,新旧vnode对比,计算出最小的更新范围

核心
 

  • 同层级比较(只比较同一层级,不跨级比较)
  • tag 不相同,则直接删除重建,不在深度比较
  • tag 和 key,两个都相同,则认为是相同节点,不在深度比较

Vue再次接触后,前端,vue.js,前端,javascript

Vue再次接触后,前端,vue.js,前端,javascript

再此推荐两篇文章

  • 解析vue2.0的diff算法
  • VirtualDOM与diff(Vue实现)

渲染过程

vue组件渲染/更新过程(异步渲染)

  • 初次渲染过程
  • 更新过程
初次渲染过程
  • 解析模板为render函数(一般在开发环境已经完成,vue-loader)4
  • 触发响应式,监听data属性gettersetter(模板中使用到的变量会触发getter)
  • 执行render函数(触发getter),生成vnode,patch(elem,vnode)渲染到页面上

注意

如果模板中没有用的data数据就不会触发getter,因为和视图没关系(vue里面的优化)

更新过程
  • 修改data的数据,触发setter(此前data数据在getter中已被监听)
  • 重新执行render函数,生成newVnode(新的虚拟dom)
  • 使用 patch(vnode,newVnode)更新到页面上

Vue再次接触后,前端,vue.js,前端,javascript

  • 1、编译模板生成render函数,生成vdom
  • 2、执行render函数,触发data中的getter
  • 3、getter方法收集依赖(通俗点就是,在模板里面触发了哪个变量的getter,就把哪个变量观察起来)
  • 4、在依赖中setter修改data中的数据的时候,Notify看下修改的那个数据是不是之前被观察起来的
  • 5、如果是之前观察起来的,就重新渲染( re-render),重新生成render函数,生成newVdom形成一个闭环

路由

vue分为hash(默认)以及 history 两个路由模式

Vue再次接触后,前端,vue.js,前端,javascript

解析

  • protocol - 协议
  • hostname - 主机名
  • port - 端口
  • pathname - url 路径
  • search - ?号之后的参数
  • hash - #号之后的部分
hash

特点

  • hash 变化会触发页面跳转,即浏览器的前进,后退
  • hash 变化不会刷新页面,SPA(单页面)必须的特点
  • hash 永远不会提交到server 端

vue中就是通过hash 的变化触发路由的变化,来触发视图的渲染, js 实现hash

<body>
    <p>
        hash路由
    </p>
    <button id='btn'>
        修改 hash
    </button>
</body>

<script>
 //hash 变化 包括;
    //a. js 修改URL
    //b. 手动修改url的hash
    //c.浏览器的前进、后退
    
    //页面初次加载获取hash
    window.addEventListener ('DOMContentLoaded',() =>{
        console.log('hash',location.hash)
    })
    //hash变化触发
     window.onhashchange = (event) =>{
        console.log('hash',location.hash)
    }
     //js 修改 url
     document.getElementById('btn').addEventListener('click',()=>{
         location.href = '#/user'
     })
</script>
history

h5 history 主要是通过 history.pushState 跳转 和 window.onpopstate 监听页面的前进和后退

<body>
    <p>
       historyh路由
    </p>
    <button id='btn'>
        修改 url
    </button>
</body>

<script>
 
    //页面初次加载获取hash
    window.addEventListener ('DOMCintentLoaded',() =>{
        console.log('load',location.pathname)
    })

     //js 修改 url
     document.getElementById('btn').addEventListener('click',()=>{
         //pushState 有三个参数
         //第一个参数是个js对象,可以放任何的内容,可以在onpostate事件中(后面介绍)获取到便于做相应的、处理。
        //第二个参数是页面标题:目前所有浏览器都不支持,填空字符串即可
        //第三个参数是个字符串,就是保存到history中的url。
         let state= {
             title:'新页面'
         }
         history.pushState(state,'','user')
     })
    
    //监听浏览器的前进、后退
    window.onpostate = (event) => {
        console.log(event.state)  // {title:'新页面'}
        console.log(location.pathname)
    }
</script>

上面的代码如果放在本地html 文件中运行 js代码会报错,需要放在web服务器

注意

history 模式需要后端配合,就是无论用户访问什么路由,所有路由的切换都由前端来做,后端只需要返回index.html的文件,如果后面没有配置兼容,当访问user这个路由,点击刷新,就会报user页面找不到文章来源地址https://www.toymoban.com/news/detail-809627.html

Vue3 快速入门

看懂会用

  1. 简介 | Vue.js 官网教程,多看几遍
  2. 找一个现有代码,从头到尾读一边,每处都能知道啥意思 比如若依vue3版

CRUD

  1. 后端生成一些接口
  2. 在前端比着抄写或者修改,不限于基本框架

啰嗦两句

  1. 从单体程序开始,自己想象如何构建一个单体程序,数据有个外部连接口
  2. 一个主窗体,主工作处理处,所谓路由,就是向这个主舞台塞个大组件
  3. 大组件展现过程是生命周期,渲染展现的基本逻辑
  4. 里面可能有多个小组件, 组件连着很多数据, 需要解决父子关系,传值,事件,插槽,异步等等需要解决
  5. 数据变化 界面变化,响应式,衍生全局状态,共享状态,store等
  6. 解决以上问题,衍生一系列的技术术语,针对场景学习更直接,不然那么抽象,没趣味,学了没有地方用,浪费情感

到了这里,关于Vue再次接触后的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端技术Html,Css,JavaScript,Vue3

    1.基本标签 2.文本格式化 3.链接 4.图片 5.无序列表 6.有序列表 7.表格 8.表单 1.选择器 2.文本和字体 3.链接 4.隐藏 5.定位position 6.浮动 7.对齐 8.图像 1.输出 2.函数 3.常用事件 4.DOM 5.改变Html 6.DOM 元素 (节点) 尾部创建新的 HTML 元素 (节点) - appendChild() 头部创建新的 HTML 元素 (节点)

    2024年02月13日
    浏览(53)
  • 前端(四)——vue.js、vue、vue2、vue3

    😊博主:小猫娃来啦 😊文章核心: vue.js、vue、vue2、vue3从全局到局部 Vue.js是一款流行的JavaScript框架 vue,vue2,vue3都是vue.js的不同版本。 Vue:Vue.js的第一个版本,也称为Vue 1.x。它于2014年首次发布,并获得了广泛的应用和认可。 Vue2:Vue.js的第二个版本,也称为Vue 2.x。它在Vu

    2024年02月12日
    浏览(79)
  • 【前端技术】Vue3 01:初识 Vue.js

    Vue 可以说是非常流行了,至少在国内是这样,他是个轻量级的 JavaScript 框架,非常适合构建大型和中小型的 Web 应用程序,如果想和前端打交道,应该绕不过这个框架吧。 目录 1 Vue.js 介绍 2  IDE 选择 2.1 vscode 2.2 WebStorm 2.3 Eclipse 3  创建 Vue 应用 3.1 本地脚手架创建 ① 安装

    2024年02月02日
    浏览(64)
  • 从javascript到vue再到react:前端开发框架的演变

    目录 JavaScript: 动态语言的基础 JavaScript:Web开发的起点 Vue.js: 渐进式框架的兴起 Vue.js:简洁、高效的前端框架 React.js: 声明式UI的革新 React.js:强大、灵活的前端框架 演变之路与未来展望 演变过程 当提到前端开发中的框架时,JavaScript、Vue.js和React.js是三个最常见的名词。它

    2024年02月07日
    浏览(53)
  • js的鼠标事件(JavaScript的鼠标事件,vue的鼠标事件)

    js鼠标事件,相关属性: vue鼠标事件,相关属性 (js鼠标事件和vue中的鼠标事件区别是省略了on字符):

    2024年02月12日
    浏览(46)
  • 前端开发 5: Vue.js 框架

    在前端开发中,Vue.js 是一个流行且灵活的 JavaScript 框架,用于构建用户界面。它采用了组件化的开发方式,使得前端开发更加模块化和可维护。在本篇博客中,我将为你介绍 Vue.js 的基础知识和常用技巧,帮助你更好地掌握前端开发中的框架部分。 Vue.js 是一个轻量级的 Jav

    2024年01月19日
    浏览(45)
  • vue.js前端框架应用案例

    Vue.js 是一种流行的前端框架,它可以帮助开发者构建单页应用(SPA)和复杂的用户界面。以下是几个 Vue.js 的案例,涵盖了不同领域的应用: Vue.js 官方文档 :Vue.js 的官方文档本身就是一个使用 Vue.js 构建的项目。它展示了 Vue.js 的各种功能和最佳实践,包括组件、指令、混

    2024年02月21日
    浏览(50)
  • Vue.js 现代前端开发的利器

    作者:阿发家的阿花 在当今的前端开发领域,Vue.js已经成为最受欢迎的JavaScript框架之一。它的简洁性、灵活性和强大的功能使其成为许多开发者首选的工具。本文将介绍Vue.js的核心概念、主要特点以及为什么它在现代前端开发中如此重要。我们还将探讨Vue.js在构建交互式和

    2024年02月10日
    浏览(51)
  • 前端埋点需求(vue.js)

    提示:基于运营活动的需求,需要对用户行为进行埋点监控,因此以下文章是代码埋点的实现。 前端埋点有两种:全局埋点、代码埋点。 全局埋点 :收集的用户所有行为,但是收集的数据驳杂,要进行处理。 代码埋点 :收集的用户所有行为更加精准,能够进行更细节的处

    2023年04月13日
    浏览(43)
  • JavaScript框架 Angular、React、Vue.js 的全栈解决方案比较

    在 Web 开发领域,JavaScript 提供大量技术栈可供选择。其中最典型的三套组合,分别是 MERN、MEAN 和 MEVN。前端框架(React、Angular 和 Vue)进行简化比较。 MERN 技术栈包含四大具体组件: MongoDB:一款强大的 NoSQL 数据库,以灵活的 JSON 格式存储数据。 Express.js:一套极简但强大的

    2024年02月03日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包