当前位置: 首页> 房产> 家装 > app应用_建个公司网站要多少钱_搜一搜_网络推广一个月工资多少

app应用_建个公司网站要多少钱_搜一搜_网络推广一个月工资多少

时间:2025/7/10 18:08:43来源:https://blog.csdn.net/m0_74145101/article/details/145818044 浏览次数:0次
app应用_建个公司网站要多少钱_搜一搜_网络推广一个月工资多少

1.1 声明式编程 vs 命令式编程

案例对比分析

传统命令式实现:

// 创建元素
const div = document.createElement('div')// 设置属性(命令式操作)
div.id = 'counter'
div.textContent = '0'// 挂载到DOM
document.body.appendChild(div)// 更新逻辑(必须手动操作DOM)
setTimeout(() => {div.textContent = '1' // 显式指定如何更新
}, 1000)

Vue声明式实现:

<div id="app">{{ count }}</div><script>
new Vue({el: '#app',data: { count: 0 },mounted() {setTimeout(() => {this.count = 1 // 只需关心数据变化}, 1000)}
})
</script>

关键差异解析

维度命令式声明式
关注点如何做(How)做什么(What)
DOM操作开发者直接操作框架自动处理
代码量与复杂度正相关保持简洁
维护性需要跟踪每个状态变化数据驱动自动更新

设计哲学体现

// Vue内部处理流程示意图
数据变化 → 触发setter → 通知Watcher → 
生成新VDOM → Diff算法 → 精准更新DOM

1.2 响应式系统核心实现

1.2.1 数据劫持原理

代码实现:

function defineReactive(obj, key, val) {const dep = new Dep() // 每个属性对应一个依赖管理器Object.defineProperty(obj, key, {enumerable: true,configurable: true,get: function reactiveGetter() {if (Dep.target) {        // 存在当前Watcher时dep.depend()           // 建立依赖关系}return val},set: function reactiveSetter(newVal) {if (newVal === val) returnval = newVal            // 更新内部值dep.notify()            // 通知所有订阅者}})
}

关键代码解析:

  1. Dep 类:依赖管理器

    • 每个响应式属性对应一个 Dep 实例
    • 负责收集依赖(Watcher)和通知更新
  2. defineProperty 的作用:

    • 拦截操作:在属性被访问和修改时执行自定义逻辑
    • 内存管理:通过闭包维护内部值 val
  3. Dep.target 机制:

    • 全局唯一变量,指向当前正在计算的 Watcher
    • 保证依赖收集的正确性

1.2.2 完整的依赖收集流程

Watcher类核心代码:

class Watcher {constructor(vm, expOrFn, cb) {this.vm = vm           // Vue实例this.cb = cb           // 回调函数this.getter = parsePath(expOrFn) // 路径解析器this.value = this.get() // 初始获取值}get() {Dep.target = this     // 标记当前Watcherlet valuetry {value = this.getter.call(this.vm, this.vm) // 触发getter} finally {Dep.target = null   // 收集完成后重置}return value}update() {this.run()           // 触发回调}run() {const value = this.get()if (value !== this.value) {const oldValue = this.valuethis.value = valuethis.cb.call(this.vm, value, oldValue) // 执行回调}}
}

执行流程解析:

  1. 初始化阶段

    • 创建 Watcher 实例时立即调用 get()
    • 设置 Dep.target = 当前Watcher
    • 执行 getter 函数触发数据属性的 get 拦截器
  2. 依赖收集阶段

    • 在数据属性的 get 中调用 dep.depend()
    • 将当前 Watcher 添加到 Dep 的订阅列表
  3. 更新阶段

    • 数据变化触发 set 拦截器
    • 调用 dep.notify() 遍历执行所有 Watcher 的 update()
    • 执行回调函数完成视图更新

1.2.3 数组的特殊处理

代码示例:

const arrayProto = Array.prototype
const arrayMethods = Object.create(arrayProto);['push', 'pop', 'shift'].forEach(method => {const original = arrayProto[method]def(arrayMethods, method, function mutator(...args) {const result = original.apply(this, args) // 调用原生方法const ob = this.__ob__                 // 获取Observer实例ob.dep.notify()                        // 手动触发通知return result})
})

关键点说明:

  1. 原型链继承:创建继承自Array原型的对象
  2. 方法重写:对变异方法进行拦截
  3. 手动通知:在数组变化后主动触发依赖更新
  4. 实现原理
    arr.__proto__ = arrayMethods // 修改数组原型链
    

1.3 模板编译深度解析

1.3.1 编译过程三个阶段

示例模板:

<div v-if="show"><span>{{ message }}</span>
</div>
阶段一:解析(Parse)

输出AST结构:

{type: 1,tag: 'div',attrsList: [{ name: 'v-if', value: 'show' }],directives: [{ name: 'if', rawName: 'v-if', value: 'show' }],children: [{type: 1,tag: 'span',children: [{type: 2,expression: '_s(message)',text: '{{ message }}'}]}]
}

解析过程关键点:

  • 使用正则表达式匹配标签/属性/指令
  • 构建树形结构的AST节点
  • 记录标签之间的父子关系
阶段二:优化(Optimize)

静态标记结果:

{// ...其他属性static: false,children: [{static: false,children: [{static: false // 包含动态插值表达式}]}]
}

优化策略:

  1. 标记静态节点(无动态绑定)
  2. 标记静态根节点(子树全静态)
  3. 提升静态节点(复用VNode)
阶段三:生成(Generate)

生成的Render函数:

function render() {with(this){return (show) ? _c('div', [_c('span', [_v(_s(message))])]) : _e()}
}

关键函数说明:

  • _c: createElement(创建VNode)
  • _v: createTextVNode(创建文本节点)
  • _s: toString(转换为字符串)
  • _e: createEmptyVNode(创建空节点)

1.4 初始化流程全解析

1.4.1 new Vue() 的执行轨迹

function Vue(options) {this._init(options) // 入口方法
}Vue.prototype._init = function(options) {// 合并选项vm.$options = mergeOptions(...)initLifecycle(vm)   // 初始化生命周期initEvents(vm)      // 初始化事件系统initRender(vm)      // 初始化渲染函数callHook(vm, 'beforeCreate')initInjections(vm)  // 处理injectinitState(vm)       // 核心:初始化响应式系统initProvide(vm)     // 处理providecallHook(vm, 'created')if (vm.$options.el) {vm.$mount(vm.$options.el) // 开始挂载}
}

关键初始化步骤说明:

  1. 选项合并

    • 合并全局配置和实例配置
    • 处理组件继承关系
  2. initState 核心作用

    function initState(vm) {if (opts.props) initProps(vm, opts.props)    // 初始化Propsif (opts.methods) initMethods(vm, opts.methods) // 处理methodsif (opts.data) initData(vm)                  // 响应式处理dataif (opts.computed) initComputed(vm, opts.computed) // 处理计算属性if (opts.watch) initWatch(vm, opts.watch)    // 处理侦听器
    }
    
  3. 生命周期钩子调用时机

    钩子阶段触发时机
    beforeCreate初始化inject/provide之前
    created完成响应式处理,未挂载DOM

1.5 常见问题解析

Q1:为什么data必须是函数?

错误示例:

// 组件选项
data: { count: 0 } // 多个实例会共享同一数据对象

正确写法:

data() {return { count: 0 } // 每次实例化返回新对象
}

原理说明:

  • 组件可能被多次实例化
  • 函数形式保证每个实例都有独立的数据副本

Q2:Vue如何检测数组变化?

  • 无法检测 的情况:

    vm.items[0] = newItem // 索引直接赋值
    vm.items.length = 2   // 修改length
    
  • 正确方式

    Vue.set(vm.items, 0, newItem)
    vm.items.splice(0, 1, newItem)
    

实现原理:

  1. 重写数组变异方法
  2. 对新增元素进行响应式处理
  3. 手动触发依赖通知
关键字:app应用_建个公司网站要多少钱_搜一搜_网络推广一个月工资多少

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: