前端常见面试题九

作者: jw_fc89 | 来源:发表于2019-07-09 23:03 被阅读235次

    目录

    1、Vue路由的实现原理 

    2、SPA 路由history模式上线后刷新404 

    3、$route和$router的区别 

    4、自定义过滤器详解

    5、自定义指令详解

    6、assets和static的区别

    1、Vue路由的实现原理

    vue 路由有两种方式:

    1、利用URL中的hash("#");              #本身以及它后面的字符称之为hash可通过window.location.hash属性读取.

    2、利用History interface在HTML5中新增的方法;

    实例

    Hash 的相关操作:

    1、hash虽然出现在url中,但不会被包括在http请求中,它是用来指导浏览器动作的,对服务器端完全无用,因此,改变hash不会重新加载页面。

            hash(window.location.hash)    //获取hash

     2、可以为hash的改变添加监听事件:

    window.addEventListener("hashchange",funcRef,false)

    History

    History interface是浏览器历史记录栈提供的接口,通过back(),forward(),go()等方法,我们可以读取浏览器历史记录栈的信息,进行各种跳转操作。

    从HTML5开始,History interface提供了2个新的方法:pushState(),replaceState()使得我们可以对浏览器历史记录栈进行修改:

    window.history.pushState(stateObject,title,url)

    window.history,replaceState(stateObject,title,url)

    代码结构以及更新视图的逻辑与hash模式基本类似,只不过将对window.location.hash()直接进行赋值window.location.replace()改为了调用history.pushState()和history.replaceState()方法。

    两种模式比较

    一般的需求场景中,hash模式与history模式是差不多的,根据MDN的介绍,调用history.pushState()相比于直接修改hash主要有以下优势:

    1、pushState设置的新url可以是与当前url同源的任意url,而hash只可修改#后面的部分,故只可设置与当前同文档的url

    2、pushState设置的新url可以与当前url一模一样,这样也会把记录添加到栈中,而hash设置的新值必须与原来不一样才会触发记录添加到栈中

    3、pushState通过stateObject可以添加任意类型的数据记录中,而hash只可添加短字符串

    4、pushState可额外设置title属性供后续使用

    history模式的问题:

    服务器上线:修改https://blog.csdn.net/gg451516921/article/details/89406083

    对于单页应用来说,理想的使用场景是仅在进入应用时加载index.html,后续在的网络操作通过ajax完成,不会根据url重新请求页面,但是如果用户直接在地址栏中输入并回车,浏览器重启重新加载等特殊情况。

    hash模式仅改变hash部分的内容,而hash部分是不会包含在http请求中的(hash带#):

    http://oursite.com/#/user/id //如请求,只会发送http://oursite.com/

    所以hash模式下遇到根据url请求页面不会有问题

    而history模式则将url修改的就和正常请求后端的url一样(history不带#)

    http://oursite.com/user/id

    如果这种向后端发送请求的话,后端没有配置对应/user/id的get路由处理,会返回404错误。

    官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。同时这么做以后,服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,在 Vue 应用里面覆盖所有的路由情况,然后在给出一个 404 页面。或者,如果是用 Node.js 作后台,可以使用服务端的路由来匹配 URL,当没有匹配到路由的时候返回 404,从而实现 fallback。

    附代码:https://segmentfault.com/a/1190000014822765

    2、$route和$router的区别

    1、router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。

    举例:history对象     

    $router.push({path:'home'});本质是向history栈中添加一个路由,在我们看来是 切换路由,但本质是在添加一个history记录

    方法:$router.replace({path:'home'});//替换路由,没有历史记录

    2、route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应name ,path, params ,query等

    我们可以从vue devtools中看到每个路由对象的不同

    $router 的属性:

    $route.path

    字符串,等于当前路由对象的路径,会被解析为绝对路径,如"/home/news"。

    $route.params

    对象,包含路由中的动态片段和全匹配片段的键值对

    $route.query

    对象,包含路由中查询参数的键值对。例如,对于/home/news/detail/01?favorite=yes,会得到$route.query.favorite == 'yes'。

    $route.router

    路由规则所属的路由器(以及其所属的组件)。

    $route.matched

    数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。

    $route.name

    当前路径的名字,如果没有使用具名路径,则名字为空。

    3、自定义过滤器详解

    1、创建过滤器

    2、过滤器使用

    语法:

      <any>{{表达式 | 过滤器}}</any>

    举个例子:

      <h1>{{price | myCurrency}}</h1>

    3、过滤器高级用法   (在使用过滤器的时候,还可以指定参数,来告诉过滤器按照参数进行数据的过滤)

     ①如何给过滤器传参?

    <h1>{{price | myCurrency('¥',true)}}</h1>

    ②如何在过滤器中接收到?

    附代码:https://www.jb51.net/article/127607.htm

    4、自定义指令详解


    语法:

    Vue.directive(id, definition)

    PS            <h1 v-if="yes">Yes</h1> 其中,if就是指令ID,yes是expression

    Vue.directive()传入接受两个参数,id是指指令ID,definition是指定义对象。其中,定义对象可以提供一些钩子函数。

    一个指令定义对象可以提供如下几个钩子函数 (均为可选):

    bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

    inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

    update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 

    componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

    unbind:只调用一次,指令与元素解绑时调用。

    钩子函数参数

    el:指令所绑定的元素,可以用来直接操作 DOM 。

    binding:一个对象,包含以下属性:

        1、name:指令名,不包括 v- 前缀。

        2、value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。

       3、 oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。

        4、expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。

        5、arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。

        6、modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

        7、vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

        oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    来自官方文档:        除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

    5、assets和static的区别

    相同点:

    assets和static两个都是存放静态资源文件。项目中所需要的资源文件图片,字体图标,样式文件等都可以放在这两个文件下,这是相同点 

    不相同点:

    1、assets中存放的静态资源文件在项目打包时,也就是运行npm run build时会将assets中放置的静态资源文件进行打包上传,所谓打包简单点可以理解为压缩体积,代码格式化。而压缩后的静态资源文件最终也都会放置在static文件中跟着index.html一同上传至服务器

    2、static中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上传,在打包时会提高一定的效率,但是static中的资源文件由于没有进行压缩等操作,所以文件的体积也就相对于assets中打包后的文件提交较大点。在服务器中就会占据更大的空间。所以简单点使用建议如下:

    将项目中template需要的样式文件js文件等都可以放置在assets中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css等文件可以放置在static中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。

    assets  基于webpack :

    为了能让Webpack返回正确的资源路径,你需要使用require('./relative/path/to/file.jpg'),由file-loader进行解析,然后返回处理过的URL。例如:

    static 

    作为对比,在static/下的文件都不会被Webpack处理:它们使用相同的文件名,直接拷贝到最终的路径。你必须使用绝对路径来引用这些文件,取决于在config.js里面加入的build.assetsPublicPath 和 build.assetsSubDirectory。

    相关文章

      网友评论

        本文标题:前端常见面试题九

        本文链接:https://www.haomeiwen.com/subject/uehqkctx.html