精华内容
下载资源
问答
  • 高德异步

    一. 介绍

    什么是异步加载:异步加载是和同步加载相对的组件加载方式。同步加载模式又称阻塞模式,在页面加载到该组件时会阻止浏览器的后续处理与后续解析,只有当前加载完成后才会进行下一步的操作。异步加载相反,异步加载模式又称非阻塞加载模式,浏览器在加载js的同时还会进行后续的页面加载。异步加载的方式通常有三种,此次我们主要采用动态创建script标签的方式异步引入高德API。
    近期在做服务器定位的项目,有用到高德组件,但是高德地图比较大,同步引入的话导致页面加载变慢,此外,我的项目也不是单页面应用,还涉及到很多其他业务,异步引入高德API就比较有必要。
    异步加载指的是为 JS API 指定加载的回调函数,在 JS API 的主体资源加载完毕之后,将自动调用该回调函数。回调函数应该声明在 JS API 入口文件引用之前,异步加载可以减少对其他脚本执行的阻塞。

    二. 异步加载AMap组件

    新创建一个aMap.js文件,一般会创建一个plugin文件夹,把这个js文件放到plugin文件夹下。这个文件只加载了AMap组件,需要AMapUI组件的去下一个。
    项目目录
    封装了js文件,之后在需要加载地图的页面直接import就可以,这里还用到了一些Promise的知识(Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息),不清楚的朋友百度看看。

    aMap.js

    /*
     * 异步创建script标签
     */
    export default function MapLoader (key) {
      return new Promise((resolve, reject) => {
        if (window.AMap) {
          resolve(window.AMap)
        } else {
          var script = document.createElement('script')
          const key= '填你申请的key'
          script.type = 'text/javascript'
          script.async = true
          script.src = 'http://webapi.amap.com/maps?v=1.3&callback=initAMap&key=' + key
          script.onerror = reject
          document.head.appendChild(script)
        }
        window.initAMap = () => {
          resolve(window.AMap)
        }
      })
    }
    

    在需要加载组件的.vue文件中,在script标签中
    import MapLoader from '@/plugin/aMap'

    之后在mounted或者created中加载:

    
        MapLoader().then(AMap => {
    
          console.log('地图加载成功')
          this.map = new AMap.Map("container", {
            zoom: 17,
            resizeEnable: true
          })
          // ....你的操作
        }, e => {
          console.log('地图加载失败' ,e)
        })
    
    

    三. 异步加载AMap和AMapUI组件

    同时加载AMap组件和AMapUI组件
    aMapUI.js:

    /*
     * 异步创建script标签
     */
    export default function MapUILoader (key) {
      const mp = new Promise((resolve, reject) => {
        if (window.AMap) {
          resolve(window.AMap)
        } else {
          var script = document.createElement('script')
          const key= '填你申请的api'
          script.type = 'text/javascript'
          script.async = true
          script.src = 'http://webapi.amap.com/maps?v=1.3&callback=initAMap&key=' + key
          script.onerror = reject
          document.head.appendChild(script)
        }
        window.initAMap = () => {
          resolve(window.AMap)
        }
      })
    
      const mpUI = new Promise((resolve, reject) => {
        if (window.AMapUI) {
          resolve(window.AMapUI)
        } else {
          var scriptUI = document.createElement('script')
          scriptUI.type = 'text/javascript'
          scriptUI.src = 'http://webapi.amap.com/ui/1.1/main.js?v=1.1.1'
          scriptUI.onerror = reject
    
          scriptUI.onload = function(su){
            resolve(window.AMapUI)
          };
          document.head.appendChild(scriptUI)
        }
    
      })
    
      return Promise.all([mp,mpUI])
        .then(function (result) {
          return result
        }).catch(e=>{
          console.log(e);})
    }
    
    

    需要加载组件的.vue文件,在created函数中加载:

    
     MapUILoader().then(AMap => {
          console.log("异步加载组件")
        })
        
    

    由于两个API加载都比较慢,有时候可能会出现AMapUI not defined这样的错误,我们需要延时加载1秒:

     if (!window.AMapUI || !window.AMap){
          // 延时加载
          console.log("延时加载中")
          setTimeout(() => {
            // ...你的操作
          }, 1000)
        }
        else{
          //...你的操作
        }
    

    注:在项目的在这里插入图片描述
    文件中,需要声明全局变量AMap和AMapUI:
    在这里插入图片描述

    展开全文
  • 为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。 1.2 我遇到的需求 插件...

    一.举例场景

    1.1 vue官方解释

    在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。

    1.2 我遇到的需求

    • 插件(vue组件)通过一个入口上传
    • 有一个npm(我们称为渲染器)会使用 component is 去加载,所以只能使用全局组件
    • 全局组件注册只能在 new Vue() 之前

    二.详解

    2.1 全局组件在一个项目里面的,因为项目过大做异步加载的情况不做分析

    2.2 我所遇到的情况详解

    • 引入概念
    import Test from '@/components/test.vue'
    
    // 我们可以在mounted函数里面打印一下Test
    export default {
      name: 'app',
      components: {
        Test
      },
      mounted() {
        console.log(Test)
      },
    }
    

    可以看到打印出来的就是一个对象
    image.png
    来,我们再看一下vue 官网
    image.png
    第二个参数传入的是一个 Function 或者 Object ,那么重点来了,我们import导入的组件不正是一个 Object 吗,所以我们可以使用一下方式,把这个对象给存起来

    • 新建一个 component.js
    // 引入我们要单独打包的vue组件
    import chajian from './components/zujian/mamfunc.vue'
    if (typeof window !== 'undefined' && window.Vue) {
      // 在运行这个组件的时候 script引入 或者 eval的时候 我们往一个数组里面push这个对象,存起来
      window.chajian.push(chajian)
    }
    
    export default chajian
    

    打包的话配置一下 webpack 这里不做介绍了,打包完之后我们会打包出来一个 mamfunc.js 这个js我们会通过一个页面上传给后台,比如一个叫 插件管理 的模块,上传之后后台会给你存储到 oss 然后返给你一个访问这个js的 http://xxx.xxx.com 的路径,我们在浏览器直接访问这个路径就可以看到我们打包出来的代码
    image.png
    image.png
    这就是插件管理这一块。

    • 全局挂载组件,解析我们打包出来的js

    比如说我们可能会在另外一个项目里面取使用我们打包出来的js

    <el-row :gutter="20">
      <el-col
        :span="colFunc(se)"
        v-for="(se,index) in searchs"
        :key="index"
        style="margin-bottom: 12px;overflow: hidden;"
       >
        <p :title="se.columnComment" class="query-label">{{se.columnComment}}&nbsp;&nbsp;</p>
        <div style="float:left;width:67%;margin-left: 0;">
          <!--
    				重点就是component is属性 不明白的看一下vue官方文档对这个组件的解释
    			-->
          <component
            :ref="'searchs'+ index"
            :valueCom="valueCom"
            :dataInfo="se"
            :is="se.type"
            :searchType="'searchType'"
           >
          </component>
        </div>
      </el-col>
    </el-row>
    

    我们在这里使用 is 加载我们的组件,前提是这个组件我们已经挂载,也就是通过 Vue.component(a, {}) 挂载上了,砸挂载呢,往下看…

    • 请求插件列表

    上面说到我们有一个插件管理,其实就是一个列表,那么会有一个 api 接口获取我们需要的插件 getPluginList
    重点来了重点来了重点来了

    // 发送请求获取插件列表 
    axios.post('/getPluginList')
    // 获取到一个list
    
    list.data.forEach(item => {
      const { fileName, href } = item
      Vue.component(fileName, function(resolve, reject) {
        var XML = new XMLHttpRequest();
        XML.open("GET", href, false);
        XML.send();
        if (XML.status == 200) {
          // 执行以下js chajian这个数组里面就会把这个对象给push进去
          eval(XML.responseText)
          console.log('window.chajian: ', window.chajian)
          // 重点注意一下resolve
          resolve(window.chajian[window.chajian.length - 1])
        }
      })
    })
    

    当然也可以不异步注册,可以通过script的方式加载,但是这样会阻碍UI进程的渲染,造成项目体验不好

    image.png

    展开全文
  • 然而,在官方资料中,并没有涉及到真正的“动态异步组件,经过大量的时间研究和技术分析,我们给出目前比较合理的技术实现方式,并分析一下vue动态异步组件的实现思路。动态/异步组件的问题官网中介绍,动态组件是...

    前言:在vue

    官方资料中,我们可以可以很学会如何通过vue构建“动态组件”以及“异步组件”,然而,在官方资料中,并没有涉及到真正的“动态异步”组件,经过大量的时间研究和技术分析,我们给出目前比较合理的技术实现方式,并分析一下vue动态异步组件的实现思路。

    动态/异步组件的问题

    官网中介绍,动态组件是通过tagcomponent来构建,在当中绑定组件的引用即可,大致代码如下:

    import compA from './CompA';

    import compB from './CompB';

    import compC from './CompC';

    export default {

    data () {

    return {

    currentComp: compA

    }

    },

    methods: {

    changeComp (name) {

    switch (name) {

    case 'compA' : {

    this.currentComp = compA;

    break;

    case 'compB' :

    this.currentComp = compB;

    break;

    case 'compC' :

    this.currentComp = compC;

    break;

    default :

    this.currentComp = compA;

    break;

    }

    }

    }

    }

    简单说明一下,通过对字符串的判断,来切换组件的实例,实例发生变化后,component组件会自动切换。这就是vue中最基本的动态组件。但是,这样的代码有个很显著的问题:

    所有的组件都是写死的,比如在代码层面上提前定义,即代码5-7行;

    组件的引入是同步的,即便compB和compC在一开始没渲染,但组件的内存已经被加载;

    对于第二点,我们可以很容易的使用require或者import语法来进行异步加载。然而这并没有解决问题1所带来的隐患。按照实际的要求,我们需要一个可以在客户端随意配置的组件,即通过组件的地址或配置在进行动态加载的方式。这就是为什么要进行动态异步组件的构建。

    这种构建方式是刚需的,一方面他可以构筑类似portal中的porlet组件,另一方面,他的实现方式将给组件加载带来巨大的提升。

    构建AsyncComponent

    首先,我们看一下预期的结果,我们希望构建如下的代码模式:

    因此,我们创建一个AsyncComponent.vue文件,并书写代码:

    export default {

    props: {

    path: {

    type: String,

    required: true,

    default: () => null

    }

    },

    data () {

    const componentFile = this.render;

    return {

    componentFile: componentFile

    }

    },

    methods: {

    render () {

    this.componentFile = (resolve) => ({

    component: import(`@/${this.path}`),

    loading: { template: '

    加载中
    ' },

    error: { template: '

    加载错误
    ' },

    delay: 200,

    timeout: 10000

    });

    }

    },

    watch: {

    file () {

    this.render();

    }

    }

    }

    这个代码很好解释:

    组件中传入path属性,构建时候通过render函数创建异步组件;

    render函数为官网的异步组件构建方式;

    监控path属性,当发生变化时,重新通过render函数构建;

    为了能够让组件可被重新激活,并且重用性更高,我们对组件进行更多的参数化,最终结果如下:

    :is="AsyncComponent"

    v-bind="$attrs"

    v-on="$listeners"/>

    v-else

    :is="AsyncComponent"

    v-bind="$attrs"

    v-on="$listeners"/>

    import factory from './factory.js';

    /**

    * 动态文件加载器

    */

    export default {

    inheritAttrs: false,

    // 外部传入属性

    props: {

    // 文件的路径

    path: {

    type: String,

    default: null

    },

    // 是否保持缓存

    keepAlive: {

    type: Boolean,

    required: false,

    default: true

    },

    // 延迟加载时间

    delay: {

    type: Number,

    default: 20

    },

    // 超时警告时间

    timeout: {

    type: Number,

    default: 2000

    }

    },

    data () {

    return {

    // 构建异步组件 - 懒加载实现

    AsyncComponent: factory(this.path, this.delay, this.timeout)

    }

    },

    watch: {

    path () {

    this.AsyncComponent = factory(this.path, this.delay, this.timeout);

    }

    },

    methods: {

    load (path = this.path) {

    this.AsyncComponent = factory(path, this.delay, this.timeout);

    }

    }

    }

    具体改动如下:

    代码第2行增加keep-alive配置,可让组件持久化;

    代码第5行增加属性绑定,可让异步渲染的组件通过外部(async-componenttag)传参;

    代码第6行增加事件绑定,可让异步渲染的组件通过外部(async-componenttag)进行事件监听;

    代码16行为封装异步组件构造器factory(工厂模式),可暴露出去方便其他开发者使用;

    factory函数增加加载组件、错误组件、未定义组件的封装;

    增加了delay、timeout配置;

    暴露了load函数,方便外部JavaScript调用;

    至此,我们可以通过来构建组件,如果path是一个传入属性,通过改变该属性触发watch来重新加载新组件。或者给该组件添加ref属性来获取异步组件容器,通过调用load方法来重新装载。

    后续的问题

    看上去,现在的封装已经非常好,但是距离完美还差很大一截。虽然已经解决了开发人员重复造轮子的问题,并优化了最佳的代码模式,然而我们仍然能发现一个问题:ref之后,拿到的是AsyncComponent组件,并非能像tag一样可以直接对内部组件进行获取。如果按照这样的理想去思考,有利也是有弊的。利是我们构建出了tag的动态异步版,弊是AsyncComponent作为容器的属性很容易被内部的装载物所替换,比如load方法。

    且不考虑这样实现之后的问题,我们可以在开发过程中通过约束来避免,代码中也可以增加属性检测机制。但这样的实现方式非常困难,我尝试过如下方式,均不能实现:

    函数式组件: 通过添加

    functional: true可以把一个组件函数化,这样使得该组件无法获取到

    this即组件实例,因此他所挂载的就是内部的装载组件。然而在构建过程中,出现了无限递归

    render函数的问题,无法解决,而且

    createElement函数无法创建空节点,导致组件总会出现一个不必要的标签。

    抽象化组件: 通过添加abstract: true可以把一个组件抽象化,这样组件是无法渲染其自身,而只会挂在内部的装载组件。但这样做之后,会导致外部容器无法通过ref属性查找到它,更无法获取到装载组件,因此也以失败告终。

    继承式组件: 通过添加extends可以在构建AsyncComponent的时候实现继承,这样装载组件的属性都会传入到AsyncComponent中,然而,这样的方式不支持动态继承,所以还是宣告失败。

    虽然都是失败的结果,但这并不能停止我们的想象,相信未来会有方法来解决这个问题。目前,我们还只能老老实实的把AsyncComponent当做容器来使用。

    动态异步的未来

    你要问我动态异步组件的未来是什么,我会告诉你我们的梦想有多大。我们希望实现分布式前端UIServer,让AsyncComponent可以加载远程组件。远程组件就可以实现配置化,就可以脱离代码本身而进行前端的组件构建。

    展开全文
  • Element 是饿了么前端团队开发的一个基于 Vue.js 的桌面端组件库,它提供的组件非常丰富,不仅功能强大,而且简单易用。 Element 非常的流行,大多数基于 Vue.js 开发的管理系统都会使用到它。 官网地址:...

    Element 介绍

            Element 是饿了么前端团队开发的一个基于 Vue.js 的桌面端组件库,它提供的组件非常丰富,不仅功能强大,而且简单易用。

            Element 非常的流行,大多数基于 Vue.js 开发的管理系统都会使用到它。

            官网地址: https://element.eleme.cn/#/zh-CN

    安装 

    推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。

    npm i element-ui

    不管是完整引入还是按需引入都需要先安装

    完整引入

    2、在 main.js 中配置 element 组件库

    /**
     * 项目的启动入口
     */
    
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    
    // 加载 element 组件库
    import ElementUI from 'element-ui'
    
    // 加载 element 组件库的样式
    import 'element-ui/lib/theme-chalk/index.css'
    
    // 加载全局样式文件
    import './styles/index.less'
    
    // 全局注册 element 组件库
    Vue.use(ElementUI)
    
    Vue.config.productionTip = false
    
    // 创建 Vue 根实例
    // 把 router 配置到根实例中
    // 通过 render 方法把 App 根组件渲染到 #app 入口节点
    new Vue({
      router,
      render: h => h(App)
      // el: '#app' // 等价于 $mount('#app')
    }).$mount('#app')

    使用说明

    用哪个组件就看哪个组件的说明文档。

    复制 -> 粘贴

            

    按需引入

    借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

    首先,安装 babel-plugin-component:

    npm install babel-plugin-component -D

    注意:这里的操作和官网的介绍有所不同

    官网上说的是将.babelrc 修改为:

    注意:

    • 我们最新Vue-cli生成的项目文件已经不叫.babelrc
    • 生成的文件叫babel.config.js 
    • 在官网提供的配置项中 "presets": [["es2015", { "modules": false }]], 没有及时的更新
      • 老版的脚手架中 确实应该写["es2015", { "modules": false }]
      • 但是在新版的脚手架中应该写为["@babel/preset-env", { modules: false }]

    然后,将babel.config.js文件修改为:

    module.exports = {
      presets: [
        '@vue/cli-plugin-babel/preset',
        [
          "@babel/preset-env", { modules: false }
        ]
      ],
      "plugins": [
        [
          "component",
          {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
          }
        ]
      ]
    }
    

    使用说明

            通常我们会在src目录下新建一个element-ui文件夹 里面创建一个index.js文件

            在文件中导入你需要的组件并使用

    import Vue from 'vue'
    import { Button, Select } from 'element-ui'
    
    // Vue.component(Button.name, Button)
    // Vue.component(Select.name, Select)
    
    // 或写为一下形式
    
    Vue.use(Button)
    Vue.use(Select)

    在mian.js中引入文件就好了

    import './element-ui/index.js'

    用哪个组件就看哪个组件的说明文档。

    复制 -> 粘贴

    展开全文
  • element-ui异步加载行政区划树 功能:进入页面,左侧显示行政区划树的顶级目录,单击目录左侧的箭头,则向后端发送请求,获得该级目录的子目录;以此类推;点击目录本身,则向后端发请求和右边的列表进行联动; ...
  • vue element-ui upload组件结合VueCropper 上传图片按照固定尺寸任意剪裁 示例代码 安装VueCropper npm install vue-croppe 在main.js全局引入 import VueCropper from 'vue-cropper' Vue.use(VueCropper) 上传...
  • 如果你使用过 Redux 开发 React,你一定听过 容器组件(Smart/Container Components) 或 展示组件(Dumb/Presentational Components),这样划分有什么样的好处,我们能否能借鉴这种划分方式来编写 Vue 代码呢?...
  • //通过vue异步模板更新UI resolveCall({ props: ['customSettingVal'], template: html, }); ``` 异步组件可以解决动态生成后加载到UI的问题 可是无法解决 别的模块调用全局弹窗时组件UI已无法再次使用 异步组件回...
  • vue高德地图异步加载

    2020-11-21 10:11:30
    /**map.js*/ //引入地图 export function ... }) } /**使用map.js*/ import { MapLoader } from './js/map' MapLoader().then(res => { console.log('%地图异步加载成功%') this.AMap = res[0] this.AMapUI = res[1] }
  • 作者:Matt Maribojoc 译者:前端小智 来源:stackabuse 有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗...Vue3引入了一些新功能,可通过改进异步组件API和新的Suspense组件来帮助我们实现友.
  • 引入组件,并配置在 Vue 原型上。 import { Loading } from "element-ui"; Vue.prototype.$loading = Loading.service; 在需要的组件或页面中使用如下: 在组件中 methods 对象中添加如下方法 loadingShow() {
  • vue 结合element-ui实现pc端高德地图组件

    千次阅读 多人点赞 2019-07-24 10:04:02
    vue 结合 element-ui 实现 pc 端高德地图组件 背景:去年由于业务需求写了一个高德地图组件,前段时间重构了下。 实现的功能有:自动定位,检索地址提示,点击地图获取地址,添加工具栏,拿到的数据经纬度,地址,...
  • Vue 事件绑定v-on:为 HTML 标签绑定事件。 事件指令: 方式一: v-on:事件名称=“函数名称()” 方式二: @事件名称=“函数名称()” 注意: 1.事件名称不要加on 比如: ccc <button @click=“test1()”>ccc 2.事件...
  • vue异步加载高德地图

    2018-06-19 07:17:15
    异步加载 延迟加载 同步加载 用的最多的一种方式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前加载完成,才能进行下一步操作。所以默认同步执行才是安全的。但这样如果js中有输出document...
  • 关于Form表单中restFields()方法的官方解释 ...我最开始所理解的“初始化数据”是指的实例化Vue时在data中所声明的数据。如下图所示: 也就是说,调用restFields()会将数据充值为这里所声明的初...
  • 在写单文件组件时,一般都是把标签、脚本、样式写到一起,这样写个人感觉有点不够简洁,所以就想着把样式分离出去。采用import加载样式在局部作用域(scoped)采用@import加载进来的样式文件,想法是美好的。以为这样...
  • VUE 组件异步加载

    2020-04-07 09:37:41
    当我们页面上引入组件过多时,会导致页面加载速度变得很慢,为了加快页面的渲染速度,我们引入组件使用异步加载,只有当用到这个组件的时间,页面才会去加载组件,这样一来,就大大加快了页面的渲染速度。...
  • 记录Vue结合Element-Ui组件库的安装与基本用法 1. 创建工程 选择一个文件夹 cmd 创建一个名字为 hello-vue 的工程 vue init webpack hello-vue 安装依赖,需要安装 vue-router、element-ui、sass-loader、node...
  • Vue单文件组件 在webpack中使用vue 使用webpack打包发布项目 Vue脚手架 Vue脚手架的自定义配置 Element-UI的基本使用 模块化的分类 浏览器端的模块化 1).AMD(Asynchronous Module Definition,异步模块定义) ...
  • 在市面上找到一个好用的vue树形穿梭框组件都很难,又不想仅仅因为一个穿梭框在element-ui之外引入其他重量级插件,因此就有了el-tree-transfer。轻量,易用,无需投入其他学习成本。el-tree-fransfer是一个基于VUE和...
  • 特别是当子组件使用了某些第三方 UI 组件库的时候,在子组件内进行了 v-model 双向绑定,而该值又需父组件传入 props 进行依赖,于是当第三方组件事件被触发导致 v-model 值发生改变,就产生了冲突,因为此时父级...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,477
精华内容 2,990
关键字:

vue异步引入ui组件

vue 订阅