当前位置: 首页 > news >正文

网站开发招聘 领英电子商务网站的整体规划

网站开发招聘 领英,电子商务网站的整体规划,常用wap网站开发工具 手机网站制,推进网站集约化建设 网络安全一、思考 我们都听过知其然知其所以然这句话 那么不知道大家是否思考过new Vue()这个过程中究竟做了些什么#xff1f; 过程中是如何完成数据的绑定#xff0c;又是如何将数据渲染到视图的等等 一、分析 首先找到vue的构造函数 源码位置#xff1a;src\core\instance\… 一、思考 我们都听过知其然知其所以然这句话 那么不知道大家是否思考过new Vue()这个过程中究竟做了些什么 过程中是如何完成数据的绑定又是如何将数据渲染到视图的等等 一、分析 首先找到vue的构造函数 源码位置src\core\instance\index.js function Vue (options) {if (process.env.NODE_ENV ! production !(this instanceof Vue)) {warn(Vue is a constructor and should be called with the new keyword)}this._init(options) }options是用户传递过来的配置项如data、methods等常用的方法 vue构建函数调用_init方法但我们发现本文件中并没有此方法但仔细可以看到文件下方定定义了很多初始化方法 initMixin(Vue); // 定义 _init stateMixin(Vue); // 定义 $set $get $delete $watch 等 eventsMixin(Vue); // 定义事件 $on $once $off $emit lifecycleMixin(Vue);// 定义 _update $forceUpdate $destroy renderMixin(Vue); // 定义 _render 返回虚拟dom 首先可以看initMixin方法发现该方法在Vue原型上定义了_init方法 源码位置src\core\instance\init.js Vue.prototype._init function (options?: Object) {const vm: Component this// a uidvm._uid uidlet startTag, endTag/* istanbul ignore if */if (process.env.NODE_ENV ! production config.performance mark) {startTag vue-perf-start:${vm._uid}endTag vue-perf-end:${vm._uid}mark(startTag)}// a flag to avoid this being observedvm._isVue true// merge options// 合并属性判断初始化的是否是组件这里合并主要是 mixins 或 extends 的方法if (options options._isComponent) {// optimize internal component instantiation// since dynamic options merging is pretty slow, and none of the// internal component options needs special treatment.initInternalComponent(vm, options)} else { // 合并vue属性vm.$options mergeOptions(resolveConstructorOptions(vm.constructor),options || {},vm)}/* istanbul ignore else */if (process.env.NODE_ENV ! production) {// 初始化proxy拦截器initProxy(vm)} else {vm._renderProxy vm}// expose real selfvm._self vm// 初始化组件生命周期标志位initLifecycle(vm)// 初始化组件事件侦听initEvents(vm)// 初始化渲染方法initRender(vm)callHook(vm, beforeCreate)// 初始化依赖注入内容在初始化data、props之前initInjections(vm) // resolve injections before data/props// 初始化props/data/method/watch/methodsinitState(vm)initProvide(vm) // resolve provide after data/propscallHook(vm, created)/* istanbul ignore if */if (process.env.NODE_ENV ! production config.performance mark) {vm._name formatComponentName(vm, false)mark(endTag)measure(vue ${vm._name} init, startTag, endTag)}// 挂载元素if (vm.$options.el) {vm.$mount(vm.$options.el)}}仔细阅读上面的代码我们得到以下结论 在调用beforeCreate之前数据初始化并未完成像data、props这些属性无法访问到到了created的时候数据已经初始化完成能够访问data、props这些属性但这时候并未完成dom的挂载因此无法访问到dom元素挂载方法是调用vm.$mount方法 initState方法是完成props/data/method/watch/methods的初始化 源码位置src\core\instance\state.js export function initState (vm: Component) {// 初始化组件的watcher列表vm._watchers []const opts vm.$options// 初始化propsif (opts.props) initProps(vm, opts.props)// 初始化methods方法if (opts.methods) initMethods(vm, opts.methods)if (opts.data) {// 初始化data initData(vm)} else {observe(vm._data {}, true /* asRootData */)}if (opts.computed) initComputed(vm, opts.computed)if (opts.watch opts.watch ! nativeWatch) {initWatch(vm, opts.watch)} }我们和这里主要看初始化data的方法为initData它与initState在同一文件上 function initData (vm: Component) {let data vm.$options.data// 获取到组件上的datadata vm._data typeof data function? getData(data, vm): data || {}if (!isPlainObject(data)) {data {}process.env.NODE_ENV ! production warn(data functions should return an object:\n https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function,vm)}// proxy data on instanceconst keys Object.keys(data)const props vm.$options.propsconst methods vm.$options.methodslet i keys.lengthwhile (i--) {const key keys[i]if (process.env.NODE_ENV ! production) {// 属性名不能与方法名重复if (methods hasOwn(methods, key)) {warn(Method ${key} has already been defined as a data property.,vm)}}// 属性名不能与state名称重复if (props hasOwn(props, key)) {process.env.NODE_ENV ! production warn(The data property ${key} is already declared as a prop. Use prop default value instead.,vm)} else if (!isReserved(key)) { // 验证key值的合法性// 将_data中的数据挂载到组件vm上,这样就可以通过this.xxx访问到组件上的数据proxy(vm, _data, key)}}// observe data// 响应式监听data是数据的变化observe(data, true /* asRootData */) }仔细阅读上面的代码我们可以得到以下结论 初始化顺序props、methods、datadata定义的时候可选择函数形式或者对象形式组件只能为函数形式 关于数据响应式在这就不展开详细说明 上文提到挂载方法是调用vm.$mount方法 源码位置 Vue.prototype.$mount function (el?: string | Element,hydrating?: boolean ): Component {// 获取或查询元素el el query(el)/* istanbul ignore if */// vue 不允许直接挂载到body或页面文档上if (el document.body || el document.documentElement) {process.env.NODE_ENV ! production warn(Do not mount Vue to html or body - mount to normal elements instead.)return this}const options this.$options// resolve template/el and convert to render functionif (!options.render) {let template options.template// 存在template模板解析vue模板文件if (template) {if (typeof template string) {if (template.charAt(0) #) {template idToTemplate(template)/* istanbul ignore if */if (process.env.NODE_ENV ! production !template) {warn(Template element not found or is empty: ${options.template},this)}}} else if (template.nodeType) {template template.innerHTML} else {if (process.env.NODE_ENV ! production) {warn(invalid template option: template, this)}return this}} else if (el) {// 通过选择器获取元素内容template getOuterHTML(el)}if (template) {/* istanbul ignore if */if (process.env.NODE_ENV ! production config.performance mark) {mark(compile)}/*** 1.将temmplate解析ast tree* 2.将ast tree转换成render语法字符串* 3.生成render方法*/const { render, staticRenderFns } compileToFunctions(template, {outputSourceRange: process.env.NODE_ENV ! production,shouldDecodeNewlines,shouldDecodeNewlinesForHref,delimiters: options.delimiters,comments: options.comments}, this)options.render renderoptions.staticRenderFns staticRenderFns/* istanbul ignore if */if (process.env.NODE_ENV ! production config.performance mark) {mark(compile end)measure(vue ${this._name} compile, compile, compile end)}}}return mount.call(this, el, hydrating) }阅读上面代码我们能得到以下结论 不要将根元素放到body或者html上可以在对象中定义template/render或者直接使用template、el表示元素选择器最终都会解析成render函数调用compileToFunctions会将template解析成render函数对template的解析步骤大致分为以下几步将html文档片段解析成ast描述符将ast描述符解析成字符串生成render函数 生成render函数挂载到vm上后会再次调用mount方法 源码位置src\platforms\web\runtime\index.js // public mount method Vue.prototype.$mount function (el?: string | Element,hydrating?: boolean ): Component {el el inBrowser ? query(el) : undefined// 渲染组件return mountComponent(this, el, hydrating) }调用mountComponent渲染组件 export function mountComponent (vm: Component,el: ?Element,hydrating?: boolean ): Component {vm.$el el// 如果没有获取解析的render函数则会抛出警告// render是解析模板文件生成的if (!vm.$options.render) {vm.$options.render createEmptyVNodeif (process.env.NODE_ENV ! production) {/* istanbul ignore if */if ((vm.$options.template vm.$options.template.charAt(0) ! #) ||vm.$options.el || el) {warn(You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.,vm)} else {// 没有获取到vue的模板文件warn(Failed to mount component: template or render function not defined.,vm)}}}// 执行beforeMount钩子callHook(vm, beforeMount)let updateComponent/* istanbul ignore if */if (process.env.NODE_ENV ! production config.performance mark) {updateComponent () {const name vm._nameconst id vm._uidconst startTag vue-perf-start:${id}const endTag vue-perf-end:${id}mark(startTag)const vnode vm._render()mark(endTag)measure(vue ${name} render, startTag, endTag)mark(startTag)vm._update(vnode, hydrating)mark(endTag)measure(vue ${name} patch, startTag, endTag)}} else {// 定义更新函数updateComponent () {// 实际调⽤是在lifeCycleMixin中定义的_update和renderMixin中定义的_rendervm._update(vm._render(), hydrating)}}// we set this to vm._watcher inside the watchers constructor// since the watchers initial patch may call $forceUpdate (e.g. inside child// components mounted hook), which relies on vm._watcher being already defined// 监听当前组件状态当有数据变化时更新组件new Watcher(vm, updateComponent, noop, {before () {if (vm._isMounted !vm._isDestroyed) {// 数据更新引发的组件更新callHook(vm, beforeUpdate)}}}, true /* isRenderWatcher */)hydrating false// manually mounted instance, call mounted on self// mounted is called for render-created child components in its inserted hookif (vm.$vnode null) {vm._isMounted truecallHook(vm, mounted)}return vm }阅读上面代码我们得到以下结论 会触发beforeCreate钩子定义updateComponent渲染页面视图的方法监听组件数据一旦发生变化触发beforeUpdate生命钩子 updateComponent方法主要执行在vue初始化时声明的renderupdate方法 render的作用主要是生成vnode 源码位置src\core\instance\render.js // 定义vue 原型上的render方法 Vue.prototype._render function (): VNode {const vm: Component this// render函数来自于组件的optionconst { render, _parentVnode } vm.$optionsif (_parentVnode) {vm.$scopedSlots normalizeScopedSlots(_parentVnode.data.scopedSlots,vm.$slots,vm.$scopedSlots)}// set parent vnode. this allows render functions to have access// to the data on the placeholder node.vm.$vnode _parentVnode// render selflet vnodetry {// Theres no need to maintain a stack because all render fns are called// separately from one another. Nested components render fns are called// when parent component is patched.currentRenderingInstance vm// 调用render方法自己的独特的render方法 传入createElement参数生成vNodevnode render.call(vm._renderProxy, vm.$createElement)} catch (e) {handleError(e, vm, render)// return error render result,// or previous vnode to prevent render error causing blank component/* istanbul ignore else */if (process.env.NODE_ENV ! production vm.$options.renderError) {try {vnode vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)} catch (e) {handleError(e, vm, renderError)vnode vm._vnode}} else {vnode vm._vnode}} finally {currentRenderingInstance null}// if the returned array contains only a single node, allow itif (Array.isArray(vnode) vnode.length 1) {vnode vnode[0]}// return empty vnode in case the render function errored outif (!(vnode instanceof VNode)) {if (process.env.NODE_ENV ! production Array.isArray(vnode)) {warn(Multiple root nodes returned from render function. Render function should return a single root node.,vm)}vnode createEmptyVNode()}// set parentvnode.parent _parentVnodereturn vnode } _update主要功能是调用patch将vnode转换为真实DOM并且更新到页面中 源码位置src\core\instance\lifecycle.js Vue.prototype._update function (vnode: VNode, hydrating?: boolean) {const vm: Component thisconst prevEl vm.$elconst prevVnode vm._vnode// 设置当前激活的作用域const restoreActiveInstance setActiveInstance(vm)vm._vnode vnode// Vue.prototype.__patch__ is injected in entry points// based on the rendering backend used.if (!prevVnode) {// initial render// 执行具体的挂载逻辑vm.$el vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)} else {// updatesvm.$el vm.__patch__(prevVnode, vnode)}restoreActiveInstance()// update __vue__ referenceif (prevEl) {prevEl.__vue__ null}if (vm.$el) {vm.$el.__vue__ vm}// if parent is an HOC, update its $el as wellif (vm.$vnode vm.$parent vm.$vnode vm.$parent._vnode) {vm.$parent.$el vm.$el}// updated hook is called by the scheduler to ensure that children are// updated in a parents updated hook.}三、结论 new Vue的时候调用会调用_init方法 定义 s e t 、 set、 set、get 、 d e l e t e 、 delete、 delete、watch 等方法定义 o n 、 on、 on、off、 e m i t 、 emit、 emit、off等事件定义 _update、 f o r c e U p d a t e 、 forceUpdate、 forceUpdate、destroy生命周期 调用$mount进行页面的挂载 挂载的时候主要是通过mountComponent方法 定义updateComponent更新函数 执行render生成虚拟DOM _update将虚拟DOM生成真实DOM结构并且渲染到页面中
http://www.pierceye.com/news/793753/

相关文章:

  • 哪些网站需要做分享按钮米卓网站建设
  • 做的网站怎样评估价值微商城网站建设平台
  • 后台网站更新 网站没显示广告投放代理商
  • 北京住房保障建设投资中心网站wordpress文章页面修改
  • 游戏网站建设项目规划书案例集约化网站群建设情况
  • 网站策划书编写阿里云部署多个网站
  • 品牌高端网站制作公司佛山新网站建设如何
  • 网站开发中怎么设置快捷键网页设计知名网站
  • 公司网上注册在哪个网站分析网络营销方式
  • 网站用什么颜色外贸企业建站公司
  • 网站下载音乐网站开发公司知乎
  • 什么样式表一般用于大型网站什么是seo搜索
  • 做网站用vue还是用jquery济宁网站建设 中企动力临沂
  • 网站专题教程最吸引人的营销广告词
  • 瑞安网站网站建设如何推广自己的店铺
  • 建设网站花都水泥公司网站建设
  • asp网站怎么下载源码农业做的好的网站
  • 导购网站怎么做视频教学网页设计与制作教程第5版
  • 建设部施工安全管理网站网站建设公司如何
  • 企业商城建站公司网站页面加密
  • 昆山教育云平台网站建设软件工程师考试报名
  • ps做网站大小尺寸大连开发区商场
  • 化妆品网站建设网站右键禁止
  • wordpress 没有样式表网站如何免费做SEO优化
  • 青岛有没有专门做淘宝网站中国建设人才网站
  • 网站移动端是什么问题吗怎样自己做免费的网站
  • 做网站没有做退钱宁波品牌策划公司
  • 网站备案 不关站家乡网页制作模板
  • 成都网站建设企业 排名网络营销推广方案ppt
  • 阳西住房和城乡规划建设局网站微信公众号商城制作