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

织梦小说网站开设赌场罪 网站开发

织梦小说网站,开设赌场罪 网站开发,网站建设的价值体现在哪,中国最知名的网站建设公司前言 我们每天写vue3项目的时候都会使用setup语法糖#xff0c;但是你有没有思考过下面几个问题。setup语法糖经过编译后是什么样子的#xff1f;为什么在setup顶层定义的变量可以在template中可以直接使用#xff1f;为什么import一个组件后就可以直接使用#xff0c;无需…前言 我们每天写vue3项目的时候都会使用setup语法糖但是你有没有思考过下面几个问题。setup语法糖经过编译后是什么样子的为什么在setup顶层定义的变量可以在template中可以直接使用为什么import一个组件后就可以直接使用无需使用components 选项来显式注册组件 vue 文件如何渲染到浏览器上 要回答上面的问题我们先来了解一下从一个vue文件到渲染到浏览器这一过程经历了什么 我们的vue代码一般都是写在后缀名为vue的文件上显然浏览器是不认识vue文件的浏览器只认识html、css、jss等文件。所以第一步就是通过webpack或者vite将一个vue文件编译为一个包含render函数的js文件。然后执行render函数生成虚拟DOM再调用浏览器的DOM API根据虚拟DOM生成真实DOM挂载到浏览器上。 setup编译后的样子 在javascript标准中script标签是不支持setup属性的浏览器根本就不认识setup属性。所以很明显setup是作用于编译时阶段也就是从vue文件编译为js文件这一过程。 我们来看一个简单的demo这个是index.vue源代码 templateh1{{ title }}/h1h1{{ msg }}/h1Child / /templatescript langts setup import { ref } from vue; import Child from ./child.vue;const msg  ref(Hello World!); const title  title; if (msg.value) {const content  content;console.log(content); } /script这里我们定义了一个名为msg的ref响应式变量和非响应式的title变量还有import了child.vue组件。 这个是child.vue的源代码 templatedivi am child/div /template我们接下来看index.vue编译后的样子代码我已经做过了简化 import { ref } from vue; import Child from ./Child.vue;const title  title;const __sfc__  {__name: index,setup() {const msg  ref(Hello World!);if (msg.value) {const content  content;console.log(content);}const __returned__  { title, msg, Child };return __returned__;}, };import {toDisplayString as _toDisplayString,createElementVNode as _createElementVNode,createVNode as _createVNode,Fragment as _Fragment,openBlock as _openBlock,createElementBlock as _createElementBlock, } from vue; function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(),_createElementBlock(_Fragment,null,[_createElementVNode(h1, null, _toDisplayString($setup.title)),_createElementVNode(h1,null,_toDisplayString($setup.msg),1 /* TEXT */),_createVNode($setup[Child]),],64 /* STABLE_FRAGMENT */)); } __sfc__.render  render; export default __sfc__;我们可以看到index.vue编译后的代码中已经没有了template标签和script标签取而代之是render函数和__sfc__对象。并且使用__sfc__.render render将render函数挂到__sfc__对象上然后将__sfc__对象export default出去。 看到这里你应该知道了其实一个vue组件就是一个普通的js对象import一个vue组件实际就是import这个js对象。这个js对象中包含render方法和setup方法。 编译后的setup方法 我们先来看看这个setup方法是不是觉得和我们源代码中的setup语法糖中的代码很相似没错这个setup方法内的代码就是由setup语法糖中的代码编译后来的。 setup语法糖原始代码 script langts setup import { ref } from vue; import Child from ./child.vue;const msg  ref(Hello World!); const title  title; if (msg.value) {const content  content;console.log(content); } /scriptsetup编译后的代码 import { ref } from vue; import Child from ./Child.vue;const title  title;const __sfc__  {__name: index,setup() {const msg  ref(Hello World!);if (msg.value) {const content  content;console.log(content);}const __returned__  { title, msg, Child };return __returned__;}, };经过分析我们发现title变量由于不是响应式变量所以编译后title变量被提到了js文件的全局变量上面去了。而msg变量是响应式变量所以依然还是在setup方法中。我们再来看看setup的返回值返回值是一个对象对象中包含title、msg、Child属性非setup顶层中定义的content变量就不在返回值对象中。 看到这里可以回答我们前面提的第一个问题。 setup语法糖经过编译后是什么样子的 setup语法糖编译后会变成一个setup方法编译后setup方法中的代码和script标签中的源代码很相似。方法会返回一个对象对象由setup中定义的顶层变量和import导入的内容组成。 由template编译后的render函数 我们先来看看原本template中的代码 templateh1{{ title }}/h1h1{{ msg }}/h1Child / /template我们再来看看由template编译成的render函数 import {toDisplayString as _toDisplayString,createElementVNode as _createElementVNode,createVNode as _createVNode,Fragment as _Fragment,openBlock as _openBlock,createElementBlock as _createElementBlock, } from vue; function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(),_createElementBlock(_Fragment,null,[_createElementVNode(h1, null, _toDisplayString($setup.title)),_createElementVNode(h1,null,_toDisplayString($setup.msg),1 /* TEXT */),_createVNode($setup[Child]),],64 /* STABLE_FRAGMENT */)); }我们这次主要看在render函数中如何访问setup中定义的顶层变量title、msgcreateElementBlock和createElementVNode等创建虚拟DOM的函数不在这篇文章的讨论范围内。你只需要知道createElementVNode(h1, null, _toDisplayString($setup.title))为创建一个h1标签的虚拟DOM就行了。 在render函数中我们发现读取title变量的值是通过$setup.title读取到的读取msg变量的值是通过$setup.msg读取到的。这个$setup对象就是调用render函数时传入的第四个变量我想你应该猜出来了这个$setup对象就是我们前面的setup方法返回的对象。 那么问题来了在执行render函数的时候是如何将setup方法的返回值作为第四个变量传递给render函数的呢我在下一节会一步一步的带你通过debug源码的方式去搞清楚这个问题我们带着问题去debug源码其实非常简单。 debug源码搞清楚是如何调用render函数 有的小伙伴看到这里需要看源码就觉得头大了别着急其实很简单我会一步一步的带着你去debug源码。 首先我们将Enable JavaScript source maps给取消勾选了不然在debug源码的时候断点就会走到vue文件中而不是走到编译会的js文件中。 然后我们需要在设置里面的Ignore List看看node_modules文件夹是否被忽略。新版谷歌浏览器中会默认排除掉node_modules文件夹所以我们需要将这个取消勾选。如果忽略了node_modules文件夹那么debug的时候断点就不会走到node_modules中vue的源码中去了。 接下来我们需要在浏览器中找到vue文件编译后的js代码我们只需要在network面板中找到这个vue文件的http请求然后在Response下右键选择Open in Sources panel就会自动在sources面板自动打开对应编译后的js文件代码。 找到编译后的js文件我们想debug看看是如何调用render函数的所以我们给render函数加一个断点。然后刷新页面发现代码已经走到了断点的地方。我们再来看看右边的Call Stack调用栈发现render函数是由一个vue源码中的renderComponentRoot函数调用的。 点击Call Stack中的renderComponentRoot函数就可以跳转到renderComponentRoot函数的源码我们发现renderComponentRoot函数中调用render函数的代码主要是下面这样的 function renderComponentRoot(instance) {const {props,data,setupState,// 省略...}  instance;render2.call(thisProxy,proxyToUse,renderCache,props,setupState,data,ctx) }这里我们可以看到前面的$setup实际就是由setupState赋值的而setupState是当前vue实例上面的一个属性。那么setupState属性是如何被赋值到vue实例上面的呢 我们需要给setup函数加一个断点然后刷新页面进入断点。通过分析Call Stack调用栈我们发现setup函数是由vue中的一个setupStatefulComponent函数调用执行的。 点击Call Stack调用栈中的setupStatefulComponent进入到setupStatefulComponent的源码。我们看到setupStatefulComponent中的代码主要是这样的 function setupStatefulComponent(instance) {const { setup }  Component;// 省略const setupResult  callWithErrorHandling(setup,instance);handleSetupResult(instance, setupResult); }setup函数是Component上面的一个属性我们将鼠标放到Component上面看看这个Component是什么东西 看到这个Component对象中既有render方法也有setup方法是不是感觉很熟悉没错这个Component对象实际就是我们的vue文件编译后的js对象。 const __sfc__  {__name: index,setup() {const msg  ref(Hello World!);if (msg.value) {const content  content;console.log(content);}const __returned__  { title, msg, Child };return __returned__;}, };__sfc__.render  render;从Component对象中拿到setup函数然后执行setup函数得到setupResult对象。然后再调用handleSetupResult(instance, setupResult); 我们再来看看handleSetupResult函数是什么样的下面是我简化后的代码 function handleSetupResult(instance, setupResult) {if (isFunction(setupResult)) {// 省略} else if (isObject(setupResult)) {instance.setupState  proxyRefs(setupResult);} }我们的setup的返回值是一个对象所以这里会执行instance.setupState proxyRefs(setupResult)将setup执行会的返回值赋值到vue实例的setupState属性上。 看到这里我们整个流程已经可以串起来了首先会执行由setup语法糖编译后的setup函数。然后将setup函数中由顶层变量和import导入组成的返回值对象赋值给vue实例的setupState属性然后执行render函数的时候从vue实例中取出setupState属性也就是setup的返回值。这样在render函数也就是template模版就可以访问到setup中的顶层变量和import导入。 现在我们可以回答前面提的另外两个问题了 为什么在setup顶层定义的变量可以在template中可以直接使用 因为在setup语法糖顶层定义的变量经过编译后会被加入到setup函数返回值对象__returned__中而非setup顶层定义的变量不会加入到__returned__对象中。setup函数返回值会被塞到vue实例的setupState属性上执行render函数的时候会将vue实例上的setupState属性传递给render函数所以在render函数中就可以访问到setup顶层定义的变量和import导入。而render函数实际就是由template编译得来的所以说在template中可以访问到setup顶层定义的变量和import导入。。 为什么import一个组件后就可以直接使用无需使用components 选项来显式注册组件 因为在setup语法糖中import导入的组件对象经过编译后同样也会被加入到setup函数返回值对象__returned__中同理在template中也可以访问到setup的返回值对象也就可以直接使用这个导入的组件了。 总结 setup语法糖经过编译后就变成了setup函数而setup函数的返回值是一个对象这个对象就是由在setup顶层定义的变量和import导入组成的。vue在初始化的时候会执行setup函数然后将setup函数返回值塞到vue实例的setupState属性上。执行render函数的时候会将vue实例上的setupState属性也就是setup函数的返回值传递给render函数所以在render函数中就可以访问到setup顶层定义的变量和import导入。而render函数实际就是由template编译得来的所以说在template中就可以访问到setup顶层定义的变量和import导入。
http://www.zqtcl.cn/news/818769/

相关文章:

  • 清华紫光网站建设怎样做团购网站
  • 诸城网站建设费用网站建设便捷
  • 丰台网站建设联系方式全屋定制十大名牌口碑
  • mip网站模板中国建设集团门户网站
  • 笑话 语录用什么网站做搜一搜百度
  • 合肥网站建设新闻营销影视类网站建设
  • 焦作有网站建设公司c 转网站开发
  • 化妆品网站建设报告邯郸在哪个省
  • 自建网站怎么做后台管理系统世界网站流量排名
  • 我做外贸要开国际网站吗官方网站下载微博
  • 佛山专业建设网站网页模板是什么
  • 网站描述标签怎么写wordpress首页图标
  • 做系统去哪个网站好好玩又不用实名认证的游戏
  • 仿帝国网站源码wordpress主题idown
  • 大型网站开发php框架seo全站优化全案例
  • wordpress收录优化做抖音seo用哪些软件
  • DW怎么做招聘网站重庆有什么好玩的
  • 网站建设的网络公司百度官方app下载
  • 医疗电子科技网站建设站群 网站如何做
  • 汇邦团建网站谁做的钢结构招聘网
  • 如何制作一个动态的网站的登录详细步骤页面网站炫酷首页
  • 网站建设找星火龙网站开发 在线支付
  • 如何在公司网站下设置邮箱自己开发一个app要多少钱
  • 珠海市横琴新区建设环保局网站做catia数据的网站
  • 珠海pc网站建设wordpress子主题安全
  • 布吉企业网站建设网站维护与建设内容
  • 专业图书商城网站建设七初SEO网站建设
  • 南通公司网站模板建站wordpress设置主页
  • 小企业网站建设哪找广州app开发平台
  • 建设部国家标准网站免费网站建设 免备案