vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)

温故知新:

组件的认识:

  • 组件是可复用的
  • 把组件当做一种标签使用 使用一次 它内部的代码就会完整的执行一次
  • 类比函数 使用组件就相当于调用函数 实参就相当于组件的属性传值
  • 不用把数据全部放在数据源中,会变化更新或网络请求的数据才放在data中,固定的数据直接写在模板标签中

关于项目的资源打包问题:

  热更新服务:将打包后的静态项目在内存中托管起来

  项目中的本地资源打包时:

  • 引用文件的资源(import)、标签中引入的资源(img-src)会启用loder去加载资源  会被webpack打包
  • 放在data数据源中的网址对应的资源(如把图片等本地资源的路径放在data中)  webpack不会读取data 所以webpack不打包
  • data数据源中的图片应该放网络图片

编辑器写代码有波浪线

v-for:不写key会有警告

解决:绑定一个key 如果没有id就绑定for循环的下标 或者忽略不管没影响

标签的其他地方 命令窗口报错

解决:关闭webpack中配置的eslint的严格检测模式:lintOnSave:false

一、插槽v-slot

v-slot:插槽名    是具名插槽的用法  

       #s1            是插槽的语法糖
没有指定插槽名就是默认插入到插槽,不给插槽插入数据的话,就会使用组件的slot中的数据
插槽名不用使用引号引起来,直接写变量名
插入的内容必须是template标签或者组件 不能是原生的元素

eg:

设计组件里面:

  • 默认槽位:< slot> < /slot>
  • 具名槽位:< slot name="s1"> < /slot>

使用组件时:

< 组件名> 尖括号中的东西插入默认槽位 < /组件名>

< 组件名>

   < template v-slot:s1>插入内容必须放在这个标签中,老版本不用< template>

   < template #s1>插入内容必须放在这个标签中,老版本不用< template>

< /组件名>

(1)组件的属性传值:

   App.vue文件:





  Box1.vue文件:



 结果显示:

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第1张图片

(2)插槽

父组件使用子组件时要在子组件中插入内容 在子组件中就要用插槽来装 否则不会显示出来

插槽的位置在哪 插入的内容就在哪

   App.vue文件:





    Box2.vue文件:





     Box3.vue文件:

 结果显示:

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第2张图片

(3)插槽

   App.vue文件:





   Box4.vue文件:






 结果显示:

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第3张图片

二、组件的自定义事件

  • 事件的三要素: 事件源 事件类型 事件监听器

如:

事件源target:box组件

事件类型type:myevent

使用组件时 绑定监听器,内部触发事件时 监听器就会调用

1.在原生组件(就是html标签)中  事件是由系统来设计触发条件的:

 如:
点我

  App.vue文件:



结果显示: 

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第4张图片

2.在自定义组件中,事件是由自己来设计什么时候触发:

绑定事件:

  • Box组件是事件源  
  • myevent是Box组件绑定的事件类型  
  • fn是Box组件上面绑定的监听器

事件设计:
在Box组件内部,可以在想要的条件下去触发事件

以下代码放在想触发自定义事件的地方 
this.$emit("myevent","要给触发的事件的函数传入的参数")

(1)自定义事件

   App.vue文件:



  Box.vue文件:




  结果显示: 

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第5张图片

(2)组件中写的只能是自定义事件 就算与系统原生事件一模一样的写法也不能执行

   App.vue文件:



  Box2.vue文件:




  结果显示: 

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第6张图片

3.希望组件绑定原生事件(事件的触发条件设计由系统设计) 

给事件绑定事件修饰符   .native
点我//事件名必须是系统存在的事件

   App.vue文件:



   Box3.vue文件:

  结果显示:

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第7张图片

 三、组件中的网络请求

  配置代理(解决跨域问题):vue的8080服务器请求egg的7001服务器

  vue.config.js中:

devServer: {
    //代理配置,这里只是配置,不用写代理服务器的代码(配置好了它帮我们实现)
    // proxy: {
    // 	'/xxxx': 'http://localhost:7001',
    // },
    proxy: {
      '/xxxx': {
        target: 'http://ip:7001',
        secure: true, //如果代理的target是https接口,需要配置它 
        pathRewrite: {
          '^/xxxx': '/'
        }, //请求时重写pathname
        //如果项目中实际请求的是:http://ip:8080/xxxx/ajax1
        //8080服务器就会帮我们代理 请求:http://ip:7001/ajax1
      },
    },
  }

(1)在组件中引入axios模块 

   App.vue文件:



 结果显示:

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第8张图片

(2)配置公共url:

  main.js中:

  在组件的原型链上配置axios工具,并配置公共网址:

import axios from "axios"
Vue.prototype.$axios=axios
axios.defaults.baseURL="http://ip:8001/xxxx"
//配置公共url 如果这个axios去请求 ajax1 实际网址是:http://ip:8001/xxxx/ajax1
//做网络请求都是基于baseURL
//代理去请求:http://ip:7001/ajax1

    App.vue文件:



 显示结果同上

四、面试题相关

1、组件中的data设计为函数的原因:

1.组件被复用时,data数据源才不会被共用 设计成对象就会被共用 调函数调一次生成一次

2.函数的设计就像懒加载一样 当组件使用时,数据源的对象才会创建 这样设计性能更好

 2、数据劫持的顺序:

this组件对象有很多属性和方法 都是劫持“别人”的:如 data methods props

给this设置成员(初始化)的顺序:属性props>方法methods>数据源data>计算属性computed>对属性监听watch

3、单向数据流:

数据由 根组件-->父组件-->子组件  ,单向修改,不能反向修改

父组件通过属性传值给子组件,子组件内部修改数据,父组件的数据不改变;父组件修改数据,会重新传值给子组件,子组件的数据更新改变

即:

  • 在父传子的前提下,父组件的数据发生会通知子组件自动更新
  • 子组件内部,不能直接修改父组件传递过来的props => props是只读的

 4、vue加载流程

每一个组件在加载时都会调用vue内部的render函数把这个组件的template选项的模板解析为一个js对象,这个对象和DOM节点对象“长得一模一样”,就是为了后面的渲染。调render生成虚拟模板VNode.

然后是数据劫持代理监听等等:

底层设计:发布着/订阅者设计 其实就是写了一个watcher函数去订阅(监听)数据的改变(底层js语法就是Obj.defineproperty,vue3是proxy)

当数据变化以后:

当数据变更的时候,重新构造一颗新的对象树。然后用新的树和旧的树进行比较(diff),记录两棵树的差异。当第二棵树所记录的差异应用到第一棵树所构建的真正的DOM树上(patch),视图更新。(DIFF算法)

比较的过程是 一层一层的比较 父组件和父组件比较 并不会把父组件和子组件比较 同层级时 从两边到中间

比较的过程中 发现差异(组件/标签类型,文本,属性值。注释等) 就会异步地给DOM打补丁(操作页面)

vue——插槽v-slot、组件的自定义事件、网络请求、面试题相关(数据的劫持顺序、单向数据流、DIFF算法)_第9张图片

5、DIFF算法

什么是DIFF?

用JavaScript对象结构表示DOM树的结构,然后用这个树构建一个真正的DOM树,插到文档中

当状态变更的时候,重新构建一颗新的对象树。然后用新的树和就的树进行比较(diff),记录两棵树的差异

当第二棵树所记录的差异应用到第一棵树所构建的真正的DOM树上(patch),视图更新。

DIFF算法的过程
当数据发生改变时,订阅者watcher就会调用patch给真实的DOM打补丁
通过sameVnode进行判断,相同则调用patchVnode方法
patchVnode做了以下操作:
找到对应的真实dom,称为el
如果都有都有文本节点且不相等,将el文本节点设置为Vnode的文本节点
如果oldVnode有子节点而VNode没有,则删除el子节点
如果oldVnode没有子节点而VNode有,则将VNode的子节点真实化后添加到el
如果两者都有子节点,则执行updateChildren函数比较子节点
updateChildren主要做了以下操作:
设置新旧VNode的头尾指针
新旧头尾指针进行比较,循环向中间靠拢,根据情况调用patchVnode进行patch重复流程、调用createElem创建一个新节点,从哈希表寻找 key一致的VNode 节点再分情况操作

 6、在.vue文件中写Sass/SCSS、Less

1.引入外部写的Sass编译后的css文件

2.配置sass的加载器

你可能感兴趣的:(vue.js,前端,javascript,vue.js,组件开发,前端框架)