vue2.0复习

994 阅读7分钟

vue

用vue-cli创建一个vue项目

  1. 安装
npm install -g @vue/cli
# OR
yarn global add @vue/cli

创建项目

vue create my-project
# OR
vue ui
  1. 安装配置:具体配置按具体情况来

    第一步

    ? Please pick a preset: (Use arrow keys)

    Default ([Vue 2] babel, eslint) //默认vue2配置 Default (Vue 3 Preview) ([Vue 3] babel, eslint) //默认vue3配置 Manually select features //手动配置

第二步

​ ? Check the features needed for your project: (Press to select, to toggle all, to invert selection)

() Choose Vue version //选择vue版本 () Babel //转码器,将es6变为es5 ( ) TypeScript //TypeScript是一个JavaScript(后缀.js)的超集(后缀.ts) ( ) Progressive Web App (PWA) Support // 渐进式Web应用程序 ( ) Router //路由 ( ) Vuex //状态管理 ( ) CSS Pre-processors //CSS预处理器如less,sass () Linter / Formatter // 代码规范和报错 ( ) Unit Testing //单元测试 ( ) E2E Testing //end to end测试

第三步 ? Choose a version of Vue.js that you want to start the project with (Use arrow keys)

2.x //vue2.0 3.x (Preview) //vue3.0

第四步 ? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) //使用什么路由模式, 我经常选n,使用hash模式

第五步 ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys) //使用那种css的预处理器

Sass/SCSS (with dart-sass) Sass/SCSS (with node-sass) Less //我经常用 Stylus

第六步 ? Pick a linter / formatter config: (Use arrow keys) //选择那种代码规则

ESLint with error prevention only ESLint + Airbnb config ESLint + Standard config ESLint + Prettier //我经常用

第七步 ? Pick additional lint features: (Press to select, to toggle all, to invert selection)

(*) Lint on save //保存就检测 ( ) Lint and fix on commit //fix和commit时检测

第八步 ? Pick a unit testing solution: (Use arrow keys)

Mocha + Chai //mocha灵活,只提供简单的测试结构,如果需要其他功能需要添加其他库/插件完成。必须在全局环境中安装 Jest //安装配置简单,容易上手。内置Istanbul,可以查看到测试覆盖率,相较于Mocha:配置简洁、测试代码简洁、易于和babel集成、内置丰富的expect

第九步 ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files //独立文件放置

In package.json //存放在package.json中

第十步 ? Save this as a preset for future projects? (y/N) //是否保存配置

vue项目创建完毕。

我们打开我们创建的文件,先打开src里面的app.vue。

1616896148882

里面全部删除,敲上如下代码

<template>
  <div id="app">

  </div>
</template>

<script>
export default {
    data(){
      return {

      }
    },
    methods: {
    
  }
}
</script>

<style lang="less">
#app {

}

</style>

template内是html,需要且只有有一个根元素

script内data写数据,methods写逻辑

style内写样式

数据绑定

<template>
  <div id="app">
    {{a}}
    <!-- 插值表达式,可以将data里面的值显示到页面 -->
    {{a+2}}
    <!-- 可以输出简单的表达式的结果 -->
    {{a+3>2? '大':'小'}}
    <!-- 可以用三元表达式 -->
  </div>
</template>

<script>
export default {
    data(){
      return {
        a:'1'
      }
    },
    methods: {
    
  }
}
</script>

<style>
#app {

}
</style>

双向数据绑定:data的值变化时,页面的数据也会跟着变化,页面的数据变化,data的值也会发生变化

nextTick():获取dom更新后的数据

指令

指令是带有v-开头的特殊指令

v-block

v-text

和插值表达式差不多,显示data的数据

<template>
  <div id="app">
    <h1 v-text="msg"></h1>
  </div>
</template>

<script>
export default {
    data(){
      return {
        msg: 'Hello Vue.'
      }
    },
    methods: {
  }
}
</script>

<style>
#app {

}
</style>

v-html

和v-text差不多,这里可以解析html标签

<template>
  <div id="app">
    <div v-html="msg"></div>
    
  </div>
</template>

<script>
export default {
    data(){
      return {
        msg: '<h1>Hello Vue.</h1>'
      }
    },
    methods: {
  }
}
</script>

<style>
#app {

}
</style>

v-pre

其和其子元素跳过编译,直接显示,加快性能,

<template>
  <div id="app">
    <div v-pre>{{msg}}</div>
  </div>
</template>

<script>
export default {
    data(){
      return {
        msg: '<h1>Hello Vue.</h1>'
      }
    },
    methods: {
  }
}
</script>

<style>
#app {

}
</style>

v-once

只渲染一次,后面再也不改动

<template>
  <div id="app">
    <p @click="add">点击变化:{{ a }}</p>
    <p v-once @click="add">点击不变:{{ a }}</p>
  </div>
</template>

<script>
export default {
    data(){
      return {
        msg: '<h1>Hello Vue.</h1>',
        a:1
      }
    },
    methods: {
      add(){
        this.a++
      }
  }
}
</script>

<style>
#app {

}
</style>

v-show

显示和隐藏,设置元素属性display:none;

<template>
  <div id="app">
    <h1 v-show="true">{{msg}}显示</h1>
    <h1 v-show="false">{{msg}}</h1>不显示
  </div>
</template>

<script>
export default {
    data(){
      return {
        msg: 'Hello Vue.',
      }
    },
    methods: {
     
  }
}
</script>

<style>
#app {

}
</style>

v-if,v-else-if,v-else

如同if...else if....else....的用法,这里隐藏后元素都不会出现

<template>
  <div id="app">
    <p v-if="nub>3">大于</p>
    <p v-else-if="nub=3">等于</p>
    <p v-else>小于</p>
  </div>
</template>

<script>
export default {
    data(){
      return {
        nub: 3,
      }
    },
    methods: {
     
  }
}
</script>

<style>
#app {

}
</style>

v-for

可以自动帮你循环数组和对象

<template>
  <div id="app">
    <ul>
      <li v-for="(val,key) in No" :key="key">
<!-- val是值,key是属性名,key是用于虚拟dom查找用的,不写没用语法错误,但正常都要写上,不如可能会出问题 -->
        {{key+"---"+val}}
      </li>
    </ul>
    <ul>
      <li v-for="(value,index) in No.girlfriend" :key="index">
<!-- value是值,index是索引 -->
        {{ value}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
    data(){
      return {
        No:{
          name:"不忘",
          age:"20",
          girlfriend:['冰冰','黑嘉嘉','雷姆']
        }
      }
    },
    methods: {
     
  }
}
</script>

<style>
#app {

}
</style>

v-model

表单的数据绑定

<template>
  <div id="app">
   <input type="text" v-model="msg">
   <br>
   表单的内容:{{msg}}
  <!-- 表单的值改变msg的值,msg改变,页面的值也跟着改变,这就可以看到什么是双向数据绑定 -->

  </div>
</template>

<script>
export default {
    data(){
      return {
        msg: "",
      }
    },
    methods: {
     
  }
}
</script>

<style>
#app {

}
</style>

有关v-model的修饰符

<template>
  <div id="app">
   <input type="text" v-model.lazy="msg">
   <br>
   表单的内容:{{msg}}
  <!-- 此时失去焦点值才会发生变化 -->

  </div>
</template>

<script>
export default {
    data(){
      return {
        msg: "",
      }
    },
    methods: {
     
  }
}
</script>

<style>
#app {

}
</style>

常用的修饰符

改成change方法:lazy

输入数字:number

去除首尾空白:trim

v-bind

属性绑定,有时候属性是动态的,绑定后就可以改变值简写是:

基础用法

<template>
  <div id="app">
  <a :href="url">去</a>
  </div>
</template>
<script>
export default {
    data(){
      return {
        url: "http://www.baidu.com/",
      }
    },
    methods: {
     
  }
}
</script>

<style>
#app {

}

绑定class(对象)

<template>
  <div id="app"> 
  <h1 :class="{red:isred}">hello world. </h1>
  </div>
</template>
<script>
export default {
    data(){
      return {
        isred:true,
      }
    },
    methods: {
     
  }
}
</script>

<style>
 .red{
    color: red;
  }
</style>

绑定class(数组)

<template>
  <div id="app">
  <h1 :class="['red']">hello world. </h1>
  </div>
</template>
<script>
export default {
    data(){
      return {
        
      }
    },
    methods: {
     
  }
}
</script>

<style>
 .red{
    color: red;
  }
</style>

绑定style

<template>
  <div id="app">
  <h1 :style="{color:col}">hello world. </h1>
  </div>
</template>
<script>
export default {
    data(){
      return {
        col:'red'
      }
    },
    methods: {
     
  }
}
</script>

<style>

</style>

绑定style(数组)

<template>
  <div id="app">
  
  <h1 :style="[col]">hello world. </h1>
  </div>
</template>
<script>
export default {
    data(){
      return {
        col:{color:'red'}
      }
    },
    methods: {
     
  }
}
</script>

<style>

</style>

v-on

绑定事件,简写@

基础用法

<template>
  <div id="app">
  <p>{{a}}</p>
  <button @click="add">加一</button>
  </div>
</template>
<script>
export default {
    data(){
      return {
        a:1
      }
    },
    methods: {
     add(){
       this.a++
     }
  }
}
</script>

<style>

</style>

常用的事件有:

单击:click

双击:dblclick

鼠标移入:mouseover

鼠标移出:mouseleave

鼠标移动:mousemove

获取焦点:focus

失去焦点:blue

按键弹起:keyup

按键按下:keydown

传递参数

<template>
  <div id="app">
  <p>{{a}}</p>
  <button @click="add(2)">加二</button>
  </div>
</template>
<script>
export default {
    data(){
      return {
        a:1
      }
    },
    methods: {
     add(nub){
       this.a=this.a+nub;
     }
  }
}
</script>

<style>

</style>

有关v-on的修饰符

可以对事件进行一定规定

<template>
  <div id="app">
  <a href="https://www.baidu.com/" @click.prevent="add">加一去</a>
      <!-- a链接不发生跳转因为阻止默认事件了 -->
  {{a}}
  </div>
</template>
<script>
export default {
    data(){
      return {
        a:1
      }
    },
    methods: {
     add(){
       this.a++
     }
  }
}
</script>

<style>

</style>

常用的修饰符有

停止冒泡:stop

阻止默认行为:prevent

只触发一次:once

自触发自身:self

键盘触发的按键:.enter 或者.按键码

修饰符可以连用,且有先后顺序问题

自定义指令

过滤器filter

可以将数据按照固定格式修改

全局过滤器

所有文件都可以使用

<template>
  <div id="app">
  <p>{{name | no}}</p>
  </div>
</template>
<script>

export default {
    data(){
      return {
        name:"不忘"
      }
    },
    methods: {
     
    },

}
</script>

<style>

</style>

上面是使用过滤器,全局过滤器需要在main.js定义

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

Vue.filter('no',_=>{//全局过滤器
  return _+'最帅'
})

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

局部过滤器

当前文件可以使用

<template>
  <div id="app">
  <p>{{name | no}}</p>
  </div>
</template>
<script>

export default {
    data(){
      return {
        name:"不忘"
      }
    },
    methods: {
     
    },
  filters:{
    no(msg){
      return msg+'最帅'
    }
  }
}
</script>

<style>

</style>

侦听器watch

可以监听数据变化,当数据变化时触发

<template>
  <div id="app">
  <p>{{a}}</p>
  <button @click="add">加一</button>
  <br>
  现在的值:{{newval}}
  <br>
  之前的值:{{old}}
  </div>
</template>
<script>
export default {
    data(){
      return {
        a:1,
        newval:'',
        old:''
      }
    },
    methods: {
     add(){
       this.a++
     }
    },
    watch:{
      a(newval,old){
        //第一个参数是改变后的值,第二个是改变前的值
        this.newval=newval
        this.old=old
      }
    }
}
</script>

<style>

</style>

计算属性computed

在{{}}放入太多逻辑会加大计算机处理,在computed内会将数据修改后保存

computed内是属性名不能和data中一样

<template>
  <div id="app">
    {{fullname}}
  </div>
</template>
<script>
export default {
    data(){
      return {
        firstname:'东方',
        lastname:'老赢',
      }
    },
    methods: {
     
    },
    computed:{
      fullname(){
        return this.firstname + '-' + this.lastname;
      }
    }
}
</script>

<style>

</style>

组件

组件就是自己定义一段html,然后用一个标签就可以引用,经常用的html片段就可以封装成一个组件

全局注册

在component的文件夹下创建son.vue文件

<template>
  <div id="son">
    <h1>为天地立心</h1>
  </div>
</template>
<script>
export default {
    name:'son',
    data(){
      return {
        message:'hellow vue.',
        isShow:true,
      }
    },
    methods: {
    
    }
}
</script>

<style>

</style>

在main.js文件下创建

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

import son from './components/son.vue'; //导入son.vue
Vue.component('Son', son)//设置全局组件

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

在app.vue中使用

<template>
  <div id="app">
    <Son />
    <!-- 使用组件 -->
  </div>
</template>
<script>
export default {
    name:'app',
    data(){
      return {
      }
    },
    methods: {
    
    }
}
</script>

<style>

</style>

局部注册

和上面一样在component的文件夹下创建son.vue文件

然后再app.vue上使用

<template>
  <div id="app">
    <Son />
    <!-- 使用组件 -->
  </div>
</template>
<script>
import Son from './components/son'
export default {
    name:'app',
    components: {
      Son
    },
    data(){
      return {
      }
    },
    methods: {
     
    }
}
</script>

<style>

</style>

组件传值

父传子

父组件

<template>
  <div id="app">
    <Son :fatherMsg="msg"/>
    <!-- 将要传的值属性绑定在标签上 -->
  </div>
</template>
<script>
import Son from './components/son'
export default {
    name:'app',
    components: {
      Son
    },
    data(){
      return {
        msg:'为生民立命'
      }
    },
    methods: {
   
    }
}
</script>

<style>

</style>

子组件

<template>
  <div id="son">
    <h1>为天地立心</h1>
    <h1>{{fatherMsg}}</h1>
  </div>
</template>
<script>
export default {
    name:'son',
    //使用props接受父组件的值,有两种写法
    props:['fatherMsg'],
    // props:{
    //     fatherMsg: {
    //         required: true,//必填
    //         type: String,//字符串类型
    //     }
    // },
    data(){
      return {
    
      }
    },
    methods: {
  
    }
}
</script>

<style>

</style>

子传父

父组件

<template>
  <div id="app">
    <Son @sonShow="fatherShow"/>
      <!-- 用方法绑定传递fatherShow方法 -->
    <h1>{{msg}}</h1>
  </div>
</template>
<script>
import Son from './components/son'
export default {
    name:'app',
    components: {
      Son
    },
    data(){
      return {
        msg:''
      }
    },
    methods: {
     fatherShow(sonMsg){
       this.msg=sonMsg
     }
    }
}
</script>

<style>

</style>

子组件

<template>
  <div id="son">
    <button @click="show">出现</button>
    <h1>为天地立心</h1>
  </div>
</template>
<script>
export default {
    name:'son',
    data(){
      return {
        msg:'为生民立命',
      }
    },
    methods: {
     show(){
       this.$emit('sonShow',this.msg)//用sonShow接收方法,并将给父组件的数据加到参数内
     }
    }
}
</script>

<style>

</style>

Even bus传值

在src下创建utils文件夹,在创建bus.js

import Vue from 'vue'
export const eventbus = new Vue()

子组件

<template>
  <div id="son">
    {{didi}}
    <button @click="givege">获取弟弟的消息</button>
  </div>
</template>
<script>
import {eventbus} from '../utils/bus.js'
export default {
    name:'son',
    data(){
      return {
        didi:'',
        a:'今朝有酒今朝醉'
      }
    },
    methods: {
      givege(){
        eventbus.$emit('givege',this.a)
      }
    }
}
</script>

<style>

</style>

创建兄弟组件borther.vue

<template>
  <div id="app">
    {{gege}}
    <button @click='givedi'>获取哥哥的消息</button>
  </div>
</template>
<script>
import {eventbus} from '../utils/bus.js'
export default {
    name:'app',
    data(){
      return {
       gege:'',
       b:'明日愁来明日愁'
      }
    },
    methods: {
      givedi(){
        eventbus.$emit('givedi',this.b)
      }
    }
}
</script>

<style>

</style>

在app.vue

<template>
  <div id="app">
    <Son />
    <Borther />
  </div>
</template>
<script>
import Son from "./components/son"
import Borther from "./components/brother"
import {eventbus} from './utils/bus.js'
export default {
    name:'app',
    components:{
      Son,Borther
    },
    data(){
      return {
     
      }
    },
    methods: {
    },
    mounted(){
      eventbus.$on('givedi',data=>{
        console.log(data);
      })
      eventbus.$on('givege',data=>{
        console.log(data);
      })
    }
}
</script>

<style>

</style>

多级组件传值

attrs/attrs/listeners

父组件

<template>
  <div id="app">
      <h1>为天地立心</h1>
    <Son :msg="msg" :msgT="msgT" :msgS="msgS" @father="father" @gfather="gfather"/>
  </div>
</template>
<script>
import Son from './components/son'
export default {
    name:'app',
    components: {
      Son
    },
    data(){
      return {
        msg:'为生民立命',
        msgT:'继往圣绝学',
        msgS:'为万世开太平'
      }
    },
    methods: {
      father(){
        console.log("666");
      },
      gfather() {
        console.log("牛比");
      }
    }
}
</script>

<style>

</style>

子组件

<template>
  <div id="son">
    <h1>{{msg}}</h1>
    <h1>{{$attrs}}</h1>
    <Gson v-bind="$attrs" v-on="$listeners"/>
  </div>
</template>
<script>
import Gson from "./gson";
export default {
    name:'son',
    inheritAttrs:false,// 可以关闭自动挂载到组件根元素上的没有在props声明的属性
    props:['msg'],//这里截取后孙子就获取不到了
    components:{
        Gson
    },
    data(){
      return {
    
      }
    },
    methods: {
      
    },
    mounted(){
      this.$emit('father')
    }
}
</script>

<style>

</style>

子组件的子组件

<template>
  <div id="son">
    <h1>{{msgT}}</h1>
  </div>
</template>
<script>
export default {
    name:'son',
    inheritAttrs:false,
    props:['msgT'],
    data(){
      return {
    
      }
    },
    methods: {
  
    },
    mounted(){
      this.$emit('gfather')
    }
}
</script>

<style>

</style>

provide/inject

父组件

<template>
  <div id="app">
    <h1>为天地立心</h1>
    <Son/>
  </div>
</template>
<script>
import Son from './components/son'
export default {
    name:'app',
    components: {
      Son
    },
    data(){
      return {
      }
    },
    provide: {
      msgT:'为生民立命',
      msgS:'为继往圣绝学'
    },
    methods: {
     
    }
}
</script>

<style>

</style>

子组件

<template>
  <div id="son">
    <h1>{{msgT}}</h1>
    <Gson />
  </div>
</template>
<script>
import Gson from "./gson";
export default {
    name:'son',
    inject:['msgT'],
    components:{
        Gson
    },
    data(){
      return {
    
      }
    },
    methods: {
      
    },
    mounted(){
      this.$emit('father')
    }
}
</script>

<style>

</style>

子组件的子组件

<template>
  <div id="son">
    <h1>{{msgS}}</h1>
  </div>
</template>
<script>
export default {
    name:'son',
    inject:['msgS'],
    data(){
      return {
    
      }
    },
    methods: {
  
    },
    mounted(){
      this.$emit('gfather')
    }
}
</script>

<style>

</style>

vuex

看下面

插槽

在父组件添加子组件的内容

普通插槽

父组件

<template>
  <div id="app">
    <h1>为天地立心</h1>
    <Son>
      <h1>为万世开太平</h1>
     <!-- 写到子组件的内容 -->
    </Son>
  </div>
</template>
<script>
import Son from './components/son'
export default {
  name: 'app',
  components: {
    Son
  },
  data () {
    return {
    }
  },
  methods: {
  }
}
</script>

<style>
</style>

子组件

<template>
  <div id="app">
      <h1>为生民立命</h1>
      <slot></slot>
   <!-- 父组件内容存放的位置-->
  </div>
</template>
<script>
export default {
  name: 'app',
  data () {
    return {
    }
  },
  methods: {
  }
}
</script>

<style>
</style>

具名插槽

父组件

<template>
  <div id="app">
    <Son>
      <template v-slot:header>
        <h1>为天地立心</h1>
      </template>
      <template v-slot:footer>
        <h1>为万世开太平</h1>
      </template>
    </Son>
  </div>
</template>
<script>
import Son from './components/son'
export default {
  name: 'app',
  components: {
    Son
  },
  data () {
    return {
    }
  },
  methods: {
  }
}
</script>

<style>
</style>

子组件

<template>
  <div id="app">
      <slot name="header"></slot>
      <h1>为生民立命</h1>
      <slot name="footer"></slot>
  </div>
</template>
<script>
export default {
  name: 'app',
  data () {
    return {
    }
  },
  methods: {
  }
}
</script>

<style>
</style>

作用域插槽

父组件

<template>
  <div id="app">
    <h1>为天地立心</h1>
    <Son>
     <template v-slot:default="soldata">
       <h1>{{soldata.data}}</h1>
     </template>
    </Son>

    <!-- <Son  v-slot:default="soldata">
       <h1>{{soldata.data}}</h1>
    </Son> -->

    <!-- <Son  v-slot="soldata">
       <h1>{{soldata.data}}</h1>
    </Son> -->
  </div>
</template>
<script>
import Son from './components/son'
export default {
  name: 'app',
  components: {
    Son
  },
  data () {
    return {
    }
  },
  methods: {
  }
}
</script>

<style>
</style>

子组件

<template>
  <div id="app">
      <h1>为生民立命</h1>
      <slot :data="msg">{{msg}}</slot>
  </div>
</template>
<script>
export default {
  name: 'app',
  data () {
    return {
      msg: '为万世开太平'
    }
  },
  methods: {
  }
}
</script>

<style>
</style>

vue生命周期钩子函数

一个组件从开始到消亡所经历的全部过程,就是一个组件的生命周期

简单讲就是你看到组件在页面出现和消失的过程,在这个过程中会自动触发几个函数,就是生命周期钩子函数

父组件

<template>
  <div id="app">
    <h1 @click="change">让组件消失</h1>
    <Son v-if="isShow"/>
  </div>
</template>
<script>
import Son from './components/son'
export default {
    name:'app',
    components: {
      Son
    },
    data(){
      return {
        isShow:true
      }
    },
    provide: {
      msgT:'为生民立命',
      msgS:'为继往圣绝学'
    },
    methods: {
     change(){
       this.isShow=false;
     }
    }
}
</script>

<style>

</style>

子组件

<template>
  <div id="son">
    <button @click="change">{{!isShow?'出现':"消失"}}</button>
    <h1 v-if="isShow">{{message}}</h1>
  </div>
</template>
<script>
export default {
    name:'son',
    data(){
      return {
        message:'hellow vue.',
        isShow:false,
      }
    },
    methods: {
     change(){
       this.isShow = !this.isShow;
     }
    },
     beforeCreate(){
      console.group('------beforeCreate创建前状态------');
      console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
      console.log("%c%s", "color:red","data   : " + this.$data); //undefined 
      console.log("%c%s", "color:red","message: " + this.message) //undefined 
    },
    created(){
      console.group('------created创建完毕状态------');
      console.log("%c%s", "color:red","el     : " + this.$el); //undefined
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化 
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    beforeMount(){
      console.group('------beforeMount挂载前状态------');
      console.log("%c%s", "color:red","el     : " + (this.$el)); //undefined
      //此时应该是已经初始化但数据未加载上去,但结果确实未underfind,不是很了解情况,各位可以自己尝试一下
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化  
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化  
    },
    mounted(){
      console.group('------mounted 挂载结束状态------');
      console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
      console.log(this.$el);    
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
    },
    beforeUpdate(){
      console.group('beforeUpdate 更新前状态===============》');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);   
      console.log("%c%s", "color:red","data   : " + this.$data); 
      console.log("%c%s", "color:red","message: " + this.message); 
    },
    updated(){
      console.group('updated 更新完成状态===============》');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el); 
      console.log("%c%s", "color:red","data   : " + this.$data); 
      console.log("%c%s", "color:red","message: " + this.message); 
    },
    beforeDestroy(){
      console.group('beforeDestroy 销毁前状态===============》');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);    
      console.log("%c%s", "color:red","data   : " + this.$data); 
      console.log("%c%s", "color:red","message: " + this.message); 
    },
    destroyed(){
      console.group('destroyed 销毁完成状态===============》');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);  
      console.log("%c%s", "color:red","data   : " + this.$data); 
      console.log("%c%s", "color:red","message: " + this.message)
    }
}
</script>

<style>

</style>

vue路由

单页面应用(SPA),第一次加载页面,后面全部都是获取数据,加快页面的响应速度,不利于seo

这里页面跳转变成了路由跳转

由于我用的是脚手架,所以vue-router已经配置好了,可以打开router文件下的index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
   //这里配置路由
  {
    path: '/',//路径
    name: 'Home',//路由名
    component: Home//指向的组件
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

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

export default router

修改app.vue

<template>
  <div id="app">
    <router-view />
    <!-- 路由开启,开始按照路由的文件导入组件 -->
  </div>
</template>

<style>
</style>

路由跳转

router-link

不带参数

<template>
<router-link :to="{name:'home'}">跳转</router-link>
<router-link :to="{path:'/home'}">跳转</router-link>
<!-- 注意:router-link中链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始。 -->
</template>

带参数

<template>
<router-link :to="{name:'home', params: {id:1}}"> 跳转</router-link>
     <!-- 
        在url路径中看不到
        html 取参  $route.params.id
        script 取参  this.$route.params.id
    -->
<router-link :to="{name:'home', query: {id:1}}"> 跳转</router-link>
      <!-- 
        在url路径中可以看到
        html 取参  $route.query.id
        script 取参  this.$route.query.id
    -->
</template>

this.$router.push()

不带参数

<template>
  <div id="app">
	<button @click="add">跳转</button>
  </div>
</template>

<script>
export default {
    data(){
      return {

      }
    },
    methods: {
    	go(){
            this.$router.push('/home') 
            //this.$router.push({name:'home'}) 
            //this.$router.push({path:'/home'})
        }
  	}
}
</script>

<style lang="less">
#app {

}
</style>

带参数

<template>
  <div id="app">
	<button @click="add">跳转</button>
  </div>
</template>

<script>
export default {
    data(){
      return {

      }
    },
    methods: {
    	go(){
            this.$router.push({name:'home',query: {id:'1'}})
		   //this.$router.push({path:'/home',query: {id:'1'}})
            //html 取参  $route.query.id
            //script 取参  this.$route.query.id
           
            //this.$router.push({name:'home',params: {id:'1'}}) 
            // html 取参  $route.params.id
		   // script 取参  this.$route.params.id
        }
  	}
}
</script>

<style lang="less">
#app {

}
</style>

this.$router.replace() t

用法和this.$router.push() 一样,就是history不会有记录,返回不了

this.$router.go(n)

整数向前,负数向后跳转n次,多用来做返回

导航守卫

有些页面可以跳转有些页面不能跳转,这时候就需要导航守卫了

全局

写在router的index.js中

router.beforeEach(全局前置守卫) :所以路由跳转前都会执行

router.beforeEach((to, from, next) => {
    //to : 将要进入的目标路由对象
    //from : 即将离开的目标路由对象
    //next:执行跳转的下一步钩子,执行才会进入下一步,否则不会跳转
    next()
});

router.beforeResolve() (全局解析守卫) ,和router.beforeEach差不多

router.afterEach() (全局后置钩子) :和router.beforeEach差不多,区别路由已经跳转,所以没有next

独享

{
   path: '/about',
   name: 'about',
   component: about,
   beforeEnter:(to,from,next)=>{
      console.log(to);
      console.log(from);
      next()
   }
   //和 router.beforeEach差不多,这是单个路由用的

组件内

<template>
  <div>关于页面</div>
</template>
<script>
  export default {
    name: "about",
    beforeRouteEnter(to, from, next) {
      //进入该路由时执行
    },
    beforeRouteUpdate(to, from, next) {
      //该路由参数更新时执行,同一个路由,参数改变时执行
    },
    beforeRouteLeave(to, from, next) {
      //离开该路由时执行
    }
  }
</script>
<style scoped>
</style>

vuex

使用脚手架,vuex的基本配置也弄好了,可以看到store文件夹下的index.js,vuex会将需要的数据保存,各个组件都可以调用

state

保存数据状态

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
      name:'不忘'
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

调用

<template>
  <div class="about">
    <h1>{{$store.state.name}}</h1>
  </div>
</template>
<script>
export default {
  methods: {
    test () {
      console.log(this.$store.state.name)
    }
  }
}
</script>

mutations

修改state的数据

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
      name:'不忘'
  },
  mutations: {
      change(state){//可以加第二个参数,接受调用传递过来的参数
          state.name="回忆"
      }
  },
  actions: {
  },
  modules: {
  }
})

组件调用

<template>
  <div class="about">
    <h1>{{$store.state.name}}</h1>
  </div>
</template>
<script>
export default {
  methods: {
    test () {
      this.$store.commit('change')
       //可以在后面加参数
        //this.$store.commit('change',参数)
    }
  }
}
</script>

增加删除state的数据

Vue.set(state,"age",15)//增加
Vue.delete(state,'age')//删除

getters

对数据加工

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    name: '不忘',
  },
  mutations: {
  },
  getters: {
    fullname(state) {
      const a = `姓名:${state.name}`;
      return a;
    },
  },
  actions: {
  },
  modules: {
  },
});

调用

<template>
  <div class="about">
    <h1>{{$store.getters.fullname}}</h1>
  </div>
</template>
<script>
export default {
  methods: {
    
  },
};
</script>

aciton

操作异步方法修改state

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    name: '不忘',
  },
  mutations: {
    change(state, data) {
      state.name = data;
    },
  },
  actions: {
    useChange(context, payload) {
      setTimeout(() => {
        context.commit('change', payload);
      }, 1000);
    },
  },
  modules: {
  },
});

调用

<template>
  <div class="about">
    <h1>{{$store.state.name}}</h1>
    <button @click="change">改变</button>
  </div>
</template>
<script>
export default {
  methods: {
    change() {
      this.$store.dispatch('useChange', '回忆');
    },
  },
};
</script>

modules

对vuex内数据分类,调用和前面差不多

vue.config.js

module.exports = {
  // 部署生产环境和开发环境下的URL。
  // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
  // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
  publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
  // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
  outputDir: 'dist',
  // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
  assetsDir: 'static',
  // 是否开启eslint保存检测,有效值:ture | false | 'error'
  lintOnSave: process.env.NODE_ENV === 'development',
  // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
  productionSourceMap: false,
  // webpack-dev-server 相关配置
  devServer: {
    host: '0.0.0.0',//服务器地址
    port: 3000,//开启端口
    open: true,//是否自动代开网页
    proxy: {//代理服务器,解决跨域问题
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      [process.env.VUE_APP_BASE_API]: {
        target: `http://192.168.1.53:8080`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
        }
      }
    },
    disableHostCheck: true
  },
  configureWebpack: {
    name: '不忘',//标题
    resolve: {
      alias: {
        '@': resolve('src')//导入文件时路径@/开头表示src/开头
      }
    }
  }
}

配置比较复杂,各位可以自己尝试