Vue笔记

本文详细介绍了Vue.js的基础知识和高级特性,包括渐进式框架的概念、Vue的特点、安装方法、MVVM模式、指令系统如v-if/v-for/v-model,以及组件化开发、Vue Router和Vuex的使用。此外,还涵盖了事件处理、计算属性、插槽、父子组件通信、状态管理和异步数据处理等内容,是全面学习Vue.js的实用教程。
摘要由CSDN通过智能技术生成

Vue教程,从入门到精通

Vue是渐进式框架?

  1. 渐进式意味着你可以将Vue作为应用的一部分嵌入进去,带来丰富的交互体验;
  2. 如果你希望将更多业务逻辑使用Vue实现,能够使用Vue的核心库以及其生态系统;
  3. Core+Vue-router+Vuex,满足各种各样需求。

Vue特点\高级功能

  1. 解耦视图和数据;
  2. 可复用组件;
  3. 前端路由技术;
  4. 状态管理;
  5. 虚拟DOM

安装Vue

  1. CDN引入

    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!-- 生产环境版本,优化了尺寸和速度 -->
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    
  2. 下载和引用

    <!-- 开发环境版本 -->
    https://vuejs.org/js/vue.js
    <!-- 生产环境版本 -->
    https://vuejs.org/js/vue.min.js
    
  3. NPM

    <!-- 最新稳定版 -->
    npm install vue	
    

Hello Vue初体验

<body>
    <div id="app">
        {{ message }}
    </div>
    <script src="../../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'Hello Vue!'
            }
        });
    </script>
</body>

Vue列表展示

<body>
    <div id="app">
        <div>{{ message }}</div>
        <ul>
            <li v-for="(item, i) in movies" :key="i">{{ item }}</li>
        </ul>
    </div>
    <script src="../../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊',
                movies: ['星际穿越', '钢铁侠', '盗梦空间', '死侍']
            }
        });
    </script>
</body>

计数器

<body>
    <div id="app">
        <h2>当前计数:{{ counter }}</h2>
        <button @click="add">+</button>
        <button @click="sub">-</button>
    </div>
    <script src="../../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                counter: 0
            },
            methods: {
                add() {
                    this.counter++
                },
                sub() {
                    if(this.counter !== 0){
                        this.counter--
                    }else{
                        this.counter = 0
                    }
                }
            }
        });
    </script>
</body>

Vue MVVM

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dAIwrqlH-1614003939266)(C:\Users\10131\AppData\Roaming\Typora\typora-user-images\image-20210211110927286.png)]

Vue生命周期

Vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。

Vue生命周期函数

lifecycle

插值操作

  1. {{}}
  2. v-html
  3. v-text
  4. v-pre
  5. v-cloak
<body>
  <div id="app">
    <h3>{{ message }}</h3>
    <h3 v-once>{{ message }}</h3>
    <h3 v-html="url"></h3>
    <h3 v-text="message"></h3>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '安娜',
        url: '<a href="https://www.bilibili.com/">bilibili</a>'
      }
    });
  </script>
</body>

v-bind

动态属性绑定

<body>
  <div id="app">
    <img :src="imgUrl" alt="">
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        imgUrl: 'https://i2.hdslb.com/bfs/face/c850c18ae6b507d0ef34837f53a51090b6a7451f.jpg@96w_96h_1c.webp'
      }
    });
  </script>
</body>

<body>
  <div id="app" v-cloak>
    <!-- 对象语法 -->
    <p :class="{active: isActive, line: isLine}">{{ message }}</p>
    <button @click="turnActive">turn</button>
    <hr color="black">
    <!-- 数组语法 -->
    <p :class="['active', 'line']">{{ message }}</p>
    <p :class="getClasses()">{{ message }}</p>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        isActive: true,
        isLine: true,
        message: 'fuck you',
        active: 'aaa',
        line: 'bbb'
      },
      methods: {
        turnActive() {
          this.isActive = !this.isActive
          this.isLine = !this.isLine
        },
        getClasses() {
          return [this.active, this.line]
        }
      }
    });
  </script>
</body>

v-bind和v-for结合

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="../../css/global.css">
  <title>Document</title>
  <style>
    .fontcolor {
      color: red;
      font-weight: bold;
      font-size: 30px;
    }
  </style>
</head>
<body>
  <div id="app">
    <ul>
      <li v-for="(item, i) in movies" :key="i" :class="{fontcolor: index === i}" @click="changeStyle(i)">{{ item }}</li>
    </ul>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        movies: ['海王', '进击的巨人', '火影忍者', '守望先锋'],
        index: -1
      },
      methods: {
        changeStyle(i) {
          this.index = i
        }
      }
    });
  </script>
</body>
</html>

计算属性

<body>
  <div id="app">
    <h2>总价格:{{ totalPrice }}</h2>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        overwatch: [
          { id: 1, name: 'genji', price: 110 },
          { id: 2, name: 'ana', price: 112 },
          { id: 3, name: 'mercy', price: 113 },
          { id: 4, name: 'doomfist ', price: 114 },
          { id: 5, name: 'mccree ', price: 115 },
          { id: 6, name: 'reaper', price: 116 },
          { id: 7, name: 'tracer', price: 117 }
        ]
      },
      computed: {
        totalPrice() {
          let result = 0
          // for(let i in this.overwatch){
          //   this.overwatch[i].price
          // }
          // for(let ow of this.overwatch){
          //   ow.price
          // }
          for(let i = 0; i < this.overwatch.length; i++) {
            result += this.overwatch[i].price
          }
          return result
        }
      }
    });
  </script>
</body>

计算属性的setter/getter

<body>
  <div id="app">
    <p>{{ fullName }}</p>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        firstName: 'genji',
        lastName: 'ana'
      },
      methods: {

      },
      // 属性一般没有set方法,只读属性
      computed: {
        fullName: {
          set(newValue) {
            const name = newValue.split(' ')
            this.firstName = name[0]
            this.lastName = name[1]
          },
          get() {
            return this.firstName + ' ' + this.lastName
          }
        }
      }
    });
  </script>
</body>

let/var/const

varletconst
函数作用域块级作用域块级作用域
变量提升不存在变量提升不存在变量提升
值可更改值可更改值不可更改

v-on修饰符

<body>
  <div id="app">
    <!-- stop 阻止冒泡 -->
    <div @click="divClick">
      <button @click.stop="btnClick">按钮</button>
    </div>
    <!-- prevent 阻止默认事件 -->
    <form action="baidu">
      <input type="submit" value="提交" @click.prevent="submitClick">
    </form>
    <input type="text" @keyup.enter="keyUp">
    <!-- once 仅点击一次 -->
    <button @click.once="btnsClick()">按钮</button>
    <!-- native 监听组件根元素的原生事件 -->
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      methods: {
        btnClick() {
          console.log('btnClick');
        },
        divClick() {
          console.log('divClick');
        },
        submitClick() {
          console.log('submitClick');
        },
        keyUp() {
          console.log('keyUp');
        },
        btnsClick() {
          console.log("btnsClick");
        }
      }
    });
  </script>
</body>

v-if/v-else-if/v-else

<body>
  <div id="app">
    <h2 v-if="isShow">{{ message }}</h2>
    <button @click="isShow = !isShow">点击</button>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好',
        isShow: false
      }
    });
  </script>
</body>

登录切换案例

<body>
  <!-- key解决组件复用 -->
  <!-- v-if: 当条件为false时,包含v-if指令的元素,根部不存在DOM中(操作DOM),v-show则是存在DOM中,仅隐藏(操作样式),切换频率高,使用v-show,反之v-if -->
  <div id="app">
    <span v-if="isUser">
      <label for="username">用户账号</label>
      <input type="text" id="username" placeholder="用户账号" key="username">
    </span>
    <span v-else>
      <label for="username">用户邮箱</label>
      <input type="text" id="useremial" placeholder="用户邮箱" key="useremial">
    </span>
    <button @click="isUser = !isUser">切换类型</button>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        isUser: true
      }
    });
  </script>
</body>

v-for

<body>
  <div id="app">
    <!-- 获取对象 -->
    <ul>
      <li v-for="item in info">{{ item }}</li>
    </ul>
    <!-- 获取key和value -->
    <ul>
      <li v-for="(value, key) in info">{{ value }} -- {{ key }}</li>
    </ul>
    <!-- 获取key、value和index -->
    <ul>
      <li v-for="(value, key, index) in info">{{ value }} -- {{ key }} -- {{ index }}</li>
    </ul>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        info: {
          name: 'genji',
          age: '18',
          height: 1.6
        }
      }
    });
  </script>
</body>

v-model双向数据绑定/实现原理

<body>
  <div id="app">
    <input type="text" v-model="message">
    <h2>{{ message }}</h2>
    <!-- v-model实现原理 v-bind + v-on -->
    <input type="text" :value="message" @input="valueChange">
    <h2>{{ message }}</h2>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      methods: {
        valueChange(event) {
          this.message = event.target.value
        }
      }
    });
  </script>
</body>

v-model结合radio

<body>
  <div id="app">
    <label for="male">
      <input type="radio" id="male" value="" v-model="sex"></label>
    <label for="female">
      <input type="radio" id="female" value="" v-model="sex"></label>
    <h2>您的性别是:{{sex}}</h2>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        sex: '男'
      }
    });
  </script>
</body>

v-model结合checkbox

<body>
  <div id="app">
    <!-- checkbox单选框 -->
    <label for="agree">
      <input type="checkbox" id="agree" v-model="isAgree">同意协议
    </label>
    <h2>您选择的是:{{isAgree}}</h2>
    <button :disabled="!isAgree">下一步</button>
    <br>
    <!-- checkbox多选框 -->
    <label for="hero">
      <input type="checkbox" value="ana" v-model="heroes">ana
      <input type="checkbox" value="hanzo" v-model="heroes">hanzo
      <input type="checkbox" value="mercy" v-model="heroes">mercy
      <input type="checkbox" value="genji" v-model="heroes">genji
    </label>
    <h2>您选择的是:{{heroes.join(' ')}}</h2>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        isAgree: false,
        heroes: []
      }
    });
  </script>
</body>

v-model结合select

<body>
  <div id="app">
    <!-- 选择一个 -->
    <select name="abcd" id="" v-model="abcd">
      <option value="a">a</option>
      <option value="b">b</option>
      <option value="c">c</option>
      <option value="d">d</option>
    </select>
    <h2>您选择的是:{{abcd}}</h2>
    <br>
    <!-- 选择多个 -->
    <select name="abcds" id="" v-model="abcds" multiple>
      <option value="a">a</option>
      <option value="b">b</option>
      <option value="c">c</option>
      <option value="d">d</option>
    </select>
    <h2>您选择的是:{{abcds.join(' ')}}</h2>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        abcd: 'b',
        abcds: []
      }
    });
  </script>
</body>

v-model修饰符

<body>
  <div id="app">
    <!-- 1. lazy -->
    <input type="text" v-model.lazy="message">
    <h2>{{message}}</h2>
    <!-- 2. number -->
    <input type="text" v-model.number="age">
    <h2>{{age}}---{{typeof age}}</h2>
    <!-- 3. trim -->
    <input type="text" v-model.trim="name">
    <h2>{{name}}---{{typeof name}}</h2>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello',
        age: 0,
        name: ''
      }
    });
  </script>
</body>

组件化开发

  1. 开发出一个个独立可复用的小组件来构造应用;
  2. 任何应用都能被抽象成一个组件树。

组件化基本使用

<body>
  <div id="app">
    <my-cpn></my-cpn>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    // 1.创建组件构造器对象
    const cpnC = Vue.extend({
      template:`
        <div>
          <h2>ana</h2>
          <p>overwatch</p>
          <p>overwatch</p>
          <p>overwatch</p>
        </div>`
    })
    // 2.注册组件(全局组件)
    Vue.component('my-cpn', cpnC)
    const app = new Vue({
      el: '#app',
      // 局部注册
      components: {
        cpn: cpnC
      }
    });
  </script>
</body>

父组件/子组件

<body>
  <div id="app">
    <my-ow>
      <cpn></cpn>
    </my-ow>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    // 1.创建组件构造器对象
    const cpnC = Vue.extend({
      template:`
        <div>
          <h2>ana</h2>
          <p>overwatch</p>
          <p>overwatch</p>
          <p>overwatch</p>
        </div>`
    })
    // 创建第二个组件
    const ow = Vue.extend({
      template: `
        <div>
          <h2>守望先锋</h2>
          <p>斯巴拉西</p>
          <cpn></cpn>
        </div>
      `,
      components: {
        cpn: cpnC
      }
    })
    // 2.注册组件
    Vue.component('my-ow', ow)
    const app = new Vue({
      el: '#app'
    });
  </script>
</body>

注册组件语法糖

<body>
  <div id="app">
    <my-cpn></my-cpn>
  </div>
  <script src="../../js/vue.js"></script>
  <script>
    // 1.创建组件构造器对象
    // const cpnC = Vue.extend()
    // 2.注册组件
    Vue.component('my-cpn', 
    {
      template:`
        <div>
          <h2>ana</h2>
          <p>overwatch</p>
          <p>overwatch</p>
          <p>overwatch</p>
        </div>`
    })
    const app = new Vue({
      el: '#app'
    });
  </script>
</body>

组件模板抽离

<body>
  <div id="app">
    <my-ow></my-ow>
  </div>
  <script src="../../js/vue.js"></script>
  <!-- <script type="text/x-template" id="ow">
    <div>
      <h2>overwatch</h2>
      <p>斯巴拉西</p>
    </div>
  </script> -->
  <template id="ow">
    <div>
      <h2>overwatch</h2>
      <p>斯巴拉西</p>
    </div>
  </template>
  <script>
    // 1.创建组件构造器对象
    // const cpnC = Vue.extend()
    // 2.注册组件
    Vue.component('my-ow', { template:  '#ow'})
    const app = new Vue({
      el: '#app'
    });
  </script>
</body>

组件数据的存放

  1. 组件对象也有一个data属性,以及methods等属性;
  2. data属性必须是一个函数;
  3. 函数返回一个对象,对象内部保存着数据。

父传子props

<body>
  <div id="app">
    <cpn :c-info="info" :child-my-message="message"></cpn>
  </div>
  <script src="../../js/vue.js"></script>
  <template id="cpn">
    <div>
      <h2>{{cInfo}}</h2>
      <h2>{{childMyMessage}}</h2>
    </div>
  </template>
  <script>
    const cpn = {
      template: '#cpn',
      props: {
        cInfo: {
          type: Object,
          default() {
            return {}
          }
        },
        childMyMessage: {
          type: String,
          default() {
            return {}
          }
        }
      }
    }
    const app = new Vue({
      el: '#app',
      data: {
        info: {
          name: 'tkx',
          age: 22,
          height: 1.73
        },
        message: 'aaaa'
      },
      components: {
        cpn
      }
    });
  </script>
</body>

子传父(事件传值)

<body>
  <div id="app">
    <cpn @item-click="cpnClick"></cpn>
  </div>
  <template id="cpn">
    <div>
      <button  v-for="item in categories" :key="item.id" @click="btnClick(item)">{{item.name}}</button>
    </div>
  </template>
  <script src="../../js/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
      data() {
        return {
          categories: [
            { id: '1', name: 'lizeyan' },
            { id: '2', name: 'hanzo' },
            { id: '3', name: 'genji' },
            { id: '4', name: 'mercy' }
          ]
        }
      },
      methods: {
        btnClick(item) {
          // 发射 自定义事件
          this.$emit('item-click', item)
        }
      }
    }
    const app = new Vue({
      el: '#app',
      methods: {
        cpnClick(item) {
          console.log(item);
        }
      },
      components: {
        cpn
      }
    });
  </script>
</body>

父访问子(children/refs)

<body>
  <div id="app">
    <cpn></cpn>
    <cpn></cpn>
    <cpn ref="aaa"></cpn>
    <button @click="btnClick">按钮</button>
  </div>
  <template id="cpn">
    <div>
      <h2>我是子组件</h2>
    </div>
  </template>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      methods: {
        btnClick() {
          console.log(this.$children);
          this.$children[0].showMessage()
          // $refs => 对象类型,默认是一个空对象 ref='***'
          console.log(this.$refs.aaa);
        }
      },
      computed: {

      },
      components: {
        cpn: {
          template: '#cpn',
          methods: {
            showMessage() {
              console.log('showmessage');
            }
          }
        }
      }
    });
  </script>
</body>

子访问父(parent/root)

<body>
  <div id="app">
    <cpn></cpn>
  </div>
  <template id="cpn">
    <div>
      <h2>我是子组件</h2>
      <button @click="btnClick">按钮</button>
    </div>
  </template>
  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      components: {
        cpn: {
          template: '#cpn',
          methods: {
            btnClick() {
              console.log(this.$parent);
              console.log(this.$root);
            }
          }
        }
      }
    });
  </script>
</body>

插槽slot

<!-- 基本使用 -->
<body>
  <div id="app">
    <cpn><button>我是button元素</button></cpn>
  </div>
  <template id="cpn">
    <div>
      <div>我是div元素</div>
      <slot>我是slot元素</slot>
      <h2>我是h2元素</h2>
    </div>
  </template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = Vue.extend({
      template: '#cpn',
    })
    const app = new Vue({
      el: '#app',
      components: {
        cpn
      }
    });
  </script>
</body>
<!-- 具名插槽 -->
<body>
  <div id="app">
    <cpn>
      <div slot="center">
        <h2>中间被替换</h2>
      </div>
    </cpn>
  </div>
  <template id="cpn">
    <div>
      <slot name="left">我是左边</slot>
      <slot name="center">我是中间</slot>
      <slot name="right">我是右边</slot>
    </div>
  </template>
  <script src="../../js/vue.js"></script>
  <script>
    const cpn = Vue.extend({
      template: '#cpn'
    })
    const app = new Vue({
      el: '#app',
      components: {
        cpn
      }
    });
  </script>
</body>

作用域插槽

<div id="app">
	<cpn v-show="isShow"><template slot-scope="scope"></template></cpn>
</div>

CommonJS

// 模块化两个核心:导入和导出
// CommonJS导出
module.exports = {
    flag: true,
    test(a, b) {
        return a + b
    },
    demo(a, b) {
        return a * b
    }
}

//CommonJS导入
let { test, demo, flag } = require('moduleA');
// 等同于
let _mA = require('moduleA');
let test = _mA.test;
let demo = _mA.demo;
let flag = _mA.flag;

webpack安装

  1. 安装node.js

  2. 全局安装webpack

    npm install webpack@3.6.0 -g
    npm install webpack@3.6.0 --save-dev
    
  3. 打包js文件

    webpack ./src/main.js ./dist/bundle.js
    

配置

// webpack.config.js
const path = require('path')
module.export = {
	entry: path.resolve(__dirname, 'dist'),
	output: {
		// 绝对路径 动态获取
		path: '',
		filename: 'bundle.js'
	}
}
//package.json
npm init
"build": "webpack"
npm run build

loader安装

  1. npm install --save-dev css-loader,;

  2. webpack.config.js配置

    module: {
    	rules: [
    		{
    			test: /\.css$/,
    			use: ['style-loader', 'css-loader']
    		}
    	]
    }
    

webpack-less文件处理

  1. npm install --save-dev less-loader less;

  2. webpack.config.js配置

    module: {
    	rules: [{
    		test: /\.less$/,
    		loader: 'less-loader' // 将 Less 编译为 CSS
    	}]
    }
    

webpack图片文件处理

  1. npm install url-loader --save-dev、npm install file-loader --save-dev

  2. webpack.config.js配置

    module: {
    	rules: [{
    		test: /\.(png|jpg|gif)$/i,
    		use: [{
    			loader: 'url-loader',
    			options: {
    					limit: 8192
    					}
    				}]
    			}]
    		}
    

babel配置

npm install -D babel-loader @babel/core @babel/preset-env

// webpack.config.js配置
module: {
  rules: [
    {
      test: /\.m?js$/,
      // exclude: 排除
      // include: 包含
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
}

webpack使用vue配置

npm install vue --save
npm install vue-loader vue-template-compiler --save-dev

// 1. runtime-only -> 代码中,不可以有任何的template 2. runtime-compiler -> 代码中,可以有template,因为有compiler可以用于编译template
// webpack.config.js配置
resolve: {
    alias: {
        'vue$': 'vue/dist/vue.esm.js'
    }
}

Vue脚手架

初始化项目

// 2.0
vue init webpack my-project
// 3.0
vue create my-project

vue-router

  1. 基本使用

  2. 嵌套路由

  3. 参数传递

    params的类型:
        配置路由格式: /router/:id
        传递的方式: 在path后面跟上对应的值
        传递后形成的路径: /router/123, /router/abc
        this.$router.push('/user/' + this.userId)
    query的类型:
        配置路由格式: /router, 也就是普通配置
        传递的方式: 对象中使用query的key作为传递方式
        传递后形成的路径: /router?id=123, /router?id=abc
        this.$router.push({path: '/user', query: {
        	name: 'lizeyan',
        	age: 22,
        	height: 1.73
        }})
    
  4. 导航守卫

    // 挂载路由导航守卫
    router.beforeEach((to, from, next) => {
      // to: 将要访问的路径
      // from: 代表从哪个路径跳转而来
      // next: 是一个函数,表示放行
      // next() 放行   next('/login') 强制跳转
      if (to.path === '/login') return next()
      // 获取token
      const tokenStr = window.sessionStorage.getItem('token')
      if (!tokenStr) return next('/login')
      next()
    })
    
  5. keep-alive

    keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染,它们有两个非常重要的属性:

    1. include - 字符串或正则表达,只有匹配的组件会被缓存;

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

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

      <keep-alive exclude="Profile,User">
      	<router-view>
          	<!-- 所有路径匹配到的视图组件都会被缓存 --!>
          </router-view>
      </keep-alive>
      
  6. 懒加载

    // 方式一: 结合Vue的异步组件和Webpack的代码分析
    const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
    // 方式二: AMD写法
    const About = resolve => require(['../components/About.vue'], resolve);
    // 方式三: 在ES6中, 我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割
    const Home = () => import('../components/Home.vue')
    

r o u t e r 和 router和 routerroute区别

  1. r o u t e r 为 V u e R o u t e r 实 例 , 想 要 导 航 到 不 同 U R L , 则 使 用 router为VueRouter实例,想要导航到不同URL,则使用 routerVueRouterURL使router.push方法;
  2. $route为当前router跳转对象里面可以获取name、path、query、params等 。

Promise

Promise是异步编程的一种解决方案,它有三种状态:

  1. pending:等待状态,比如正在进行网络请求,或者定时器没有到时间;
  2. fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then();
  3. reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()。

Promise链式调用

  <script>
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('Hello World')
      }, 1000)
    }).then(data => {
      console.log(data);
      return data + '111'
    }).then(data => {
      console.log(data);
      return data + '222'
    }).then(data => {
      console.log(data);
      return Promise.reject(data + 'error')
    }).then(data => {
      // 这部分代码不执行
      console.log(data); 
      return data + '333'
    }).catch(data => {
      console.log(data);
      return data + '444'
    }).then(data => {
      console.log(data);
    });
  </script>

Promise.all()

  <script>
    Promise.all([
      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('result1')
        }, 2000)
      }),

      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('result2')
        }, 1000)
      })
    ]).then(results => {
      console.log(results);
    });
  </script>

vuex

vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享

使用vuex统一管理状态的好处:

  1. 能够在vuex中集中管理共享的数据,易于开发和后期维护;
  2. 能够高效的实现组件之间的数据共享,提高开发效率;
  3. 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步。
import { createStore } from 'vuex'

export default createStore({
  // 创建store数据源,提供唯一的公共数据,所有共享数据都要统一放到Store的State中进行存储
  state: {
    count: 0
  },
  // Mutations用于变更Store中的数据,不能在mutations执行异步操作
  mutations: {
    add(state) {
      state.count++
    },
    add(state, step) {
      state.count += step
    }
  },
  // 用于处理异步操作,通过触发mutations间接变更数据
  actions: {
  },
  modules: {
  }// 对store的数据加工
  getters: {  
  }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值