四、vue-cli

1.1、Vue-cli 介绍与安装

安装命令: vue/cli3的版本

##vue/cli3
npm install -g @vue/cli
##vue/cli2
npm install -g @vue/cli-init

新建项目命令:

##cli3 新建项目
vue create 项目名称
##cli2 新建项目
vue init webpack 项目名称

1.2、vue-cli2 新建项目的目录结构

目录名称 作用
build webpack 配置文件夹
config webpack配置文件夹
src 项目主体文件夹
static 静态资源文件夹
.babelrc 浏览器适配文件配置
.editorconfig 代码统一配置
.eslintignore eslint 检查代码规范
.eslintignore是规定哪些模块忽略规范
.eslintrc.js 代码检查配置文件
.gitignore 代码上传服务器时哪些可以忽略
index.html 模板文件
package.json 管理包文件配置
1.3、runtime-compiler和runtime-only的区别

两者的区别在main.js文件中

runtime-compiler 运行过程

template --解析-->ast 【抽象语法树】--编译成-->render函数--->虚拟Dom--->uiDom

runtime-only 运行过程 【性能高,代码量小】

render函数--->虚拟Dom--->uiDom

  1. 4、cl3创建项目以及目录结构

    创建项目命令:

    ##cli3 新建项目
    vue create 项目名称
    
    
1.5、箭头函数的使用

代码如下:


  <script> 
    //定义函数的方式:
    //1)
   const func = function ()
    {

    }
    //2)第二种方式
     const func1 = 
     {
        fu:function ()
        {

        }
     }
    //3)、箭头函数
   const  func2 = (参数列表)=>{
       // 函数体
       //如果函数体只有一行代码,不需要大括号 和 return 关键字

   } 
   //箭头函数this的使用
   //1) 结论:
        //  箭头函数中的this引用的就是最近作用域中的this
   //2)问题:箭头函数中的this是如何查找的呢
    // 答案:向外层作用域中,一层一层的查找this,直到有this的定义
    </script> 

总结: 箭头函数:也是一种定义函数的方式。

箭头函数this的使用 1) 结论: 箭头函数中的this引用的就是最近作用域中的this 2)问题:箭头函数中的this是如何查找的呢 答案:向外层作用域中,一层一层的查找this,直到有this的定义

  1. 6、什么是路由以及其中的映射关系

    路由的定义:路由就是通过互联的网络把信息从源地址传输到目的地址的活动。

1.7、url的hash与html5的history

整体页面不刷新,单组件刷新,【hash】代码如下:【推荐】

location.hash ='路由地址'

整体页面不刷新,单组件刷新,【html5的history】代码如下:

history.pushState ({},'','路由地址')

1.8、vue-router安装与配置

安装路由命令:

npm  install vue-router --save 

步骤:

1)、导入路由对象,并且调用Vue .use(VueRouter)

import Router from 'vue-router'
//安装路由插件
Vue.use(Router)

2)、创建路由实例,并且传入路由映射配置

// 创建路由对象  
export default new Router({
  //配置路由与组件之间的映射关系
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})

3)、在Vue实例中挂载创建的路由实例,在项目中main.js 进行路由挂载

new Vue({
  el: '#app',
  router, //路由挂载
  render: h => h(App)
})

使用vue-router的步骤

1)、创建路由组件 【新建了两个组件】

Index组件

<template>
<div>
  {{mess}}
</div>
</template>
<script>
export default {
  name:'Index',
  data(){
    return {
      mess:"这是Index页面"
    }
  }
}
</script>
<style></style>

About组件

 <template>
    <div>  {{mess}}</div>
 </template> 
 <script>
   export default { 
     name:'About',
     data (){
       return{
         mess:'这是About页面'
       }
     }
   }
 </script> 
 <style> 
 </style>

2)、配置路由映射:组件和路径的关系映射,在router文件夹下的index.js文件中添加路由映射配置

//导入组件
import About from '../components/About'
import Index from '../components/Index'
//路由配置
export default new Router({
  //配置路由与组件之间的映射关系
  routes: [
    {
      //页面路径
      path: '/About', 
      //导入的变量名
      component: About
    },
    {
      //页面路径
      path: '/Index', 
      //导入的变量名
      component: Index
    }

  ]
})

3)、使用路由 :通过<router-link>和<router-view>

在App.vue 添加组件标签组件

<template>
  <div id="app"> 
     <!--页面跳转链接-->
     <router-link to ="/Index">首页</router-link>
     <router-link to="/About">关于</router-link>
     <!--页面渲染标签-->
   <router-view></router-view> 
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

<router-link> 标签 :跳转组件

<router-view>:跳转组件后页面要渲染的位置 【占位】

1.9、路由的默认值和修改为history模式

访问网站默认显示页面,代码如下:

import About from '../components/About'
import Index from '../components/Index'

// 创建路由对象  
export default new Router({
  //配置路由与组件之间的映射关系
  routes: [
     //打开浏览器后,默认显示的页面
    {
      path:'',
      //重定向 
      redirect:'/Index'
    },
    {
      //页面路径
      path: '/About', 
      //导入的变量名
      component: About
    },
    {
      //页面路径
      path: '/Index', 
      //导入的变量名
      component: Index
    }

  ],
    //将访问模式更改为 history   默认为:hash模式
      mode:'history'
})

2.0、router-link其他属性的使用

代码如下:

tag:可以指定router-link之后渲染成什么组件, tag =“button” 那么渲染后就是按钮。

replace :replace不会留下history记录,也就是浏览器顶部的箭头不能返回,它是没有属性值的,直接加上就行。

active-class:当router-link对应的路由匹配成功的时候,会自动给当前的元素设置一个router-link-active 的class,设置active-class可以修改默认的名称。

在进行高亮显示的导航菜单或底部的tabar时,会用到该类

但是通常不会修改类的属性,回直接使用默认的router-link-active即可。

2.1、通过代码跳转页面

代码如下:

<template>
  <div id="app">
    <!--<router-link to="/index" tag="button">首页</router-link>
    <router-link to="/about" tag="button">关于</router-link>-->
    <button @click="indexClick">首页</button>
    <button @click="aboutClick">关于</button>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
  methods:{
    indexClick()
    {
      console.log("index");
      //第一种反方式
      this.$router.push("/index");
      //第二种方式
     this.$router.replace('/index');
    },
    aboutClick()
    {
      console.log('about');
      //第一种方式
      this.$router.push('/about');
      //第二种方式
      this.$router.replace('/about');
    }
  }
}
</script>

总结:

vue内部提供了两种跳转方式,第一种与第二种的区别就是:

点击第一种他会在内存的栈空间中将点击的地址存储,这样可以点击浏览器顶部的左右箭头 【前进 后退】,而第二种不能这样使用。

2.2、Vue-Router 动态路由

动态路由的定义:在某些情况下,一个页面的路径可能是不确定,比如我们进入用户登录页面时,希望它的路径是:/user/aaaa?id=12,这种路径和组件的匹配关系,我们称之为动态路由(也是路由传递参数的一种方式)

代码如下:App.vue

<template>
  <div id="app">
    <router-link to="/index">首页</router-link>
    <router-link to="/about">关于</router-link>
  <router-link v-bind:to="'/user/'+userId">我的</router-link>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data(){
    return {
      userId: '张三'
    }
  },

}
</script>

user.vue

<template>
  <div>
    {{mess}}
    <div>
     我是:{{userId}}
    </div>
  </div>
</template>

<script>
export default {
  name: "User",
  data(){
    return {
      mess:'我是用户界面信息'
    }
  },
  computed:{
    userId()
    {
      return this.$route.params.userId;
    }
  }
}
</script>

<style scoped>

</style>

路由配置:

import Vue from 'vue'
import Router from 'vue-router'
import Index from '../components/Index'
import About from '../components/About'
import User from '../components/User'
Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '',
      title:'首页',
      redirect:'/index'
    },
    {
      path:'/index',
      title:'首页',
      component:Index
    },
    {
      path:'/about',
      title:'关于',
      component:About
    },
    {
      path:'/user/:userId',
      component:User
    }
  ],
  mode:'history'
})

总结:

绑定url传递到值: 使用绑定语法对属性绑定值。

获取url传递值:this.$route.params.userId

2.3、路由懒加载

懒加载:用到时就加载。

懒加载使用代买如下: Router文件夹下的index.js文件

import Vue from 'vue'
import Router from 'vue-router' 

Vue.use(Router)
const Index=()=>import ('../components/Index')
export default new Router({
  routes: [
     {
       path:'',
       redirect:'/index'
     },
     {
       path:'/index',
       component:Index
     }

  ],
  mode:'history'
})

执行 npm run build 命令后,dist/static/js 文件夹下生成好多js文件,其中关键的有几个js文件比较重要:

app.818f4239f2ab7a40c7a6.js 打包后的业务代码js文件

manifest.5a0dee674fd2e1195491.js 打包后底层代码文件

vendor.2374c374d8cc0cfea2da.js 打包后的第三方的代码文件

2.4、路由的嵌套

一个路径映射一个组件,访问这两个路径也会分别渲染两个组件。

创建步骤:

1)、创建对应的子组件,并且在路由映射中配置子路由。

2)、在组件的内部使用 <router-view>标签

代码如下:

①、 新建子组件,名称:IndexMessage.vue

<template>
  <div>
   <ul>
     <li>消息1</li>
     <li>消息2</li>
     <li>消息3</li>
     <li>消息4</li>
   </ul>
  </div>
</template>

<script>
  export default {
    name:"IndexMessage"
  }
</script>

<style>
</style>

②、新建子组件,名称:IndexNews.vue

<template>
  <div>
   <ul>
     <li>新闻1</li>
       <li>新闻2</li>
         <li>新闻3</li>
           <li>新闻4</li>
   </ul>
  </div>
</template>

<script>
  export default {
    name:"IndexNews",
    data()
     {
       return {

       }
     }
  }
</script>

<style>
</style>

③、配置路由子组件的映射,代码如下: 【Router/Index.js】

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

const Index=()=>import ('../components/Index');
const About =()=>import('../components/About');
const messge =()=>import('../components/IndexMessage');
const news = ()=>import ('../components/IndexNews')
export default new Router({
  routes: [
     {
       path:'',
       redirect:'/index'
     },
     {
       path:'/index',
       component:Index,
       children:[
         {
           path:'',
           redirect:'news'
         },
         {
          path:'news',
          component:news,
         },
         {
          path:'messge',
          component:messge,
         }
       ]
     },
     {
       path:'/about',
       component:About
     } 
  ],
  mode:'history'
})

④、在父组件中添加跳转链接 Index.vue,代码如下:

<template>
  <div> 
<router-link to="/index/news">新闻</router-link>
<router-link to="/index/messge">消息</router-link>
<router-view></router-view>
  </div>
</template>

<script>
  export default {
    name:"Index",
    data()
     {
       return {
         mess:'这是Index页面'
       }
     },
     computed:{
       User()
       {
         return this.$route.params.id;
       }
     }
  }
</script>

<style>
</style>

2.4、路由参数传递

传递参数的方式有两种:

1) params 类型

配置路由格式:/router/:id

传递方式:在path后面跟上对应的值

传递后形成路径:/router/123

2)、使用query 类型

配置路由格式:/router 普通的路由格式

传递方式:对象中使用query的key作为传递方式

传递后形成路径:/router?id=12

代码如下:

①. 新建 Profile.vue 文件

<template>
  <div> 
 {{mess}}
 <h2>{{profile.name}}</h2>
  <h2>{{profile.sex}}</h2>
   <h2>{{profile.age}}</h2>
  </div>
</template>

<script>
  export default {
    name:"Profile",
    data()
     {
       return {
         mess:'这是Profile页面'
       }
     },
     computed:{
       profile(){ 
         return this.$route.query;
       }
     }
  }
</script>

<style>
</style>

②、在Router/Index.js文件中添加 路由配置,代码如下:

import Vue from 'vue'
import Router from 'vue-router' 

Vue.use(Router)

const Index = () => import('../components/Index');
const About = () => import('../components/About');
const messge = () => import('../components/IndexMessage');
const news = () => import('../components/IndexNews')
const user = () => import('../components/User'); 
const profile = ()=> import('../components/Profile');
export default new Router({
  routes: [
    {
      path: '',
      redirect: '/index'
    },
    {
      path: '/index',
      component: Index,
      children: [
        {
          path: '',
          redirect: 'news'
        },
        {
          path: 'news',
          component: news,
        },
        {
          path: 'messge',
          component: messge,
        }
      ]
    },
    {
      path: '/about',
      component: About
    },
    {
      path: '/user/:id',
      component: user
    },
    {
      path:'/profile',
      component:profile
    }
  ],
  mode: 'history'
})

③、在App.vue 中添加跳转,代码如下:

<template>
  <div id="app">
    <router-link to="/Index">首页</router-link>
     <router-link to="/about">关于</router-link>
     <router-link :to='"/user/"+id'>我的</router-link>
       <router-link :to="{path:'/profile',
                         query:{
                              name,
                              sex,
                              age
       }}">档案</router-link>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data()
  {
    return { 
      id:123,
      name:'晓明',
      sex:'男',
      age:18
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

总结:

传递参数的方式 ::to="{path:'跳转路径',query:{参数列表对象}}"

获取参数的方式:this.$route.query 获取到的参数对象

如果页面中的 我的和档案 链接 换成按钮,传递参数的方式代码如下:

在App.vue页面中增加按钮,并监听按钮

<template>
  <div id="app">
    <router-link to="/Index">首页</router-link>
     <router-link to="/about">关于</router-link>
    <!-- <router-link :to='"/user/"+id'>我的</router-link>
       <router-link :to="{path:'/profile',
                         query:{
                              name,
                              sex,
                              age
       }}">档案</router-link>-->
        <button @click="UserClick">我的</button>
        <button @click="ProfileClick">档案</button>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data()
  {
    return { 
      id:123,
      name:'晓明',
      sex:'男',
      age:18
    }
  },
  methods:{
    UserClick()
    { 
      this.$router.push('/user/'+this.id)
    },
    ProfileClick(){
   this.$router.push({
     path:'/profile',
     query:{
       name:this.name,
       sex:this.sex,
       age:this.age
     }
   })
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

使用 this.$router.push () 方式传递参数。

2.5、全局导航守卫

导航守卫的目的:监听链接的跳转过程。 代码如下: 路由文件夹下的 index.js文件

import Vue from 'vue'
import Router from 'vue-router' 

Vue.use(Router)

const Index = () => import('../components/Index');
const About = () => import('../components/About');
const messge = () => import('../components/IndexMessage');
const news = () => import('../components/IndexNews')
const user = () => import('../components/User');
const profile = () => import('../components/Profile');
const  routes = [
  {
    path: '',
    redirect: '/index'
  },
  {
    path: '/index',
    component: Index,
    meta:{
      title:'首页'
    },
    children: [
      {
        path: '',
        redirect: 'news'
      },
      {
        path: 'news',
        component: news
      },
      {
        path: 'messge',
        component: messge 
      }
    ]
  },
  {
    path: '/about',
    component: About,
    meta:{
      title:'关于'
    }
  },
  {
    path: '/user/:id',
    component: user,
    meta:{
      title:'用户'
    }
  },
  {
    path:'/profile',
    component:profile,
    meta:{
      title:'档案'
    }
  }
];
export default new Router({
  routes,
  mode: 'history'
 });

要跳转的链接需要加 meta 对象。

在main.js文件夹中,监听要跳转的页面:

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false
//监听要跳转的页面,并将页面title更改为 meta中的title值
router.beforeEach((to,from,next)=>{

   document.title = to.matched[0].meta.title;
   next()
 })

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render: h => h(App)
}) 

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

2.6、vue-router-keep-alive 及其他问题

keep-alive是Vue内置的一个组件,可以使被包围的组件保留状态,或避免重新渲染。

两个属性:

include: 字符串或正则表达式,只有匹配的组件被缓存

exclude: 字符串或正则表达式,任何匹配的组件都不会被缓存。

router-view 也是一个组件,如果该组件直接被包在keep-alive里面,所有路径匹配到的视图组件都会被缓存下来。

代码如下:

<keep-alive>
  <router-view></router-view>
</keep-alive>

2.7、ES6 中 Promise的介绍与基本使用

1)、 Promise:它是异步编程的一种解决方案。

应用场景:一般情况下是有异步操作时,使用Promise对这个异步操作进行封装。

new ->在构造函数中保存了一些状态信息,并执行传入的函数;在执行传入的回调函数时,回传入两个参数,resolve和reject,它们本身就是函数,语法如下:

 new Promise((resolve,reject)=>{ 
     // 网络请求代码在此处写,如果请求响应正常在执行resolve()方法,如果出现异常则会执行reject方法
     setTimeout(() => {
        //请求成功  
        resolve('异步请求!')
        //请求出现异常
        reject("请求失败")
     }, 1000); 
    }).then((data)=>{
      console.log(data);
    }).catch((data)=>{
      console.log(data);
    });

总结:

resolve()和reject()是两个函数,函数里面是有参数的。

如果请求成功会使用resolve(data),而处理返回值则在then的箭头函数中进行处理。

如果请求失败会使用reject(data),而处理返回值则在catch的箭头函数中进行处理。

2)、Promise的三种状态和另外的处理方式

①、三种状态

pending:等待状态,比如进行网络请求,或者定时器没有到时间。

fulfill:满足状态,当我们主动回调resolve函数,就处于该状态,并且回调 .then()。

reject:拒绝状态,当我们主动回调reject函数,就处于该状态,并且回调 .catch()。

②、另外的处理形式

    new Promise((resolve, reject) => {
     // resolve('请求')
      reject('请求失败');
    }).then(data => {
      console.log(data);
    }, err => {
      console.log(err);
    });

总结:

请求成功和请求失败都可以then这个回调函数中。

3)、Promise的链式调用

代码如下:

 //链式调用第一种方式
    new Promise((resolve, reject) => {
      resolve('请求') 
    }).then(data => {
      console.log(data);
      return new Promise((resolve,reject)=>{
        resolve(data)
      }).then(data=>{
        console.log(data+'1111')
      })
    });
    //链式调用第二种方式
    new Promise((resolve,reject)=>{
      resolve("请求")
    }).then(data=>{
      return Promise.resolve(data).then(data=>{
        console.log('11111'+data)
      })
    });
    //链式调用第三种方式
     new Promise((resolve,reject)=>{
       resolve('请求')
     }).then(data=>{
        console.log( data+'aaaa')
     });

4)、Promise的all方法使用

Promise.all([
      new Promise((resolve, reject) => {
        $ajax({
          url: '',
          seccess: function (data) {
            resolve(data);
          }
        });
      }),
      new Promise((resolve, reject) => {
        $ajax({
          url: '',
          seccess: function (data) {
            resolve(data);
          }
        });
      })
    ]).then(results => {
      //results  返回的类型为数组   数组包括请求1 和 请求2 的结果 
    });
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容