Vue.js 前端路由和异步组件介绍

目录
  • 文章目标
    • P6
    • P6+ ~ P7
  • 一、背景
  • 二、前端路由特性
  • 三、面试!!!
  • 四、Hash 原理及实现
    • 1、特性
    • 2、如何更改 hash
    • 3、手动实现一个基于 hash 的路由
  • 五、History 原理及实现
    • 1、HTML5 History 常用的 API
    • 2、pushState/replaceState 的参数
    • 3、History 的特性
    • 4、面试!!!
    • 5、手动实现一个基于 History 的路由
  • 六、Vue-Router
    • 1、router 使用
    • 2、动态路由匹配
    • 3、响应路由参数的变化
    • 4、捕获所有路由或 404 Not found 路由
    • 5、导航守卫
    • 6、完整的导航解析流程
    • 7、导航守卫执行顺序(面试!!!)
    • 8、滚动行为(面试!!!)
    • 9、路由懒加载

文章目标

P6

  • 针对 react/vue 能够根据业务需求口喷 router 的关键配置,包括但不限于:路由的匹配规则、路由守卫、路由分层等;
  • 能够描述清楚 history 的主要模式,知道 history 和 router 的边界;

P6+ ~ P7

  • 在没有路由的情况下,也可以根据也无需求,实现一个简单的路由;
  • 读过 router 底层的源码,不要求每行都读,可以口喷关键代码即可;

一、背景

远古时期,当时前后端还是不分离的,路由全部都是由服务端控制的,前端代码和服务端代码过度融合在一起。

客户端 --> 前端发起 http 请求 --> 服务端 --> url 路径去匹配不同的路由 --> 返回不同的数据。

这种方式的缺点和优点都非常明显:

  • 优点:因为直接返回一个 html,渲染了页面结构。SEO 的效果非常好,首屏时间特别快;

    • 在浏览器输入一个 url 开始到页面任意元素加载出来/渲染出来 --> 首屏时间;
  • 缺点:前端代码和服务端代码过度融合在一起,开发协同非常的乱。服务器压力大,因为把构建 html 的工作放在的服务端;

后来 ...随之 ajax 的流行,异步数据请求可以在浏览器不刷新的情况下进行。

后来 ...出现了更高级的体验 —— 单页应用

  •  --> HTML 文件
  • 单页 --> 单个 HTML 文件

在单页应用中,不仅在页面中的交互是不刷新页面的,就连页面跳转也都是不刷新页面的。

单页应用的特点:

  • 页面中的交互是不刷新的页面的,比如点击按钮,比如点击出现一个弹窗;
  • 多个页面间的交互,不需要刷新页面(a/b/ca-> b -> c);加载过的公共资源,无需再重复加载;

而支持起单页应用这种特性的,就是 前端路由

二、前端路由特性

前端路由的需求是什么?

  • 根据不同的 url 渲染不同内容;
  • 不刷新页面;

也就是可以在改变 url 的前提下,保证页面不刷新。

三、面试!!!

Hash 路由和 History 路由的区别?

  • hash 有 #history 没有 #
  • hash 的 # 部分内容不会给服务端,主要一般是用于锚点, history 的所有内容都会给服务端;
  • hash 路由是不支持 SSR 的,history 路由是可以的;
  • hash 通过 hashchange 监听变化,history 通过 popstate 监听变化;

四、Hash 原理及实现

1、特性

hash 的出现满足了这个需求,他有以下几种特征:

  • url 中带有一个 # 符号,但是 # 只是浏览器端/客户端的状态,不会传递给服务端;

    • 客户端路由地址 www.baidu.com/#/user --> 通过 http 请求 --> 服务端接收到的 www.baidu.com/
    • 客户端路由地址 www.baidu.com/#/list/detail/1 --> 通过 http 请求 --> 服务端接收到的 www.baidu.com/
  • hash 值的更改,不会导致页面的刷新;
location.hash = '#aaa';
location.hash = '#bbb';
// 从 #aaa 到 #bbb,页面是不会刷新的
  • 不同 url 会渲染不同的页面;
  • hash 值的更改,会在浏览器的访问历史中添加一条记录,所以我们才可以通过浏览器的返回、前进按钮来控制 hash 的切换;
  • hash 值的更改,会触发 hashchange 事件;
location.hash = '#aaa';
location.hash = '#bbb';

window.addEventLisenter('hashchange', () => {});

2、如何更改 hash

我们同样有两种方式来控制 hash 的变化:

  • location.hash 的方式:
location.hash = '#aaa';
location.hash = '#bbb';
  • html 标签的方式:
<a href="#user" rel="external nofollow" > 点击跳转到 user </a>

<!-- 等同于下面的写法 -->
location.hash = '#user';

3、手动实现一个基于 hash 的路由

  • ./index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./index.css" rel="external nofollow"  />
  </head>
  <body>
    <div class="container">
      <a href="#gray" rel="external nofollow" >灰色</a>
      <a href="#green" rel="external nofollow" >绿色</a>
      <a href="#" rel="external nofollow" >白色</a>
      <button onclick="window.history.go(-1)">返回</button>
    </div>

    <script type="text/javascript" src="index.js"></script>
  </body>
</html>
  • ./index.css
.container {
  width: 100%;
  height: 60px;
  display: flex;
  justify-content: space-around;
  align-items: center;

  font-size: 18px;
  font-weight: bold;

  background: black;
  color: white;
}

a:link,
a:hover,
a:active,
a:visited {
  text-decoration: none;
  color: white;
}
  • ./index.js
/*
  期望看到的效果:点击三个不同的 a 标签,页面的背景颜色会随之变化
*/
class BaseRouter {
  constructor() {
    this.routes = {}; // 存储 path 以及 callback 的对应关系
    this.refresh = this.refresh.bind(this); // 如果不 bind 的话,refresh 方法中的 this 指向 window
    // 处理页面 hash 变化,可能存在问题:页面首次进来可能是 index.html,并不会触发 hashchange 方法
    window.addEventListener('hashchange', this.refresh);

    // 处理页面首次加载
    window.addEventListener('load', this.refresh);
  }

  /**
   * route
   * @param {*} path 路由路径
   * @param {*} callback 回调函数
   */
  route(path, callback) {
    console.log('========= route 方法 ========== ', path);
    // 向 this.routes 存储 path 以及 callback 的对应关系
    this.routes[path] = callback || function () {};
  }

  refresh() {
    // 刷新页面
    const path = `/${location.hash.slice(1) || ''}`;
    console.log('========= refresh 方法 ========== ', path);
    this.routes[path]();
  }
}

const body = document.querySelector('body');
function changeBgColor(color) {
  body.style.backgroundColor = color;
}

const Router = new BaseRouter();

Router.route('/', () => changeBgColor('white'));
Router.route('/green', () => changeBgColor('green'));
Router.route('/gray', () => changeBgColor('gray'));

五、History 原理及实现

hash 有个 # 符号,不美观,服务端无法接受到 hash 路径和参数。

历史的车轮无情撵过 hash,到了 HTML5 时代,推出了 History API

1、HTML5 History 常用的 API

window.history.back(); // 后退

window.history.forward(); // 前进

window.history.go(-3); // 接收 number 参数,后退 N 个页面

window.history.pushState(null, null, path);

window.history.replaceState(null, null, path);

其中最主要的两个 API 是 pushState 和 replaceState,这两个 API 都可以在不刷新页面的情况下,操作浏览器历史记录。

不同的是,pushState 会增加历史记录,replaceState 会直接替换当前历史记录。

2、pushState/replaceState 的参数

  • pushState:页面的浏览记录里添加一个历史记录;
  • replaceState:替换当前历史记录;

他们的参数是⼀样的,三个参数分别是:

  • state:是一个对象,是一个与指定网址相关的对象,当 popstate 事件触发的时候,该对象会传入回调函数;
  • title:新页面的标题,浏览器支持不一,建议直接使用 null
  • url:页面的新地址;

3、History 的特性

History API 有以下几个特性:

  • 没有 #
  • history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面渲染;
  • 可以使用 history.popstate 事件来监听 url 的变化;
  • 只有用户点击浏览器 倒退按钮 和 前进按钮,或者使用 JavaScript 调用 backforwardgo 方法时才会触发 popstate

4、面试!!!

  • pushState 时,会触发 popstate 吗?

    • pushState/replaceState 并不会触发 popstate 事件,这时我们需要手动触发页面的重新渲染;
  • 我们可以使用 popstate 来监听 url 的变化;
  • popstate 到底什么时候才能触发:
    • 点击浏览器后退按钮;
    • 点击浏览器前进按钮;
    • js 调用 back 方法;
    • js 调用 forward 方法;
    • js 调用 go 方法;

5、手动实现一个基于 History 的路由

  • ./index.html
  • ./index.css
.container {
  width: 100%;
  height: 60px;
  display: flex;
  justify-content: space-around;
  align-items: center;

  font-size: 18px;
  font-weight: bold;

  background: black;
  color: white;
}

a:link,
a:hover,
a:active,
a:visited {
  text-decoration: none;
  color: white;
}
  • ./index.js
class BaseRouter {
  constructor() {
    this.routes = {};

    // location.href; => hash 的方式
    console.log('location.pathname ======== ', location.pathname); // http://127.0.0.1:8080/green ==> /green
    this.init(location.pathname);
    this._bindPopState();
  }

  init(path) {
    // pushState/replaceState 不会触发页面的渲染,需要我们手动触发
    window.history.replaceState({ path }, null, path);
    const cb = this.routes[path];
    if (cb) {
      cb();
    }
  }

  route(path, callback) {
    this.routes[path] = callback || function () {};
  }

  // ! 跳转并执行对应的 callback
  go(path) {
    // pushState/replaceState 不会触发页面的渲染,需要我们手动触发
    window.history.pushState({ path }, null, path);
    const cb = this.routes[path];
    if (cb) {
      cb();
    }
  }
  // ! 演示一下 popstate 事件触发后,会发生什么
  _bindPopState() {
    window.addEventListener('popstate', e => {
      /*
        触发条件:
          1、点击浏览器前进按钮
          2、点击浏览器后退按钮
          3、js 调用 forward 方法
          4、js 调用 back 方法
          5、js 调用 go 方法
      */
      console.log('popstate 触发了');
      const path = e.state && e.state.path;
      console.log('path >>> ', path);
      this.routes[path] && this.routes[path]();
    });
  }
}
const Router = new BaseRouter();
const body = document.querySelector('body');
const container = document.querySelector('.container');

function changeBgColor(color) {
  body.style.backgroundColor = color;
}
Router.route('/', () => changeBgColor('white'));
Router.route('/gray', () => changeBgColor('gray'));
Router.route('/green', () => changeBgColor('green'));

container.addEventListener('click', e => {
  if (e.target.tagName === 'A') {
    e.preventDefault();
    console.log(e.target.getAttribute('href')); // /gray  /green 等等
    Router.go(e.target.getAttribute('href'));
  }
});

六、Vue-Router

1、router 使用

使用 Vue.js,我们已经可以通过组合组件来组成应用程序,当你要把 Vue Router 添加进来,我们需要做的是,将组件(components)映射到路由(routes),然后告诉 Vue Router 在哪里渲染它们。

举个例子:

<!-- 路由匹配到的组件将渲染在这里 -->
<div id="app">
  <router-view></router-view>
</div>
// 如果使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)

// 1、定义(路由)组件
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' };
const Bar = { template: '<div>bar</div>' };

// 2、定义路由
//每个路由应该映射一个组件,其中 component 可以是通过 Vue.extend() 创建的组件构造器,或者只是一个组件配置对象
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar },
];

// 3、创建 router 实例,然后传 routes 配置
const router = new VueRouter({
  routes,
});

// 4、创建和挂载根实例
// 记得要通过 router 配置参数注入路由,从而让整个应用都有路由功能
const app = new Vue({
  router,
}).$mount('#app');

2、动态路由匹配

我们经常需要把某种模式匹配到的所有路由,全部映射到同个组件,比如用户信息组件,不同用户使用同一个组件。

可以通过 $route.params.id 或者参数。

const router = new VueRouter({
  routes: [
    // 动态路径参数,以冒号开头
    { path: '/user/:id', component: User },
  ],
});

const User = {
  template: '<div>User: {{ $route.params.id }}</div>',
};

3、响应路由参数的变化

复用组件时,想对 路由参数 的变化作出响应的话,可以使用 watch 或者 beforeRouteUpdate

举个例子:

const User = {
  template: '...',
  watch: {
    $route(to, from) {
      // 对路由变化作出响应...
    },
  },
};

const User = {
  template: '...',
  beforeRouteUpdate(to, from, next) {
    // 对路由变化作出响应...
    // don't forget to call next()
  },
};

4、捕获所有路由或 404 Not found 路由

当时用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该在 最后

举个例子:

5、导航守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种方式植入路由导航过程中:

  • 全局的

    • 全局前置守卫:router.beforeEach
    • 全局解析守卫:router.beforeResolve
    • 全局后置钩子:router.afterEach
  • 单个路由独享的
    • 路由独享守卫:beforeEnter
  • 组件级的
    • beforeRouteEnter
    • beforeRouteUpdate
    • beforeRouteLeave

6、完整的导航解析流程

  • 导航被触发;
  • 在失活的组件里调用离开守卫(前一个组件的 beforeRouteLeave);
  • 调用全局的 beforeEach 守卫;
  • 在重用的组件里调用 beforeRouteUpdate 守卫;
  • 在路由配置里调用 beforeEnter
  • 解析异步路由组件;
  • 在被激活的组件里调用 beforeRouterEnter
  • 调用全局的 beforeResolve 守卫;
  • 导航被确认;
  • 调用全局的 afterEach 钩子;
  • 触发 DOM 更新;
  • 用创建好的实例调用 beforeRouterEnter 守卫中传给 next 的回调函数;

举个例子:

// 全局
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
});

// 全局的导航守卫
router.beforeEach((to, from, next) => {
  console.log(`Router.beforeEach => from=${from.path}, to=${to.path}`);
  // 可以设置页面的 title
  document.title = to.meta.title || '默认标题';
  // 执行下一个路由导航
  next();
});

router.afterEach((to, from) => {
  console.log(`Router.afterEach => from=${from.path}, to=${to.path}`);
});

// 路由独享
const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // 配置数组里针对单个路由的导航守卫
        console.log(`TestComponent route config beforeEnter => from=${from.path}, to=${to.path}`);
        next();
      },
    },
  ],
});

// 组件
const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 comfirm 前调用
    // 不!能!获取组件实例 this,因为当守卫执行前,组件实例还没被调用
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举个例子来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
    // 可以访问组件实例 this
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 this
  },
};

next 必须调用:

  • next():进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed(确认的)。
  • next(false):中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
  • next("/") 或者 next({ path: "/" }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: "home" 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
  • next(error):如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

7、导航守卫执行顺序(面试!!!)

  • 【组件】前一个组件的 beforeRouteLeave
  • 【全局】的 router.beforeEach
    • 【组件】如果是路由参数变化,触发 beforeRouteUpdate
  • 【配置文件】里,下一个的 beforeEnter
  • 【组件】内部声明的 beforeRouteEnter
  • 【全局】的 router.afterEach

8、滚动行为(面试!!!)

vue-router 里面,怎么记住前一个页面的滚动条的位置???

使用前端路由,当切换到新路由时,想要页面滚动到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。

Vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。

【注意】:这个功能只在支持 history.pushState 的浏览器中可用。

scrollBehavior 生效的条件:

  • 浏览器支持 history API
  • 页面间的交互是通过 goforwardback 或者 浏览器的前进/返回按钮
window.history.back(); // 后退
window.history.forward(); // 前进
window.history.go(-3); // 接收 number 参数,后退 N 个页面

举个例子

// 1. 记住:手动点击浏览器返回或者前进按钮,记住滚动条的位置,基于 history API 的,其中包括:go、back、forward、手动点击浏览器返回或者前进按钮
// 2. 没记住:router-link,并没有记住滚动条的位置

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
  scrollBehavior: (to, from, savedPosition) => {
    console.log(savedPosition); // 已保存的位置信息
    return savedPosition;
  },
});

9、路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

举个例子:

const Foo = () => import(/* webpackChunkName: "foo" */ './Foo.vue');

const router = new VueRouter({
  routes: [{ path: '/foo', component: Foo }],
});

到此这篇关于Vue.js 前端路由和异步组件介绍的文章就介绍到这了,更多相关Vue.js 异步组件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决vue动态路由异步加载import组件,加载不到module的问题

    报错信息应该是这样的 webpackEmptyContext (eval at ./src/store/modules sync recursive (0.js:10), <anonymous>:2:10) 路由信息由后端给出,那么前端需要动态加载路由,同时component的路径也是后端给出,但是动态加载该路径会报错 如: // 假如path = '@/views/user' const com = () => import(path) // 这样会报错哦 const com2 = (

  • vue3 vite异步组件及路由懒加载实战示例

    目录 引言 一.前言 1-1.三点变化: 1-2.引入辅助函数defineAsyncComponent的原因: 二.Vue 2.x与Vue 3.x定义比较 2-1.异步组件/路由定义比较 2-2.声明方式比较 2-3.异步组件加载函数返回比较 三.Vue3实践 3-1.路由懒加载实现 3-2.异步组件实现 四.总结 引言 在 Vue2 中,异步组件和路由懒加载处理使用 import 就可以很轻松实现.但是在Vue 3.x 中异步组件的使用与 Vue 2.x 完全不同了.本文就详细讲讲vue3中异

  • Vue组件开发之异步组件详解

    目录 一.引入 二.vue中的异步组件 三.异步组件和suspense 总结 一.引入 我们在讲异步组件之前,我们再来回顾一下webpack打包时的分包操作.我们可以使用import()异步加载模块来实现分包操作.import函数的返回值是一个Promise,所以我们可以使用then进行下一步处理. 如下图所示为打包后的文件目录,因为我们如果同步加载math.js文件,此时就不存在中间的文件,此时当浏览器请求资源时,就会很慢. 二.vue中的异步组件 通过上面的webpack配置我们明白了为什么

  • vue 组件异步加载方式(按需加载)

    目录 组件异步加载(按需加载) 1.使用() => import() 2.使用resolve => require([’./_account’], resolve) 3. 使用Webpack 的内置语句:import(*) 4. require.ensure: 怎么实现组件异步加载 1.什么是异步组件 2.为什么需要异步加载组件 3.异步加载组件方法 组件异步加载(按需加载) 有时候打包出来的js文件过大,严重影响访问速度,这个时候我们就不得不考虑相关方法来提速,毕竟这可是会影响浏览量的. 如

  • 一文搞懂Vue3中的异步组件defineAsyncComponentAPI的用法

    目录 前言 传递工厂函数作为参数 传递对象类型作为参数 总结 前言 当我们的项目达到一定的规模时,对于某些组件来说,我们并不希望一开始全部加载,而是需要的时候进行加载:这样的做得目的可以很好的提高用户体验. 为了实现这个功能,Vue3中为我们提供了一个方法,即defineAsyncComponent,这个方法可以传递两种类型的参数,分别是函数类型和对象类型,接下来我们分别学习. 传递工厂函数作为参数 defineAsyncComponent方法接收一个工厂函数是它的基本用法,这个工厂函数必须返回

  • vue3.0+vite2实现动态异步组件懒加载

    创建一个vite项目 性能决定成败;vite确实快: cmd 命令行(默认你已经安装了node & npm),执行npm init @vitejs/app vue-study – --template vue: cd至vue-study,npm install(安装依赖); npm run dev(启动项目): 创建组件 新建一个目录为pages,pages下面再新建一个目录contents,contens下面可以新建具体的组件目录页面,此时目录结构为 App.vue <template&g

  • Vue3异步数据加载组件suspense的使用方法

    目录 前言 创建组件 总结 前言 Vue3 增加了很多让人眼前一亮的特征,suspense 组件就是其中之一,对处理异步请求数据非常实用,本文通过简单的实例介绍其使用方法,如对其有兴趣,可以参阅官方文档. 通常组件在正确呈现之前需要执行某种异步请求是很常见的,通常是通过设计一种机制开发人员按照机制处理这个问题,有很多很好的方法实现这个需求. 例如,从一个 API 异步获取数据,并希望在获取响应数据解析完时显示一些信息,如 loading 效果,在Vue3中可以使用 suspense 组件来执行这

  • vue实现按需加载组件及异步组件功能

    说实话,我一开始也不知道什么叫按需加载组件,组件还可以按需加载???后来知道了 学不完啊...没关系,看我的 按需加载组件,或者异步组件,主要是应用了component的 is 属性 template中的代码: 这里的每一个按钮,都要显示不同的组件,所以我让他们使用了同一个方法名 <template slot-scope="scope"> <el-button type="text" size="mini" @click=&qu

  • Vue.js 前端路由和异步组件介绍

    目录 文章目标 P6 P6+ ~ P7 一.背景 二.前端路由特性 三.面试!!! 四.Hash 原理及实现 1.特性 2.如何更改 hash 3.手动实现一个基于 hash 的路由 五.History 原理及实现 1.HTML5 History 常用的 API 2.pushState/replaceState 的参数 3.History 的特性 4.面试!!! 5.手动实现一个基于 History 的路由 六.Vue-Router 1.router 使用 2.动态路由匹配 3.响应路由参数的变

  • vue.js前端网页弹框异步行为示例分析

    目录 1. 序 2. 找两个弹框组件看看 3. 自己肝一个 3.1. 封装 Promise 3.2. 确定时允许异步等待 3.3. 细节完善 3.4. 改革 1. 序 网页弹框是个很常见的功能,比如需要告知用户消息的时候 (Alert),需要用户进行确认的时候 (Confirm),需要用户补充一点信息的时候 (Prompt) -- 甚至可以弹框让用户填写表单 (Modal Dialog). 弹框之后,开发者需要知道这个弹框是什么时候关闭以便进行接下来的操作. 在比较古老的 UI 组件中,这个事情

  • Vue.js每天必学之组件与组件间的通信

    什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 使用组件 注册 之前说过,我们可以用 Vue.extend() 创建一个组件构造器: var MyComponent = Vue.extend({ // 选项... }) 要把这个构造器用作组件,需要用 `Vue.compone

  • Vue.js一个文件对应一个组件实践

    这方面官网给的示例是需要工具来编译的,但是nodejs又没有精力去学,只好曲线救国.VueJS的作者在另一个网站有一篇文章讲到可以用jQuery.getScript或RequireJS实现组件,却没有给示例,于是自己摸索出了一种方法. 用到的工具: vue.js --- 0.12.+ (需要0.12中async component支持) require.js text.js --- RequireJS text plugin https://github.com/requirejs/text 文

  • Vue.js仿微信聊天窗口展示组件功能

    源码:https://github.com/doterlin/vue-wxChat 演示地址:https://doterlin.github.io/vue-wxChat/ 运行 # install dependencies npm install # serve with hot reload at localhost:8080 npm run dev # build for production with minification npm run build 介绍 支持文本和图片的展示(后续将

  • vue.js通过路由实现经典的三栏布局实例代码

    经典的三栏布局效果图如下: 三栏布局 •将布局的各个区块定义成组件 <template id="header"> <div class="header bg-primary text-center"> <h3>头部区域</h3> </div> </template> <template id="left"> <div class="left bg-

  • Vue.js实现一个自定义分页组件vue-paginaiton

    vue实现一个分页组件vue-paginaiton vue使用了一段时间的感触就是,我再也不想直接操作DOM了.数据绑定式的编程体验真是好.实现的一个分页组件. 这里的css就不放出来了,可以看直接去github上下载:vue-pagination 先上一张实例图吧 模版 <div class="page-bar"> <ul> <li v-if="showFirstText"><a v-on:click="cur-

  • Vue.js框架路由使用方法实例详解

    Vue.js框架路由使用方法实例详解 html代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name='viewport' content='width=device-width,initial-

  • 详解从Vue.js源码看异步更新DOM策略及nextTick

    写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出. 文章的原地址:https://github.com/answershuto/learnVue. 在学习过程中,为Vue加上了中文的注释https://github.com/answershuto/learnVue/tree/master/vue-src,希望可以对其他想学习Vue源码的小伙伴有所帮助. 可能会有理解存在偏差的地方,欢迎提issue指出,

  • vue.js $refs和$emit 父子组件交互的方法

    本文介绍了vue.js $refs和$emit 父子组件交互的方法,分享给大家,废话不多说直接看代码: <strong>父调子 $refs (把父组件的数据传给子组件) </strong><br><br><template> <div id="app"> <input type="button" name="" id="" @click="

随机推荐