Vue技术栈

          • Vue的声明周期
            • 声明周期的函数
          • Vue中的指令
          • 计算属性
            • 计算属性复杂操作
          • 对象字面量增强写法
          • 条件判断
            • v-if的原理:
            • 案例小问题:
            • v-show和v-if的区别
          • 数组中响应式方法
          • JavaScript中的高阶函数
            • filter
            • map
            • reduce
          • v-model双向绑定
            • v-model原理
            • v-model的修饰符
          • 组件化开发
            • 父组件和子组件
            • 注册组件的语法糖格式
            • 父子组件间的通信
            • 父子组件的访问方式
          • slot插槽
            • 插槽的基本使用
            • 具名插槽的使用
            • 作用域插槽使用
          • webpack
            • loader
            • plugin
          • cli
            • runtime-compiler和runtime-only的区别
            • vue-cli3与2的区别:
          • 箭头函数
            • 箭头函数的基本使用
            • this的使用
          • vue-router
            • router-link
            • 路由的懒加载
            • 参数传递方式
          • TabBar
          • axios
            • axios中的并发:
            • 封装方式
          • Promise
            • promise的三种状态
            • Promise中all方法使用
          • Vuex
            • Vuex状态管理图例
            • 在mutations中改变数据
            • getters的使用

Vue的声明周期
声明周期的函数

Vue技术栈_第1张图片

Vue中的指令
  • v-once : 只渲染一次,不会随着数据的改变而改变

  • v-html : 会将string的HTML解析出来并且渲染

  • v-text : 接受一个string类型,将数据显示在界面中

  • v-pre : 跳过这个元素和它子元素的编译过程,用于显示本地的Mustache语法

  • v-bind:

    • 作用:动态绑定属性

    • 缩写为 : (语法糖的形式)

    • v-bind动态绑定class

      DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>classtitle>
      head>
      <style>
          .active {
              color: red;
          }
      style>
      <body>
          <div id="app">
              <h2 :class="active">{{ message }}h2>
              <h2 :class="{active: isActive}">{{ message }}h2>
          div>
      body>
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
      <script>
          const app = new Vue({
              el : '#app',
              data: {
                  message: "你好",
                  active: 'active',
                  isActive : true
              }
          })
      script>
      html>
      
    • v-bind动态绑定style

      DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>style动态绑定title>
      head>
      <body>
          <div id="app">
              <h2 :style="{'font-size' : finalSize}">{{ message }}h2>
          div>
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
      <script>
          const app = new Vue({
              el : '#app',
              data: {
                  message: "你好",
                  finalSize: '100px'
              }
          })
      script>
      body>
      html>
      
  • v-on:事件监听,比如点击,拖拽,键盘事件等等

    • 作用:绑定事件监听器

    • 缩写 @ (语法糖的形式)

    • 参数: event

      • 如果方法不需要参数,方法后的()可以不添加
      • 如果方法本身有一个参数,那么会默认将原生事件event参数传递进去
      • 如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件
    • 修饰符:Vue提供了修饰符来处理一些事件

      • .stop - 调用event.stopPropagation()
      • .prevent - 调用event.preventDefault()
      • .native - 监听组件根元素的原生事件
      • .once - 只触发一次回调
      DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>修饰符title>
      head>
      <body>
          <div id="app">
              
              <div @click="divClick">
                  aaaaa
                  <button @click.stop = "btnClick">点击button>
              div>
              
              <form action="baidu">
                  <input type="submit" value="提交" @click.prevent = "subClick"/>
              form>
              
              
              <input type="text" @keyup.enter="keyup">
              
              <button @click.once="onceClick">按钮button>
          div>
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
      <script>
          const app = new Vue({
              el: "#app",
              data: {
                  message: '你好呀'
              },
              methods: {
                  btnClick() {
                      console.log("btnClick");
                  },
                  divClick() {
                      console.log("divClick");
                  },
                  subClick() {
                      console.log("subClick");
                  },
                  keyup() {
                      console.log("keyup");
                  },
                  onceClick() {
                      console.log("onceClick");
                  }
              }
          })
      script>
      body>
      html>
      
计算属性
doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>计算属性title>
head>
<body>
    <div id="app">
        <h5>{{ fullName }}h5>
        <h5>{{ fullName }}h5>
        <h5>{{ fullName }}h5>
        <h5>{{ fullName }}h5>
    div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    const app = new Vue({
        el: '#app',

        data: {
            firsrName: '阿修罗',
            lastName: '剑圣'
        },
        computed: {
            fullName: function () {
                return this.firsrName + " " + this.lastName
            }
        }
    })
script>
body>
html>
计算属性复杂操作

setter和getter

<script>
    const app = new Vue({
        el: '#app',

        data: {
            firsrName: '阿修罗',
            lastName: '剑圣'
        },
        computed: {
            // fullName: function () {
            //     return this.firsrName + " " + this.lastName
            // }
            fullName: {
                set: function () {
                    
                },
                get: function () {
                    return this.firsrName + " " + this.lastName
                }
            }
        }
    })
script>
对象字面量增强写法

Vue技术栈_第2张图片

条件判断
v-if的原理:
  • v-if后面的条件为false时,对应的元素及其子元素不会被渲染
  • 也就是根本不会有对应的标签出现在DOM中
案例小问题:

切换类型发现文字依然显示之前的输入的内容.

问题解答:因为在Vue进行渲染时,出于性能考虑,会尽可能的复用已经存在的元素.而不是创建新的元素

解决方案:不希望使用Vue出现类似重复使用的问题,可以给对应的input添加key,并且需要保持key的不同

v-show和v-if的区别
  • v-if当条件为false时,压根不会有对应的元素在DOM中.
  • v-show当条件为false时,仅仅是将元素的display属性设置为none而已

开发中如何选择:

  • 当需要在显示和隐藏之间切换的很频繁时,使用v-show
  • 当只有一次切换时,通过使用v-if
数组中响应式方法
  • push() : 在数组的结尾加入值
  • pop() : 删除数组中的最后一个元素
  • shift() : 删除数组中的第一个元素
  • unshift() : 在数组最前面加入元素
  • splice() : 删除元素/插入元素/替换元素
  • sort() : 排序
  • reserve () : 反转
JavaScript中的高阶函数
filter
const nums = [10, 20, 30, 50, 666, 7]
let newNums = nums.filter(function (n) {
	return n < 100
})
console.log(newNums)
  • filter中的回调函数有一个要求,必须返回一个boolean值
  • true : 当返回true时,函数内部会自动将这次回调的n加入到新的数组中
  • false: 当返回false时, 函数内部会过滤这次的n
map
reduce

对数组的内容进行汇总

v-model双向绑定
v-model原理

v-model其实是一个语法糖,它的背后本质包含两个操作:

  • v-bind绑定一个value时间
  • v-on指令给当前元素绑定input事件
<input type="text" v-model="message">

<input type="text" v-bind="message" v-on:input="message = $event.target.value">
v-model的修饰符

lazy修饰符

  • 默认情况下,v-model默认是在input事件中同步输入框的数据的
  • lazy修饰符可以让数据在失去焦点或者是回车时才会更新

number修饰符

  • 默认情况下,在输入框中无论输入的书数字还是字母,都会被当作字符串来进行处理
  • number修饰符可以让在输入框中输入的内容自动转换为数字类型

trim修饰符

  • 如果输入的内容收尾有很多的空格,通常我们希望将其去除
  • trim修饰符可以过滤内容左右边的空格
组件化开发

组件化的基本使用

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件的使用title>
head>
<body>
    <div id="app">
        <my>my>
    div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    // 创建组件构造器
    const myComponent = Vue.extend({
        template:
            `

组件标题

组件中的一段内容

`
}); // 注册组件 Vue.component('my', myComponent); const app = new Vue({ el: "#app" })
script> body> html>
父组件和子组件
<script>
    const comC1 = Vue.extend({
        template:
            `
        

阿修罗

今天的天气很好

`
}); const comC2 = Vue.extend({ template: `

子组件

子组件注册完成

`
, components: { com1: comC1 } }); const app = new Vue({ el: "#app", components: { com2: comC2 } }) </script>
注册组件的语法糖格式
<script>
    const comC2 = Vue.extend({
        template:
        `
         

子组件

子组件注册完成

`
, components: { "com1": { template: `

阿修罗

今天的天气很好

`
} } }); const app = new Vue({ el: "#app", components: { com2: comC2 } })
script>
父子组件间的通信

父子组件之间的通信:

  • 通过props向子组件传递数据
  • 通过事件向父组件发送信息

props基本用法:

props的值有两种方式:

  • 方式一:字符串数组,数组中的字符串就是传递的名称.
  • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父组件向子组件传递数据title>
head>
<body>
    <div id="app">
        <tem v-bind:cmessage="message" :cmovies="movies">tem>
    div>
<template id="tem">
    <div>
        <h2>{{ cmessage }}h2>
        <ul>
            <li v-for="movie in cmovies">{{ movie }}li>
        ul>
    div>
template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            message: "阿修罗",
            movies: ["异星灾难", "三体", "权利的游戏"]
        },
        components: {
            "tem" : {
                template: "#tem",
                // 以数组的方式传递
                // props: ["cmessage", "cmovies"]
                props: {
                    // 类型限制
                    // cmessage: String,
                    // cmovies: Array

                    // 提供一些默认值
                    cmessage: {
                        type: String,
                        default: "没有传值",
                        required: true

                    },
                    cmovies: {
                        type: Array,
                        default: ["西游记", "三国演义", "水浒传"],
                        required: true
                    }
                }
            }
        }
    })

script>
body>
html>

子组件向父组件传递数据:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>子组件向父组件传递数据title>
head>
<body>
    <div id="app">
        <cpn @itemclick="cpnClick">cpn>
    div>
<template id="cpn">
    <div>
        <button v-for="item in categories"
                @click="btnClick(item)">
            {{ item.name }}
        button>
    div>
template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    const cpn = {
        template: "#cpn",
        data() {
            return {
                categories: [
                    {id: "aaa", name: "热门推荐"},
                    {id: "bbb", name: "手机数码"},
                    {id: "ccc", name: "家用家电"},
                    {id: "ddd", name: "电脑办公"}
                ]
            }
        },
        methods: {
            btnClick(item) {
                this.$emit('itemclick', item)
            }
        }
    }
    const app = new Vue({
        el: "#app",
        data: {

        },
        methods: {
            cpnClick(item) {
                console.log("cpnClick", item);
            }
        },
        components: {
            cpn
        }
    })
script>
body>
html>
父子组件的访问方式

访问方式:

  • 父组件访问子组件: 使用$children或者是refs

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>父组件访问子组件title>
    head>
    <body>
        <div id="app">
            <cpn ref="aaa">cpn>
            <cpn ref="cpn">cpn>
            <button @click="btnClick">点击出现button>
        div>
    <template id="tem">
        <div>我是子组件div>
    template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
    <script>
        const app = new Vue({
            el: "#app",
            methods: {
                btnClick() {
                    // console.log(this.$children);
                    // console.log(this.$children[0].showMessage);
                    console.log(this.$refs.aaa);
                }
            },
            components: {
                cpn: {
                    template: "#tem",
                    methods: {
                        showMessage() {
                            console.log("showMessage");
                        }
                    }
                }
            }
        })
    script>
    body>
    html>
    
  • 子组件访问父组件: 使用$parent(不建议使用)

slot插槽
插槽的基本使用
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div id="app">
    <cpn>cpn>
    <cpn><button>新加按钮button>cpn>
    <cpn><span>天气span>cpn>
    <cpn>
        <div>阿修罗div>
    cpn>
div>
<template id="tem">
    <div>
        <h2>哈哈h2>
        <slot><button>默认按钮button>slot>
    div>
template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    const app = new Vue({
        el: "#app",
        components: {
            cpn: {
                template: "#tem"
            }
        }
    })
script>
body>
html>
具名插槽的使用
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div id="app">
    <cpn><span slot="right">替换右边span>cpn>
    <cpn><span slot="center">替换中间span>cpn>
div>
<template id="tem">
    <div>
       <slot name="left">左边slot>
       <slot name="center">中间slot>
       <slot name="right">右边slot>
    div>
template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    const app = new Vue({
        el: "#app",
        components: {
            cpn: {
                template: "#tem"
            }
        }
    })
script>
body>
html>
作用域插槽使用
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div id="app">
    <cpn>
        <template slot-scope="slot">
            <span>{{ slot.data.join("-")}}span>
        template>
    cpn>
    <cpn>
        <template slot-scope="slot">
            <span>{{ slot.data.join("*")}}span>
        template>
    cpn>
div>
<template id="tem">
    <div>
        <slot :data="pLanguage">
            <ul>
                <li v-for="item in pLanguage">{{ item }}li>
            ul>
        slot>
    div>
template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    const app = new Vue({
        el: '#app',
        components: {
            cpn: {
                template: '#tem',
                data() {
                    return {
                        pLanguage: ["JavaScript", "C#", "java", "Go"]
                    }
                }
            }
        }
    })
script>
body>
html>
webpack

npm管理node下的各种包

loader

webpack用来做什么?

  • 在我们之前的实例中,我们主要使用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖
  • 但是在开发中不仅仅有基本的js代码处理,也需要加载css、图片、也包括一些高级的将ES6转成ES5代码,将Typescript转成ES5代码,将less转成css,将.jsx .vue 转成js文件
  • 对于webpack本身来说这些转化是不支持的

loader的使用过程:

  • 通过npm安装需要使用的loader
  • 在webpack.config.js中的modules关键字下进行配置
plugin

使用步骤:

  • 通过npm安装需要的plugins
  • 在webpack.config.js中的plugins中配置插件
cli
runtime-compiler和runtime-only的区别

runtime-compiler的渲染过程:

template -> ast -> render -> vdom -> UI

runtime-only的渲染过程:

render -> vdom -> UI

vue-cli3与2的区别:
  • vue-cli3是基于webpack4打造
  • vue-cli3的设计原则是零配置,移除的配置文件根目录下的build和config等目录
  • vue-cli3提供了vue ui命令,提供了可视化视图,更加人性化
  • 移除了static文件夹,新增了public文件夹,并且index.html移动到public中
箭头函数
箭头函数的基本使用
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>箭头函数title>
head>
<body>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    // 参数问题
    // 两个参数
    const sum = (num1, num2) => {
        return num2 + num1
    }

    // 一个参数
    const power = num => {
        return num * num
    }

    // 返回值问题
    // 函数代码块中只有一行代码
    const mul = (num1, num2) => num1 * num2
    console.log(mul(20, 30));

    const demo = () => console.log("Hello World")
    console.log(demo());
script>
body>
html>
this的使用
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this的使用title>
head>
<body>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    const obj = {
        aaa() {
            setTimeout(function () {
                setTimeout(function (){
                    console.log(this)  // this
                })

                setTimeout(() => {
                    console.log(this)  // this
                })
            })
            setTimeout(() => {
                setTimeout(function () {
                    console.log(this)  // this
                })

                setTimeout(() => {
                    console.log(this)  // obj
                })
            })
        }
    }
    obj.aaa()
script>
body>
html>
vue-router

步骤一:安装vue-router

npm install vue-router --save

步骤二:

  • 导入路由对象,并且调用Vue.use(VueRouter)
  • 创建路由实例,并且传入路由映射配置
  • 在Vue实例中挂载创建的路由实例
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

步骤三:

  • 创建路由组件
  • 配置路由映射:组件和路径映射关系
  • 使用路由:通过和
router-link

router-link的一些其他属性:

  • tag:可以指定之后渲染成什么组件,比如默认会被渲染成
  • replace:repalce不会留下history记录,在指定replace的情况下,后退键返回不能返回到上一个页面中
  • active-router:当对应的路由匹配成功会自动给当前元素设置一个router-link-active的class
路由的懒加载
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      // 重定向
      redirect: '/Home'
    },
    {
      path: '/home',
      name: 'Home',
      // 路由的懒加载
      component: () => import("../components/Home")
    },
    {
      path: '/about',
      name: 'About',
      // 路由懒加载
      component: () => import("../components/About")
    },
    {
      path: '/user/:userId',
      name: 'User',
      // 路由懒加载
      component: () => import("../components/User")
    }
  ],
  // 将默认的hash模式改为history模式
  mode: 'history'
})

参数传递方式

params类型

  • 配置路由的格式: /router/:id
  • 传递的方式:在path后面跟上对应的值
  • 传递后形成的路径:/router/123,/router/abc

query类型

  • 配置格式:/router.也就是普通配置
  • 传递的方式:对象中使用query的key作为传递方式
  • 传递后形成的路径:/router?id=123
TabBar
axios
axios中的并发:
axios.all([axios({
    url: ""
}),axios({
    url: "",
    params: {
        
    }
})]).then(res => {
    
})
封装方式

方式一

export function request(config) {
  return new Promise((resolve, reject) => {
    const instance =  axios.create({
      baseURL: "",
      timeout: 5000
    })
    return instance(config)
  })
}

方式二:

export function request(config) {
  return new Promise((resolve, reject) => {
     const instance =  axios.create({
      baseURL: "",
      timeout: 5000
    })
    instance(config)
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}
Promise

什么情况下可以用到?

一般情况下有异步操作时,使用Promise对操作进行封装

    new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, 2000)
    }).then(() => {
        console.log("hello world");
        console.log("hello world");
        console.log("hello world");

        return new Promise((resolve, reject) => {

            setTimeout(() => {
                resolve()
            }, 2000)
        }).then(() => {
            console.log("hello world");
            console.log("hello world");
            console.log("hello world");
        })
    })
promise的三种状态
  • pending:等待状态,比如正在进行网络请求,或者是定时器没有到时间
  • fulfill:满足状态,当我们主动调用resolve时,就处于该状态,并调用then()
  • reject:拒绝状态,当我们主动调用reject时,就处于该状态并且会调用catch
Promise中all方法使用
    Promise.all([
        new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({name: "张三", age: 18})
            }, 2000)
        }),
        new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({name: "kobe", age: 19})
            }, 1000)
        })
    ]).then(results => {
        console.log(results);
    })
Vuex

Vue技术栈_第3张图片

  • state:驱动应用的数据源
  • view:以声明方式将state映射到视图
  • actions:响应在view上的用户输入导致的状态变化
Vuex状态管理图例

Vue技术栈_第4张图片

在mutations中改变数据
import Vue from "vue"
import Vuex from "vuex"

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    counter: 1000
  },
  mutations: {
    // 定义方法
    increment(state) {
      state.counter ++
    },
    decrement(state) {
      state.counter --
    },
    // mulations特殊的提交风格
    incrementCount(state, payload) {
        state.counter += payload.count
    }
  },
  actions: {},
  getters: {},
  modules: {}
})

export default store



getters的使用
import Vue from "vue"
import Vuex from "vuex"

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    counter: 1000,
    students: [
      {id: 1001, name: "hary", age: 18},
      {id: 1002, name: "why", age: 19},
      {id: 1003, name: "koba", age: 20},
      {id: 1003, name: "curry", age: 21}
    ]
  },
  mutations: {
    // 定义方法
    increment(state) {
      state.counter ++
    },
    decrement(state) {
      state.counter --
    }
  },
  actions: {},
  getters: {
    powerCounter(state) {
      return state.counter * state.counter
    },
    getAgeMore20Stu(state) {
      // return state.students.filter((s) => {
      //   return s.age > 20
      // })
      return state.students.filter((s => s.age > 20))
    },
    getStuLength(state, getters) {
      return getters.getAgeMore20Stu.length
    }
  },
  modules: {}
})

export default store

你可能感兴趣的:(vue,vue,javascript,前端)