呕心沥血整理的Vue面试知识点,你确定不看吗?

1,660 阅读10分钟

v-cloak

<!-- 使用 v-cloak 能够解决 插值表达式闪烁的问题 -->
<p v-cloak>======{{msg}}=======</p>
<!--不会覆盖原有的数据   需要借助于css覆盖原有的数据-->

v-text

<h4 v-text="msg">=========</h4>
<!--覆盖原有的数据-->
<!-- 默认 v-text 是没有闪烁问题的 -->
<!-- v-text会覆盖元素中原本的内容,但是 插值表达式
只会替换自己的这个占位符,不会把 整个元素的内容清空 -->

v-html

<div v-html="msg">1122121</div>
<!--覆盖原有的数据-->
//该指令可以将带有html标签的字符串,渲染到网页中

v-bind

<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>

<!-- v-bind: 是 Vue中,提供的用于绑定属性的指令 -->
<!-- v-bind 中,可以写合法的JS表达式 -->
<input type="button" value="按钮" :title="msg +'13'">

v-on

<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

<!--不能这样写,它会认为alert是一个变量-->
<input type="button" value="按钮"  v-on:click="alert('hello')">

v-for

v-for 迭代数字
<p v-for="count in 10">这是第 {{ count }} 次循环</p>

v-for 循环遍历对象
<p v-for="(val,key,i) in user">属性为:{{key}}-值为:{{val}} - 索引:{{i}}</p>

v-for 遍历对象数组
<!--user:相当于item,每一项-->
<p v-for="(user,i) in list"> 索引:{{i}}-id为:{{user.id}}-name为:{{user.name}}</p>

v-for 遍历普通数组
<!--item:是每一项的元素-->
<!--i:是索引-->
<p v-for="(item,i) in list">索引:{{i}}-每一项:{{item}}</p>

v-for 中使用key属性
<!-- 注意: v-for再循环的时候,key属性只能使用 number类型或者String类型 -->
<!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 -->
<p v-for="(item,i) in list" v-bind:key="item.id">
<input type="checkbox">{{item.id}} --- {{item.name}}
</p>

v-model

<!-- v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V, 无法实现数据的双向绑定-->
<input type="text" v-bind:value="msg" style="width:100%;">
<!-- 使用  v-model 指令,可以实现 表单元素和 Model 中数据的双向数据绑定 -->
<!-- 注意: v-model 只能运用在 表单元素中 -->
<!-- input(radio, text, address, email....)select checkbox textarea   -->

<h4>{{ msg }}</h4>
<input type="text" v-model="msg" style="width:100%;">
const vm=new Vue({
el:'#app',
data:{
    msg: '大家都是好学生,爱敲代码,爱学习,爱思考,简直是完美,没瑕疵!'
},
methods:{}
});

v-if 和 v-show

<input type="button" value="toggle" @click="flag=!flag">
<!--v-if:特点,每次切换都会删除或创建元素-->
<!--v-show:特点,每次不会进行dom的删除和创建操作,只是切换样式display:none 的样式-->
<!-- v-if 有较高的切换性能消耗 -->
<!-- v-show 有较高的初始渲染消耗 -->


<!--如果元素涉及到频繁的切换,最好不要使用v-if,推荐使用v-show-->
<!--如果原素可能永远都不会显示出来被用户看到,则推荐使用v-if-->
<h3 v-if="flag">这是用v-if控制的元素</h3>
<h3 v-show="flag">这是用v-show控制的元素</h3>

new Vue({
      el: '#app',
      data: {
        flag: false
      },
      methods: {
        /* toggle() {
          this.flag = !this.flag
        } */
      }
    });

v-if v-else v-else-if

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

v-slot

缩写: #
2.6+ 新指令,插槽

<div id="app">
       <zizujian>

           <template v-slot:head>
               <h1 >这个是name为head的插槽</h1>
           </template>
           <template v-slot:default>
               <h2>这个是默认名字的插槽,默认的插槽可以不写v-slot:default</h2>
           </template>
           <template v-slot:scope = 'scope'>
               {{scope.msg.msg1}}
           </template>
       </zizujian>
    </div>
    <template id="zi">
        <div>
            <header>
                <slot name="head"></slot>
            </header>
            <nav>
                <slot></slot>
            </nav>
            <slot name="scope" v-bind:msg = 'msg'>
                {{msg.msg1}}
            </slot>
        </div>


    </template>


<script>

    // 子组件
    var zizujian = {
        template:'#zi',
        data () {
            return {
                msg: {
                    msg1:'作用域插槽,父组件访问子组件内部的数据'
                },
            }
        }
    };

    // 创建vm实例
    var vm = new Vue({
        el: '#app',
        data: {

        },
        components:{
            zizujian
        }
    });

</script>

v-pre

跳过这个元素和它的子元素的编译过程。
可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

<span v-pre>{{ this will not be compiled }}</span>

v-once

只渲染元素和组件一次。随后的重新渲染,
元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 有子元素 -->
<div v-once>
  <h1>comment</h1>
  <p>{{msg}}</p>
</div>
<!-- 组件 -->
<my-component v-once :comment="msg"></my-component>
<!-- `v-for` 指令-->
<ul>
  <li v-for="i in list" v-once>{{i}}</li>
</ul>

ref

//  ref  是 英文单词 【reference】   值类型 和 引用类型  referenceError
<div id="app">
  <input type="button" v-bind:value="msg" v-on:click="getelement" />
  <h2 ref="h2">这是一个h2标签</h2>
  <zi ref="zi"></zi>
</div>


<template id="zi">
 <div>
  <h1>这是子组件</h1>
 </div>

</template>


<script>


   //创建一个子组件
var zi={
  data(){
   return{
    msg:'这是子组件的msg',
   };
   },
  template:'#zi',
   methods:{
    show(){
    console.log('这是子组件的show方法');
    },
   },
   };
 //创建vm实例
 new Vue({
  el:'#app',
  data:{
   msg:'点击使用ref获取DOM元素',
  },
  methods:{
   getelement(){
    console.log(this.$refs.h2.innerHTML);
    console.log(this.$refs.zi.msg);
    this.$refs.zi.show();

   },
  },
  components:{
   zi,
  },
 });

</script>

vue 的异步组件

<!--
为什么要使用异步组件?
1.用不到的组件不会加载,因此网页打开速度会特别快,当你用到这个组件的时候才会
通过异步请求加载 2.缓存组件,通过异步加载的组件会被缓存下来,当下一次再用到这个组件的时候,丝毫不会
有任何迟疑,组件很快就会从缓存中加载出来-->
<!--通常有两种方式实现异步组件-->


//第一种方式创建异步组件 //在组件中,我们通过再components属性中使用import()函数返回一个promise()
components:{
 'hot-component':()=>import('./路径--文件.vue'),
 'nav-component':()=>import('./路径--文件.vue')
 },

//第二种方式创建异步组件 //在router中,我们也可以这样做,---但是也可以使用node.js中的require函数来实现
//返回一个resolve
{
 path:'./login',
 name:'login',
 component:(resolve)=>{require(['./路径---文件.vue'],resolve)}
}
或者
{
 path:'./login',
 name:'login',
 component:()=>import('./路径--文件.vue')
 }
}

watch 方法

<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>

<!-- 容器 -->
 <router-view></router-view>
</div>

// 2. 创建子组件
 var login = {
template: '<h3>这是登录子组件,这个组件是 奔波霸 开发的。</h3>'
}

var register = {
 template: '<h3>这是注册子组件,这个组件是 霸波奔 开发的。</h3>'
 }

// 3. 创建一个路由对象
var router = new VueRouter({
routes: [ // 路由规则数组
{path: '/login', component:login},
{path:'/register',component:register}
],
linkActiveClass: 'myactive' // 和激活相关的类
 })


new Vue({
el:'#app',
data:{},
methods:{},
router:router,
watch:{ //可以监听一些非dom的------比如路由
 '$route.path':function(newval,oldval){
   console.log(this.$route);
   console.log(newval + ' --- ' + oldval)
   if(newval==='/login'){
                console.log('欢迎进入登录页面')
    }else if(newval==='/register'){
    console.log('欢迎进入注册页面')
      }

     },

    },

   });

动画 transition

<style>
.v-enter,
.v-leave-to{
 opacity: 0;
 transform: translateX(200px);
 }


.v-enter-active,
.v-leave-active{
 transition: all 0.5s ease;
 }

.my-enter,
.my-leave-to{
 opacity: 0;
 transform: translateX(200px);
 }


.my-enter-active,
.my-leave-active{
 transition: all 0.5s ease;
 }
</style>

<div id="app">
 <input type="button" v-bind:value="msg" v-on:click="flage=!flage" />
 <!--不需要v-for渲染的,都用transition包裹-->
 <transition>
  <h1 v-show="flage">这是transition包裹的,实现的动画@@@@</h1>
 </transition>

 <input type="button" v-bind:value="msg" v-on:click="flage1=!flage1" />
 <transition name="my">
         <h1 v-show="flage1">这是transition包裹的,实现的动画@@@@</h1>
 </transition>
</div>

//创建一个vm实例
new Vue({
 el:'#app',
 data:{
 flage:false,
 flage1:false,
 msg:'点击实现动画',
 },
 methods:{},
 });

列表动画

<style>
 li {
      border: 1px dashed #999;
      margin: 5px;
      line-height: 35px;
      padding-left: 5px;
      font-size: 12px;
      width: 100%;
    }

    li:hover {
      background-color: hotpink;
      transition: all 0.8s ease;
    }

    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateY(80px);
    }

    .v-enter-active,
    .v-leave-active {
      transition: all 0.6s ease;
    }


    /*下面的 .v-move 和.v-leave-active 是固定写法, 能够实现后续列表元素渐渐漂上来的效果*/
    .v-move{
     transition: all 0.6s ease;
    }
    .v-leave-active{
      position: absolute;
    }
</style>

<div id="app">
<div>
<label>Id:<input type="text" v-model="id"></label>
<label>Name:<input type="text" v-model="name"></label>
<input type="button" value="添加" @click="add">
</div>

<ul>
<!--在实现列表过度的时候,如果需要过度的元素,是通过v-for循环渲染出来的,
不能使用transistion包裹-----应该使用transition-Group包裹-->
<!-- 如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性 -->
<!--transition-Group 中添加 appear属性 实现页面入场效果-->
<!-- 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,
如果不指定 tag 属性,默认,渲染为 span 标签 -->


<transition-Group appear tag="ul">
<li v-for="(item,i) in list" v-bind:key="item.id" v-on:click="del(i)">
{{item.id}}---------------{{item.name}}
</li>
</transition-Group>
</ul>
</div>

使用第三方的动画

<!-- 使用 :duration="毫秒值" 来统一设置 入场 和 离场 时候的动画时长 -->
<transition enter-active-class=" bounceIn" leave-active-class=" bounceOut" v-bind:duration="800">
<h3 v-if="flag" class="animated">这是一个H3</h3>
</transition>



<!-- 使用  :duration="{ enter: 200, leave: 400 }"  来分别设置 入场的时长 和 离场的时长  -->
<transition enter-active-class=" bounceIn"
leave-active-class=" bounceOut"
v-bind:duration="{ enter:200 , leave:800}">
<h3 v-if="flag" class="animated">这是一个H3</h3>
</transition>

动画的钩子函数

当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

methods: {
  // --------
  // 进入中
  // --------

  beforeEnter: function (el) {
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  enter: function (el, done) {
    // ...
    done()
  },
  afterEnter: function (el) {
    // ...
  },
  enterCancelled: function (el) {
    // ...
  },

  // --------
  // 离开时
  // --------

  beforeLeave: function (el) {
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  leave: function (el, done) {
    // ...
    done()
  },
  afterLeave: function (el) {
    // ...
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled: function (el) {
    // ...
  }
}

父组件数据的同步



  <div id="app">
   <h1>使用原生js的对象引用来同步数据</h1>
   <h1>父级组件=======>{{msg.a}}</h1>
   <myzi v-bind:myzi='msg'></myzi>
  </div>
  <template id="zi">
   <div>
    <h2>子级组件========>{{this.myzi.a}}</h2>
    <input type="button" value="同步改变" @click="cg" />
   </div>
  </template>


  <script>

   //子组件
   var myzi={
    template:'#zi',
    props:['myzi'],
    methods:{
     cg(){
      this.myzi.a='数据改变了!!!'
     },
    },

   }
   new Vue({
    el:'#app',
    data:{
     msg:{
      a:'我是父级组件的数据'
     },
    },
    methods:{},
    components:{
     myzi
    },
   })
  </script>

过滤器的使用

<div id="app">
   <p> {{ msg | msgFormat('第一','参数') | text}} </p>
  </div>

  <script>

//   定义过滤器     全局
//   过滤器可以传递多个参数==============================也可以调用多个
   Vue.filter('msgFormat',function(msg,arg ,arg2){
//    字符串 replace 中的第一个参数,可以写字符串也可以写正则
    return msg.replace(/单纯/g,arg+arg2);
   });

   Vue.filter('text',function(date){
    return date+'+++++++++++';
   });
   var vm = new Vue({

    el:'#app',
    data:{
     msg: '曾经,我也是一个单纯的少年,单纯的我,傻傻的问,谁是世界上最单纯的男人'
    },
    methods:{},
   });

按键修饰符

Vue.config.keyCodes.F2=113;
 <input type="text" class="form-control" v-model="name" v-on:keyup.F2="add()">

自定义指令

//使用 Vue.directive(); 自定义全局指令
//第一个参数是:指令的名称,在定义的时候,名称不加 v-前缀,,在调用的时候必须加 v-前缀
//第二个参数:是一个对象,这个对象上有相关的函数,这些相关的函数可以在特定的阶段,执行相关的操作

Vue.directive('focus',{
bind:function(el){
// 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
//注意; 在每个函数中,第一个参数永远都是el,el表示被绑定了那个指令的元素,这个 el 参数,是一个原生的JS对象
// 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
//  因为,一个元素,只有插入DOM之后,才能获取焦点
//el.focus();
},
inserted:function(el){// inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
el.focus(); // 和JS行为有关的操作,最好在 inserted 中去执行,放置 JS行为不生效
},
updated:function(el){// 当VNode更新的时候,会执行 updated, 可能会触发多次
},
});

计算属性

new Vue({
 el:'#app',
 data:{
 firstname: '',
    lastname: '',
 middlename: ''
 },
 methods:{},
 computed:{// 在 computed 中,可以定义一些 属性,这些属性,叫做 【计算属性】,
 //计算属性的,本质,就是 一个方法,只不过,我们在使用 这些计算属性的时候,
 //是把 它们的 名称,直接当作 属性来使用的;并不会把 计算属性,当作方法去调用;
 // 注意1: 计算属性,在引用的时候,一定不要加 () 去调用,直接把它 当作 普通 属性去使用就好了;
    // 注意2: 只要 计算属性,这个 function 内部,所用到的 任何 data 中的数据发送了变化,就会 立即重新计算 这个 计算属性的值
 // 注意1:计算属性,再引用是,不要再后面加(),只把它当作一个普通的属性来使用
    // 注意2: 只有 这个计算属性,function内部,所要用到的 任何数据发生改变, 都要从新计算
    // 注意3: 计算属性的求值结果,会被缓存起来,方便下次直接使用; 如果 计算属性方法中,所以来的任何数据,都没有发生过变化,则,不会重新对 计算属性求值;
 fullname:function(){
 console.log('ok')
    return this.firstname + '-' + this.middlename + '-' + this.lastname
 },
 get(){
  console.log(`${firstname}------${lastname}`)
  }
 },
 });

子组件向父组件传值

<div id="app">
   <!--父组件给子组件传递方法,是给子组件一个事件绑定机制  v-on-->
   <!--当我们自定义了 一个 事件属性之后,那么,子组件就能够,通过某些方式,来调用 传递进去的 这个 方法了-->
   <log v-on:func="show"></log>
  </div>


  <template id="log">
   <div>
    <h1>这个是子组件</h1>
    <input type="button" value="这是子组件中的按钮 - 点击它,触发 父组件传递过来的 func 方法" @click="myclick">
   </div>
  </template>




  <script>

   // 定义了一个字面量类型的 组件模板对象
   var log={
    data:function(){
     return {
      msg:{id:1,name:'kk'},
     };
    },
    template:'#log',// 通过指定了一个 Id, 表示 说,要去加载 这个指定Id的 template 元素中的内容,当作 组件的HTML结构
    methods:{
      myclick:function(){
       // 当点击子组件的按钮的时候,如何 拿到 父组件传递过来的 func 方法,并调用这个方法???
               //  emit 英文原意: 是触发,调用、发射的意思
               // this.$emit('func123', 123, 456)
//       this.$emit('func','传参');
       this.$emit('func',this.msg);
      },
    },

   };

new Vue({
 el:'#app',
 data:{
  data2:null,
 },
 methods:{
 show:function(data1){console.log('调用了父组件身上的 show 方法'+data1);
 this.data2=data1;
    console.log(this.data2)
 },
 },
 components:{
 log
 },
 });

父组件向子组件传值

  <div id="app">
   <!--父组件,可以在引用子组件的时候,通过属性绑定(v-bind:)的形式,把需要传递给子组件的数据,-->
   <!--以属性绑定的形式,传递到子组件内部,供子组件使用-->
   <com1 v-bind:parentmsg="msg"></com1>
  </div>




  <script>

   var vm=new Vue({
    el:'#app',
    data:{
     msg:'123123',
    },
    methods:{},
    components:{
     //结论:子组件中,默认无法访问到  父组件中的data 上的数据,和methods中的方法
     com1:{
       data:function(){
        // 注意: 子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,
        //比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上;
         // data 上的数据,都是可读可写的;
        return {
         title: '123',
                    content: 'qqq'
        };
       },
       template:'<h1>这是子组件----{{parentmsg}}</h1>',
       // props组件中的数据,都是父组件传递给子组件的
       props: ['parentmsg'],// 把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
     },


    },
   });
  </script>

平级组件的传值

<div id="app">
   <myaaa></myaaa>
   <mybbb></mybbb>
   <myccc></myccc>
  </div>

  <template id="aaa">
   <div>
    <input type="button" value="传递组件myaaa的数据" @click="setData" />
   </div>
  </template>
  <template id="bbb">
   <div>
    <input type="button" value="传递组件mybbb的数据" @click="setData" />
   </div>
  </template>
  <template id="ccc">
   <div>
    <h1>{{a}}</h1>
    <h1>{{b}}</h1>
   </div>
  </template>
  <script>

   /*
   传值原理:
   就如三个数字传值一样;
   c=a a=b a=c

   vm实例就是第三方变量

   vm.$emit()---作用:传递数据
   vm.$on()-----接受数据
   */







   //创建第三方vm实例----用于传递数据

   var vm=new Vue();



   //创建三个子组件

   //1.
   var myaaa={
    template:'#aaa',
    data(){
     return {
      msg:'我是组件myaaa中的数据'
     }
    },
    methods:{
     setData(){
      vm.$emit('amsg',this.msg);
     },
    },

   }
   //2.
   var mybbb={
    template:'#bbb',
    data(){
     return {
      msg:'我是组件mybbb中的数据'
     }
    },
    methods:{
     setData(){
      vm.$emit('bmsg',this.msg);
     },
    },

   }

   //2.
   var myccc={
    template:'#ccc',
    data(){
     return {
      a:'暂无数据',
      b:'暂无数据'
     }
    },
    mounted(){
     vm.$on('amsg',(data)=>{
      this.a=data
     })
     vm.$on('bmsg',(data)=>{
      this.b=data
     })
    }

   }
   //创建vm实例
   new Vue({
    el:'#app',
    data:{},
    components:{
     myaaa,
     mybbb,
     myccc

    },
   })

生命周期函数

new Vue({

    el:'#app',
    data:{
     msg:'ok',
    },
    methods:{
     show:function(){
      console.log('执行了show方法');
     },
    },

    beforeCreate:function(){
     //第一个生命周期函数,表示实例被创建出来之前会执行它
     //console.log(this.msg);
     //this.show();
     //报错------注意:在 beforeCreate函数执行时, msg,show,数据都还没有被初始化
    },

    created:function(){
     //第二个生命周期函数, 表示实例已经被初始化好了
     //console.log(this.msg);
     //this.show();
     //表示 data 和 methods 已经初始化完毕了
     //如果想要调用 methods中的方法 或者 想要操作 data中的数据,最早也得到 created 中操作
    },

    beforeMount:function(){
     //第三个生命周期函数 ,表示模板已经在内存中渲染完毕,但是尚未把 模板渲染到 页面中
     //console.log(document.getElementById('h3').innerText)
     //在 beforeMount执行的时候,内存中的元素还没有渲染到页面中,只是之前写的一些模板字符串
    },

    mounted:function(){
     //第四个生命周期函数,表示,内存中的模板已经挂载到页面上,用户已经可以看到渲染好的页面
     //console.log(document.getElementById('h3').innerText)
     //注意:mounted,已经是函数创建期间最后一个生命周期函数,当执行完mounted就表示,
     //实例已经完全被创建好了
    },

    // 接下来的是运行中的两个事件

    beforeUpdate:function(){
     //第五个生命周期函数 ,表示 界面还没有被更新,但是数据已经被更新完了
     //console.log('界面上元素的内容:' + document.getElementById('h3').innerText)
           //console.log('data 中的 msg 数据是:' + this.msg)

           //注意:当执行到beforeUpdate中的时候,页面上的数据还是旧数据,没有被更新,
           //但是内存中的数据已经被更新了  页面尚未和 最新的数据保持同步
    },

    updated:function(){
     //第六个生命周期函数 ------------ 页面已经和 最新的数据保持同步
     console.log('界面上元素的内容:' + document.getElementById('h3').innerText)
           console.log('data 中的 msg 数据是:' + this.msg)
           // updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
    },

    //还有两个实例销毁阶段的函数
   });

vue-router 路由使用

  <div id="app">
   <router-link to='/login'>login</router-link>
   <router-link to='/denglu/22/zhang'>denglu</router-link>
   <router-view></router-view>
  </div>
  <template id="login">
    <div>
    <h1>这是login组件</h1>
    </div>
  </template>

  <template id="deng">
   <div>
    <h1>这是登陆的组件,传递的参数为:id:{{this.$route.params.id}}===name:{{this.$route.params.name}}</h1>
   </div>
  </template>
  <script>
   //创建组件
   var login={
    data(){
     return{

     };
    },
    template:'#login',
   };

   var denglu={
    data(){
     return{

     };
    },
    template:'#deng',
    created(){
     console.log(this.$route.params.id);
    },


   };


   //创建路由
   var router=new VueRouter({
    routes:[

     {path:'/',redirect:'/login'},
     {path:'/login',component:login},
     {path:'/denglu/:id/:name',component:denglu}


    ],
   });
   //创建vm实例
   var vm =new Vue({
    el:'#app',
    data:{

     msg:'sdfasd'
    },
    methods:{

    },
    components:{
     login,
     denglu
    },
    router,
   });

路由传参 解耦

<div id="app">
   <!--如果再路由中,使用查询字符串,给路由传递参数,则不需要更改路由规则中的path属性-->
   <router-link to="/login/12/zhangsan">登陆</router-link>
   <router-link to="/zhuce">注册</router-link>
   <router-view></router-view>
  </div>
  <script>
   //创建模板对象
   var login={
    props: ['id','name'],
    template:'<h1>登陆组件-----{{ this.id }}-------{{$route.params.name}}</h1>',
    created:function(){
     // console.log(this.$route)
           //console.log(this.$route.query.id);
           console.log(this.$route.params.id);
    },
   };
   var zhuce={
    template:'<h1>注册组件</h1>'
   };


   var router=new VueRouter({

    routes:[
    {path:'/login/:id/:name',component:login, props: true},
    {path:'/zhuce',component:zhuce}
    ],

   });
   var vm=new Vue({
    el:'#app',
    data:{},
    methods:{},
    router:router,
   });
  </script>

路由传参 2

<div id="app">
   <!--如果再路由中,使用查询字符串,给路由传递参数,则不需要更改路由规则中的path属性-->
   <router-link to="/login?id=10&name=zs">登陆</router-link>
   <router-link to="/zhuce">注册</router-link>
   <router-view></router-view>

  </div>
  <script>
   //创建模板对象
   var login={
    template:'<h1>登陆组件-----{{ $route.query.id }}-----{{$route.query.name}}</h1>',
    created:function(){
     // console.log(this.$route)
           console.log(this.$route.query.id);
    },
   };
   var zhuce={
    template:'<h1>注册组件</h1>'
   };
   var router=new VueRouter({

    routes:[
    {path:'/login',component:login},
    {path:'/zhuce',component:zhuce}
    ],

   });
   var vm=new Vue({
    el:'#app',
    data:{},
    methods:{},
    router:router,
   });
  </script>

路由的基本使用

<style>
.router-link-active,
.myActive {
color: red;
font-weight: 800;
font-style: italic;
font-size: 80px;
text-decoration: underline;
background-color: green;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(140px);
}

.v-enter-active,
.v-leave-active {
transition: all 0.5s ease;
}
</style>
 </head>
 <body>

  <div id="app">
   <!-- 这是 vue-router 提供的元素,专门用来 当作占位符的,将来,路由规则,匹配到的组件,就会展示到这个 router-view 中去 -->
    <!-- 所以: 我们可以把 router-view 认为是一个占位符 -->
    <!--<a href="#/login">登陆</a>-->
    <!--<a href="#/zhuce">注册</a>-->

      <!-- router-link 默认渲染为一个a 标签 -->
      <router-link to="/login">登陆</router-link>
      <router-link to="/zhuce">注册</router-link>
   <transition mode="out-in">
        <router-view></router-view>
      </transition>


  </div>




  <script>
   //创建模板对象
   var login={
    template:'<h1>登陆组件</h1>'
   };
   var zhuce={
    template:'<h1>注册组件</h1>'
   };

   // 2. 创建一个路由对象, 当 导入 vue-router 包之后,
   //在 window 全局对象中,就有了一个 路由的构造函数,叫做 VueRouter

   var routerObj=new VueRouter({
    routes:[
    // 路由匹配规则
          // 每个路由规则,都是一个对象,这个规则对象,身上,有两个必须的属性:
          //  属性1 是 path, 表示监听 哪个路由链接地址;
          //  属性2 是 component, 表示,如果 路由是前面匹配到的 path ,则展示 component 属性对应的那个组件
          // 注意: component 的属性值,必须是一个 组件的模板对象, 不能是 组件的引用名称;
    //{path:'/',component:login}------默认跳转到login组件
    {path:'/',redirect:'/login'},//重定向
    {path:'/login',component:login},
    {path:'/zhuce',component:zhuce}

    ],
    linkActiveClass:'myActive',
   });
   var vm=new Vue({
    el:'#app',
    data:{},
    methods:{},
    router:routerObj,// 将路由规则对象,注册到 vm 实例上,用来监听 URL 地址的变化,然后展示对应的组件
   });
  </script>

路由的嵌套

  <div id="app">
   <router-link to="/account">Account</router-link>

      <router-view></router-view>
  </div>



  <template id="teml">
   <div>
    <h1>这是 Account 组件</h1>
    <router-link to="/account/login">登录</router-link>
    <router-link to="/account/zhuce">注册</router-link>

    <router-view></router-view>
   </div>
  </template>


  <script>

   var login={
    template:'<h3>登录组件</h3>'
   };
   var zhuce={
    template:'<h3>注册组件</h3>'
   };
   var account={
    template:'#teml',
   };

   var router=new VueRouter({
    routes:[
    // 使用 children 属性,实现子路由,同时,子路由的 path 前面,不要带 / ,
    //否则永远以根路径开始请求,这样不方便我们用户去理解URL地址
    {path:'/account',
    component:account,
    children:[
    {path:'login',component:login},
    {path:'zhuce',component:zhuce}
    ]}

    ],
   });
   var vm=new Vue({
    el:'#app',
    data:{},
    methods:{},
    router:router,
   });
  </script>

命名视图--路由

  <div id="app">
   <router-view></router-view>
   <div class="container">
    <router-view name="left"></router-view>
    <router-view name="main"></router-view>
   </div>
  </div>
  <script>

   var header={
    template:'<h1 class="header">Header头部区域</h1>'
   };
   var leftBox={
    template:'<h1 class="left">Left侧边栏区域</h1>'
   };
   var mainBox={
    template:'<h1 class="main">mainBox主体区域</h1>'
   };
   //创建路由
   var router=new VueRouter({

    routes:[

    {path:'/',components:{
     'default':header,
     'left':leftBox,
     'main':mainBox
    }}
    ]
   });
   var vm=new Vue({
    el:'#app',
    data:{},
    methods:{},
    router:router,
   });
   </script>

按需引入 Vuex

//main.js中的代码==========================================

  import Vue from 'vue'
  import Vuex from 'vuex'
  Vue.use(Vuex)

  var store=new Vuex.Store({
  state:{
   cun:0
  },
  mutations:{
   add(state){
    state.cun++;
   }
  },
  actions:{
   addd({commit}){
    commit("add");
   }
  },
  getters:{
   getcun(state){
    return "当前cun的值是"+state.cun;
   }
  }
 })
//App.vue===========================================
  <template>
    <div>
     <h1>{{getcun}}</h1>
     <input type="button" value="加加" @click="addd" />
    </div>
  </template>

  <script>
   import {mapGetters,mapActions} from ' '
   //按需引用vuex的数据
  export default {
    name: 'App',
    computed:mapGetters(['getcun']),
    methods:mapActions(['addd']),
     //mapGetters-->getters-----mapGetters一般都定义在computed中,按需引入
     //mapActions-->actions----mapActions,事件,一般定义到methods中,按需引入
  }
  </script>

调用使用 Vuex

main.js-----------------中的vuex的定义

  import Vuex from 'vuex'
  Vue.use(Vuex)
  var store=new Vuex.Store({
  state:{
   //state相当于---data,是专门存储数据的地方----这里的数据不可以直接修改,
   //只能借助mutations中的方法进行修改

   //如果想直接调用state中的数据-------this.$store.state.想要调用数据的名字
   cun:0
  },
  mutations:{
   // 注意: 如果要操作 store 中的 state 值,只能通过 调用 mutations 提供的方法,
    //才能操作对应的数据,不推荐直接操作 state 中的数据,因为 万一导致了数据的紊乱,
    //不能快速定位到错误的原因,因为,每个组件都可能有操作数据的方法;
   add(state){
    state.cun++;
   },
//如果想要调用mutations中的方法------this.$store.commit("被调用的方法名字")
     subtract(state, obj) {
         // 注意: mutations 的 函数参数列表中,
         //最多支持两个参数,其中,参数1: 是 state 状态;
         //参数2: 通过 commit 提交过来的参数;
         console.log(obj)
         state.cun -= (obj.c + obj.d)
       }
  },
  getters:{
   //这里的getters只负责对外提供数据,不会修改state中的数据,
   //如果想要修改 state 中的数据,请 去找 mutations
   getcun(state){
    return "当前cun的值是"+state.cun;
   }
   // 经过咱们回顾对比,发现 getters 中的方法, 和组件中的过滤器比较类似,
   //因为 过滤器和 getters 都没有修改原数据, 都是把原数据做了一层包装,
   //提供给了 调用者;
    // 其次, getters 也和 computed 比较像, 只要 state 中的数据发生变化了,
    //那么,如果 getters 正好也引用了这个数据,那么 就会立即触发 getters 的重新求值;

//  如果想调用getters中的数据-----this.$store.getters.被调用的方法名字

  }
 })
 // 总结:
// 1. state中的数据,不能直接修改,如果想要修改,必须通过 mutations
// 2. 如果组件想要直接 从 state 上获取数据: 需要 this.$store.state.***
// 3. 如果 组件,想要修改数据,必须使用 mutations 提供的方法,需要通过 this.$store.commit('方法的名称', 唯一的一个参数)
// 4. 如果 store 中 state 上的数据, 在对外提供的时候,需要做一层包装,那么 ,推荐使用 getters, 如果需要使用 getters ,则用 this.$store.getters.***


 /* eslint-disable no-new */
 new Vue({
   el: '#app',
   router,
   components: { App },
   template: '<App/>',
   store
 })

//App.vue中的调用==================================

 <template>
  <div>
   <h1>Vuex的--state--调用======this.$store.state.***===调用</h1>
   <h1>{{this.$store.state.cun}}</h1>
   <h1>Vuex的--mutations--调用======this.$store.commit("方法名")===调用</h1>
   <input type="button" value="加加" @click="add" />
    <h1>Vuex的--getters--调用======this.$store.getters.***===调用</h1>
    <h1>{{this.$store.getters.getcun}}</h1>
  </div>
</template>

<script>
export default {
  name: 'App',
  methods:{
   //想要使用mutations中的方法,必须在自己的methods中定义一个方法进行调用
   add(){
    this.$store.commit("add");
   }
  }
}