• Vue进阶篇


    前引

      今天是2018年12月30,虽不是2018年的最后一天,但是却是自己在2018年写的最后一篇博客了,昨天下班在地铁上闲来无事,翻起了关注的一些公众号发的技术博文,里面就提到写博客的重要性,其实这样的内容看了N多了,但是,里面有一句感觉说的很对,现在的博客变了味了,因为我们可以Ctrl+c、Ctrl+v,短短几秒钟就是一遍几千字的博文,真正自己写出的博文需要花费很长的时间。说心里话,自己的博客中也有,大概有三分之一吧,突然莫名的恐慌,因为很可能就是这三分之一的博客,就会掩盖自己花费精力完成的其他的博客,被别人冠上这么一个标签,这人也是一个充数的、装大半蒜的家伙。其实内心已经一万个草泥马了,因为我们都是人,说话说的好,一个人一直做好事,但是突然有一天做了一件坏事,大家就定义这个人是坏人,好人难做啊,同样的,写博客亦如此。

      不感慨了,看到的小伙伴们支持一下,当然欢迎转载,欢迎Ctrl+c,但是有一个请求,在文章的最上方请注明文章来源,非常感谢。

      接下来,说今天的正事,本篇博客的正事,Vue的进阶篇,进阶,谈不上,也算是一点稍微不那么基础的基础吧,更基础的欢迎浏览本人的另一篇博客Vue基础篇

     

    老习惯,开始正文之前,先来了解一些必知必会的小知识点

    前言

      1,组件和插件的区别(组件是一个项目的必须组成部分,而插件是不必须的,动态的,即插即用)

      2,在一个项目中,一个文件以.开头表示电脑系统的隐藏文件。

      3,在前端中,一个项目中的index文件或main文件,默认为一个项目的入口

      备注:在vue-cli项目中会有一个包含很多包的文件,这个文件的文件名就是node_modules,还有一个.gitignore的文件,这个隐藏文件的意思就是git忽视的一个文件,打开这个文件,里面的有这些内容:

    .DS_Store
    node_modules
    /dist

      在这个文件中,我们可以配置当前项目一些忽略的文件,支持部分正则匹配。比如,node_modules项,如果项目上传git,或者GitHub时,会自动忽略掉这个文件,所以我们上传到GitHub上的项目中是不包含这个node_modules文件的,这也是GitHub的一个局限性,大的文件无法上传,导致我们从GitHub上下载的一些开源的项目,并不能直接使用,对于vue的项目,还需要使用一个命令:npm install  将包含很多包的这个文件下载下来。

      因此,我们从GitHub上下载下来的vue的开源代码,第一步就是运行一个命令:npm install (一般在当前目录下)   

      GitHub中,每个开源文件都有一个文件READMI.md(markdown文件),这个文件中,会告诉我们怎么使用这个项目。

      赠送的小技巧:另外的我们在一个项目名中,看到带有awesome的,表示一个生态系统,里面在这个基础上封装了很多插件和模块。

    vue-cli开始

      在vue中,一个.vue文件就是一个vue的组件。

    一个标准的可重用的vue组件的格式:

    <!--一个组件包含html、css、js-->
    
    <template>
      <!--组件的结构-->
    
    </template>
    
    <script>
        // 处理业务逻辑
      export default {
    name: "Vheader",

      } </script> <style> /*页面的样式*/ </style>

      备注

      1,在template模板中,必须有一个包裹的标签。   需要注意的是:template不是一个标签,是vue中的一个模板

      2,在vue中,一个组件的命名规范是:首字母必须大写,比如:所有的组件以“V”开头。一个组件中的data(数据属性)必须是函数,这个函数必须return一个对象。

      3,在一个项目中的MP3文件,由于webpack的打包编译,是无法直接引入到src中,所以导入MP3文件时,必须当做模块来引入

    import song1 from './assets/薛之谦 - 一半 [mqms2].mp3'

    <audio src="song1" autoplay controls></audio>

      总之,所有的静态资源都可以作为模块导入 。

    组件的引入

      组件的引入很简单 ,分三步:

      1,导入组件       import  Vheader  from  './components/Vheader.vue'

      2,挂载组件       在export  default 中  定义一个key为components,值为一个对象,这个对象中放着导入键值对;键为变量名,值为组件名,在es6中,键值相同时,可以缩写为一个单一的值。

      比如:components:{ Vheader }

      3,在template模板中使用组件:     <Vheader> </Vheader>

    备注:在父组件中定义的样式类,默认为全局的样式类,所以如果要保证自身元素的样式,在子组件的style标签中加入:scoped即可     <style  scoped><style>

    父子传值

    父子组件的传值:

    父组件向子组件传值

      1,绑定自定义的属性   :  在父组件中对应的子组件的模板上绑定属性。

        比如:<Vcontent  :menu=“menus”><Vcontent>     #menu为定义的属性名   menus为数据属性

      2,在子组件中接收这个自定义的属性,并且属性必须要验证   ,接收的属性放在props中

        比如:props:{ menu:Array }         备注:接收的变量名必须与自定义的变量名保持一致

      3,这时子组件中的数据值就是这个对应的menu变量,我们也可以在数据属性中重新赋值

        比如:data(){ return {  menus:this.menu  }  }    #这时我们在子组件用的值就是menus了

      备注:这里的this是指当前的子组件的Vue对象,Vue创建组件时:Vue.component()

    子组件向父组件传值

      1,在子组件中定义一个事件: 比如:在Vheader中定义一个点击事件。     

    <template>
    
        <div class="header">
    
            //  定义一个点击事件   addOne   
            <button @click="addOne">添加一个菜单</button>
        </div>
    </template>
    
    <script>
        export default {
            name: "Vheader",
            data(){
                return {
                   
                }
            },
            methods:{
                 //  事件触发自定义的事件
                addOne(){
                      this.$emit('addMenu','酸菜鱼');  #this.$emit(“自定义事件名”,“往父组件传的值”)
                }
        }
        }
    </script>
    
    <style scoped>
    
    </style>

      2,触发自定义的事件,this.$emit("自定义的事件名","要向父组件传的值")    #备注:固定写法,而且自定义的事件名必须与父组件中自定义的事件名一致

      3,在父组件中对应的子组件模板中,定义好这个自定义事件,比如:<Vheader @addMenu="addHand"></Vheader>

        并在对应的事件中,接收传的值,并做相应处理。

       methods:{
              addHand(value){
                  this.menus.push(value);   #接收传的值,并将值添加到父组件的menus数组中
              }
        }    

    vue的优势和用途

      

    vue主做单页面应用

      比如:饿了么、掘金、网易云音乐、豆瓣、知乎等等

    在vue中,可以给每一个单页面(组件)配置一个路由,这个是由vue-router来控制的 

    vue-router

    首先,要在我们的项目中下载安装这个vue-router   

    npm install vue-router

    如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:

    在项目的入口  main.js中

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter)

    接着就可以在这个main.js中配置组件

    1. 定义 (路由) 组件。

    // 比如:
    const Foo = { template: '<div>foo</div>' }
    const Bar = { template: '<div>bar</div>' }

    // 也可以从其他文件 import 进来
    import Vhome from './components/Vhome.vue' import Vuser from './components/Vuser.vue'
    2. 定义路由每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,或者,只是一个组件配置对象。

    const routes = [
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar }
    ]
    3. 创建 router 实例,然后传 `routes` 配置
    // 你还可以传别的配置参数, 不过先这么简单着吧。
    const router = new VueRouter({
      routes // (缩写) 相当于 routes: routes
    }
    4. 创建和挂载根实例。
    // 记得要通过 router 配置参数注入路由,
    // 从而让整个应用都有路由功能
    const app = new Vue({
      router
    }).$mount('#app')
    现在,应用可以启动了!
    

      Tips: 通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由:

    console.log(this.$router)   #打印$router的结果:

        []
        app:Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
        apps:[Vue]
        beforeHooks:[]
        fallback:false
        history:HashHistory {router: VueRouter, base: "", current: {…}, pending: null, ready: true, …}
        matcher:{match: ƒ, addRoutes: ƒ}
        mode:"hash"
        options:{routes: Array(2)}
        resolveHooks:[]
        currentRoute:(...)
        __proto__:Object
    
    点击打开__proto__(父级中声明的方法,在子级中都可以使用):
    
            addRoutes:ƒ addRoutes(routes)
            afterEach:ƒ afterEach(fn)
            back:ƒ back()
            beforeEach:ƒ beforeEach(fn)
            beforeResolve:ƒ beforeResolve(fn)
            forward:ƒ forward()
            getMatchedComponents:ƒ getMatchedComponents(to)
            go:ƒ go(n)
            init:ƒ init(app /* Vue component instance */)
            match:ƒ match( raw, current, redirectedFrom )
            onError:ƒ onError(errorCb)
            onReady:ƒ onReady(cb, errorCb)
            push:ƒ push(location, onComplete, onAbort)
            replace:ƒ replace(location, onComplete, onAbort)
            resolve:ƒ resolve( to, current, append )
            constructor:ƒ VueRouter(options)
            currentRoute:(...)
            get currentRoute:ƒ ()
            __proto__:Object

    console.log(this.$route)     打印$route的结果:

    
    
    1. fullPath:"/marked"
    2. hash:""
    3. matched:[{…}]
    4. meta:{}
    5. name:"marked"
    6. params:
      1. __proto__:Object
    7. path:"/marked"
    8. query:{}
    9. __proto__:
      1. constructor:ƒ Object()
      2. hasOwnProperty:ƒ hasOwnProperty()
      3. isPrototypeOf:ƒ isPrototypeOf()
      4. propertyIsEnumerable:ƒ propertyIsEnumerable()
      5. toLocaleString:ƒ toLocaleString()
      6. toString:ƒ toString()
      7. valueOf:ƒ valueOf()
     

    备注:$router中,push方法常用,在$route中,path(获取当前访问的路径)和fullpath(获取当前访问的全路径)方法常用

     

    配置好了路由,接下来就该在HTML中使用了

    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>

    备注:路由出口 --> 路由匹配到的组件将渲染在这里 --> <router-view></router-view>  这是路由的出口

    使用 router-link 组件来导航. -->通过传入 `to` 属性指定链接. --><router-link> 默认会被渲染成一个 `<a>` 标签

    注意:router-link和router-view也可以放置在不同的子组件中

      <router-view></router-view>    可以简写成   <router-view/>

    动态路由匹配:

      一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 User 的模板,输出当前用户的 ID:

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

    你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:

    模式匹配路径$route.params
    /user/:username /user/evan { username: 'evan' }
    /user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: 123 }

    除了 $route.params 外,$route 对象还提供了其它有用的信息,例如,$route.query (如果 URL 中有查询参数)、$route.hash

    编程式的导航

    除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

    router.push(location, onComplete?, onAbort?)

    注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push

    想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

      当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)。所以通过这个方法我们可以实现重定向的效果,

    比如:登录后跳转到首页,可以把首页的路径push到$router中即可

    声明式编程式
    <router-link :to="..."> router.push(...)

    该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:

    // 字符串
    router.push('home')
    
    // 对象
    router.push({ path: 'home' })
    
    // 命名的路由
    router.push({ name: 'user', params: { userId: 123 }})
    
    // 带查询参数,变成 /register?plan=private
    router.push({ path: 'register', query: { plan: 'private' }})


      在使用动态路由或者编程式的路由时,会有这样一个问题,路由切换后,页面不切换,解决方法:
    使用watch监听路由的变化,并做数据的覆盖处理
    <template>
        //  两种方式触发切换
      <!--方式一:通过点击事件的切换-->
    <div v-for="(item,index) in theshow.recommend_courses" @click="toaimcourse(item)"><a href="javascript:vild(0);">{{item.title}}</a></div> <!--方式二:通过动态路由的切换--> <router-link v-for="(item,index) in theshow.recommend_courses" :to="{ name: 'coursedetail', params: { id:item.id }}">{{item.title}}</router-link> </template> <script> export default { name: "vcoursedetail", data(){ return { showdetail:this.$store.state.allCourseDetail, theshow:'', currcourse:'', courseall:this.$store.state.allCourse, descurl:'', charperurl:'' } }, created(){ this.courseshowdetail(this.$route.params.id); this.getcurrentcourse(this.$route.params.id); }, methods:{ courseshowdetail(nid){ for (var i=0;i<this.showdetail.length;i++){ if (this.showdetail[i].course.id === nid){ this.theshow = this.showdetail[i]; return this.showdetail[i] } } }, getcurrentcourse(nid){ for (var i=0;i<this.courseall.length;i++){ if (this.courseall[i].id === nid){ this.currcourse = this.courseall[i].title; this.descurl = "/course/coursedetail/"+nid; this.charperurl = '/course/coursedetail/'+nid+'/charper'; console.log(this.descurl,'文章摘要的url'); return this.courseall[i] } } }, toaimcourse(item){ this.$router.push({ name: 'coursedetail', params: { id:item.id }}) } }, computed:{ }, watch:{ "$route"(to,from){ this.courseshowdetail(to.params.id);   this.getcurrentcourse(to.params.id); } } } </script>

     我们也可以做一个全局的路由操作,比如:在每个组件加载或者路由切换时,判断有没有登录

    详情参考:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

    完整的导航解析流程

    1. 导航被触发。
    2. 在失活的组件里调用离开守卫。
    3. 调用全局的 beforeEach 守卫。
    4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
    5. 在路由配置里调用 beforeEnter
    6. 解析异步路由组件。
    7. 在被激活的组件里调用 beforeRouteEnter
    8. 调用全局的 beforeResolve 守卫 (2.5+)。
    9. 导航被确认。
    10. 调用全局的 afterEach 钩子。
    11. 触发 DOM 更新。
    12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

    拦截过滤认证

    单个组件:

      可以在mounted方法中做拦截,通过判断全局变量中的token值,来判断有无登录。

    多个组件:可以在全局做拦截

    # 在main.js中配置
    
    router.beforeEach(function (to,from,next) {
        //  meta 用于设置一个标识   所以必须在需要验证是否登录的组件中加一个meta参数  meta:{requireAuth:true}
        if (to.meta.requireAuth){
            //  表示此时路径是要判断是否登录的
            if (store.state.token){
                next()
            }else{
                // query  用于给这个重定向路由设置一个参数  用于在登录成功后重定向的路径
                //  设置此参数后需要在登录成功后做一个判断  this.$route.query.backUrl  获取设置的参数
                //  有值,表示是需要跳转回的,然后通过重定向将取的值,定位即可
                next({path:'/login',query:{backUrl:to.fullPath}})
            }
        }else{
            next()
        }
    });

      

    bootstrap的使用

    在项目中,使用bootstrap时,先在package.json中查看开发环境依赖:

      "dependencies": {
        "bootstrap": "^3.3.7",
        "marked": "^0.4.0",
        "vue": "^2.5.16",
        "vue-router": "^3.0.1"
      },

      如果没有,先在当前项目中    npm install xxx

      配置好依赖后,再在需要的地方导入:   导入时,对于node_modules文件下的文件,直接导入即可。比如:import 'bootstrap/dist/css/bootstrap.min.css'     在vue-cli中,已经配置了路径,所以直接导入即可。

      备注:使用vue-router时,路由的切换会在路径前默认加一个#/,显得url很不好看,所以,可以在实例router对象时加一个mode:"history"

    const router = new VueRouter({
      mode: 'history',
      routes: [...]
    })

    在使用a标签时,会有一个默认的跳转事件,在vue中,我们可以在相应的事件后加一个.native用来阻止原生的默认事件

      @click.native = "xxxx"

    参考Vue提供的生命周期图示

    下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

    Vue 实例生命周期

      在vue的实例的生命周期中,vue为我们提供了八个方法:

      beforeCreate(在创建之前)、created(创建时的初始化操作,创键的是虚拟DOM)、beforeMount、mounted(挂载,将虚拟DOM转化为真实DOM)、beforeUpdate、updated、beforeDestroy、destroyed(销毁)

      我们常用的是 created和mounted这两个方法,其中created方法适用于页面的初始化操作,mounted适用于发送ajax请求数据的操作。

    比如:切换路由,页面样式在在此刷新时会出错,可以使用created方法进行一些初始化操作

    created(){
                for (var i=0;i<this.routes.length;i++){
                    if (this.routes[i].src === this.$route.path){
                        this.current=i;
                        return;
                    }
    
                }
            },

    vue-cli中2x版本和3x版本修改端口的方法:

    在2x版本中:

     在3x版本中:

     在3x版本中,vue-cli不推荐我们直接在模块中修改配置

    推荐这样:在当前项目的目录下直接创建一个js文件   ,文件名必须是    vue.config.js  的形式

    在这个js文件中写入:

    module.exports = {
    devServer: { open: process.platform
    === 'darwin', host: '0.0.0.0', port: 8088 , https: false, hotOnly: false, proxy: null, // 设置代理 before: app => {} } }

     修改完成后重启项目即可。

    使用vue-cli打包文件

    生产环境中,我们都会讲项目中的文件打包压缩再上线,vue-cli中提供了一种快捷的打包方式。

    在我们项目的根目录下运行   npm  run  build     就会将项目打包,打包后会在项目中多处一个文件夹dist,打开这个dist文件夹

    备注:在项目中替换文件时,最好是先将原文件删除,在拖进去,不要直接替换,放置文件合并

    在打包时,一定要配置压缩文件中的路径参数。比如:前缀加/static/

    vue中的全家桶:vue、vue-router、vuex构成了vue的全家桶,vue是MVVM的架构,vuex--->M     vue--->V     vue-router--->VM

    vue全家桶之vuex

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

    补充:在vue中专门用来发送ajax请求的是axios,详细用法参考:https://www.kancloud.cn/yunye/axios/234845

    我们可以在全局的main.js或者store.js中定义一个axios    ,将这个axios挂到vue的实例对象中,这样,在vue的子对象中都可以通过this.$axios调用到axios对象。使用axios时,可以通过返回的参数response.data取得返回的数据

    import axios from 'axios'
    import Vue from 'vue'
    
    Vue.prototype.axios = axios

    特别注意:使用jQuery的$.ajax发送post请求发送数据时,内部会自动转化为json字符串的形式发送到后端,而使用vue中的axios时,则不行,axios   post提交数据时,发送的是普通的值,所有在使用axios发送数据时,如果后端需要json形式的字符串,则需要借助一个模块  qs (npm install qs) 转化或者,JSON.stringfity  

      还有一个值得注意的地方,在vue的中,我们可以通过this拿到vue的实例对象,但是在axios中由于作用域的原因则不行,console.log(this)得到的是一个undefined,所以我们要在axios的外面声明一个变量接收这个this   var  _this = this


    vue中的mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。

     使用vue-cli时,会在src文件夹下默认创建views、components的两个文件夹,views中存放每一个vue-router(路由)对应的视图,components中存放父子嵌套的组件。

    获取v-html指令对应的文本值

      使用v-html指令时,如果我们要获取渲染的文本内容,可以给当前标签绑定一个属性ref="变量名",然后在vue的实例中可以通过this.$refs.变量名取得这个标签,在通过DOM方法.innerText取得内容,this.$refs是一个对象

    <div id="show" v-html="currentmsg" ref="mark">
    
     // 这个div的文本内容为:
    var content = this.$refs.mark.innerText;

    备注:不要滥用ref,对性能有损耗,多个标签时,可以使用js方法或者jQuery方法获取文本值   $("show").text()

    Action 类似于 mutation,不同在于:

    • Action 提交的是 mutation,而不是直接变更状态。
    • Action 可以包含任意异步操作。

    备注:mutation是同步的,action是异步的,   action是用来提交的

    用法:

    mutation的用法:接收一个state参数作为第一个参数,有其他参数可以直接跟在后面,在mutation的方法中可以直接操作state中的数据,有多个参数时,最好可以将其余的参数作为一个对象,作为方法的第二个参数传值。

     在vue的视图中可以直接this.$store.commit("方法名"),唤醒这个方法的执行

    action的用法:接收一个context参数作为第一个参数,同样的,后可以跟其他参数,多个参数时,合并为一个object对象。通过context.commit("mutation方法名") 提交, 可以唤醒mutation中的方法

      在vue的视图中可以通过this.$store.dispatch('action方法名'),触发action中的对应方法执行

    mutation和action的关系图如下:

    过滤器(格式化)

    1.价格后面加上符号‘元’。

    2.价格后面的单位也要动态的传值。(如:元、¥、$)

    代码:

    复制代码
    <!DOCTYPE html>
    <html >
    <head>
        <meta charset="UTF-8">
        <title>过滤器</title>
        <script src="bli/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <input type="text" v-model="price">
        <!-- {{ price | currency }} -->
        {{ price | currency('美元') }}
    </div>
    </body>
    <script src="js/14.main.js"></script>
    </html>
    复制代码
    复制代码
    // 过滤器
    Vue.filter('currency',function(data,unit){
        data = data || 0;  // data有值就等于data,没值就为0.
        unit = unit || '元';  // unit有值就等于unit,没值就为'元'.
        return data + unit;
        // return data + '元';
    });
    
    new Vue({
        el:'#app',
        data:{
            price:10,
        },
    });
    复制代码

    3.毫米与米的转换。

    4.毫米与米的转换,保留两位小数。

    自定义指令-基础配置

    1.自定义指令

    2.给只为true的元素定位(固定定位)

    3.加一个按钮,切换是否定位。

    默认都是没有定住的。点击之后定住,再点击之后就是取消定住。

    默认、取消定住

    定住

    4.可以给很多按钮就加上。

    默认、取消定位

    定位

    自定义指令-配置传参及修饰符

    以上例子只能定位到左上角,不够灵活。位置应该动态传参。

    1.定位到右下角:

    打印 var position = binding.modifiers;

    console.log('position',position)  // position {bottom: true, right: true}

    运行结果:已定位到右下角

    2.定位到左下角,只要改一个值即可。

    3.让一些卡片样式有所不同,突出。

    获取该值(:true),设置样式。

     

    混合 mixins

    1.点击切换显示隐藏。

    默认不显示div.

    点击后显示div,再次点击有隐藏div.

    2.鼠标移入、移出切换显示隐藏。

    默认、移出

    移入:

    3.点击显示的div应该有个可以关闭的按钮。

    注意:这两个组件有好多重复的代码!

    点击后隐藏div

    混合 mixins(相同的代表放在一起)

    功能是一样的。注意:自己写的会覆盖mixins的。

    插槽 slots

    1.定义一个样式

    2.内容都是相同的。动态传参(插槽)

    3.如果头部、底部都要动态传参呢???定义name!!!

    4.指定默认值。

    在Vue的项目中使用了Vue-Router,当某个路由有子级路由时,如下写法:

    Default
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'home',
          component: Home,
          children:[
            {
              path:'/',
              name: 'console',
              component: Console,
            }
          ]
        }
      ]
    })
    如果写法是如上的写法,就会报出如下警告:
    [vue-router] Named Route 'home' has a default child route. When navigating to this named route (:to="{name: 'home'"), the default child route will not be rendered. Remove the name from this route and use the name of the default child route for named links instead.

    解决办法

    因为当某个路由有子级路由的时候,这时候父级路由需要一个默认的路由,所以父级路由不能定义name属性,SO解决办法是:即去除父级的name属性即可。

  • 相关阅读:
    iOS 简单获取当前地理坐标
    iOS 企业账号申请证书和打包ipa
    iOS 代码片段的添加!
    iOS 扩展类方法之category!
    iOS 数组和字典排序
    iOS 字符串NSString 的一些常用方法
    iOS 一些常见问题
    iOS 数据库sqlite完整增删改查操作
    iOS pch文件的创建
    iOS 通过网络请求获取图片的下载歌曲
  • 原文地址:https://www.cnblogs.com/zhaopanpan/p/9236538.html
Copyright © 2020-2023  润新知