vue基础语法

vue基础语法

V-once

元素只渲染一次,不会随着数据改变而改变
<h2 v-once>{{message}}</h2>

v-html

按照html格式解析
<div id="app">
  <h2>{{url}}</h2>//结果是<a href="http://www.baidu.com">百度一下</a>
  <h2 v-html="url"></h2>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊",
      url: "<a href="http://www.baidu.com">百度一下</a>"
    }
  })
</script>

v-text

和mustache一样
<div id="app">
  <h2>{{message}}, 李银河!</h2>
  <h2 v-text="message">, 李银河!</h2>
</div>

v-pre

<div id="app">
  <h2>{{message}}</h2>
  <h2 v-pre>{{message}}</h2>//直接显示message
</div>

v-cloak

  <style>
    [v-cloak] {
      display: none;
    }
  </style>
</head>
<body>

<div id="app" v-cloak>
  <h2>{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
  // 在vue解析之前, div中有一个属性v-cloak
  // 在vue解析之后, div中没有一个属性v-cloak
  //vue来不及渲染,直接显示源代码,加这个属性就行
  

绑定属性

v-bind

<img :src="imgURL" alt="">
<a :href="aHref">百度一下</a>
//图片的链接src、网站的链接href、动态绑定一些类、样式

<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊",
      imgURL: "https://img11.360buyimg.com/mobilecms/s350x250_jfs/t1/20559/1/1424/73138/5c125595E3cbaa3c8/74fc2f84e53a9c23.jpg!q90!cc_350x250.webp",
      aHref: "http://www.baidu.com"
    }
  })
</script>
  <h2 class="title" v-bind:class="{active: isActive}">{{message}}</h2>
  <h2 class="title" v-bind:class="getClasses()">{{message}}</h2>

	<h2 class="title" :class="[active]">{{message}}</h2>

  <button v-on:click="btnClick">按钮</button>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊",
      isActive: true,
    },
    methods: {
      btnClick: function () {
        this.isActive = !this.isActive
      },
      getClasses: function () {
        return {active: this.isActive}
      }
    }
  })
</script>

:style

  <h2 :style="{fontSize: finalSize + "px", backgroundColor: finalColor}">{{message}}</h2>
  <h2 :style="getStyles()">{{message}}</h2>
<div id="app">
  <h2 :style="[baseStyle, baseStyle1]">{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊",
      baseStyle: {backgroundColor: "red"},
      baseStyle1: {fontSize: "100px"},
    }
  })
</script>

计算属性

计算属性和methods的区别:

计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。

computed: {
      // fullName: function () {
      //   return this.firstName + " " + this.lastName
      // }
      // name: "coderwhy"
      // 计算属性一般是没有set方法, 只读属性.
      fullName: {
        set: function(newValue) {
          // console.log("-----", newValue);
          const names = newValue.split(" ");
          this.firstName = names[0];
          this.lastName = names[1];
        },
        get: function () {
          return this.firstName + " " + this.lastName
        }
      },
}

事件监听

参数问题

<div id="app">
  <!--1.事件调用的方法没有参数-->
  <button @click="btn1Click()">按钮1</button>
  <button @click="btn1Click">按钮1</button>

  <!--2.在事件定义时, 写方法时省略了小括号, 但是方法本身是需要一个参数的, 这个时候, Vue会默认将浏览器生产的event事件对象作为参数传入到方法-->
  <!--<button @click="btn2Click(123)">按钮2</button>-->
  <!--<button @click="btn2Click()">按钮2</button>-->
  <button @click="btn2Click">按钮2</button>

  <!--3.方法定义时, 我们需要event对象, 同时又需要其他参数-->
  <!-- 在调用方式, 如何手动的获取到浏览器参数的event对象: $event-->
  <button @click="btn3Click(abc, $event)">按钮3</button>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊",
      abc: 123
    },
    methods: {
      btn1Click() {
        console.log("btn1Click");
      },
      btn2Click(event) {
        console.log("--------", event);
      },
      btn3Click(abc, event) {
        console.log("++++++++", abc, event);
      }
    }
  })

  // 如果函数需要参数,但是没有传入, 那么函数的形参为undefined
  // function abc(name) {
  //   console.log(name);
  // }
  //
  // abc()
</script>

修饰符

<div id="app">
  <!--1. .stop修饰符的使用-->
  <div @click="divClick">
    aaaaaaa
    <button @click.stop="btnClick">按钮</button>
  </div>

  <!--2. .prevent修饰符的使用-->
  <br>
  <form action="baidu">
    <input type="submit" value="提交" @click.prevent="submitClick">
  </form>

  <!--3. .监听某个键盘的键帽-->
  <input type="text" @keyup.enter="keyUp">

  <!--4. .once修饰符的使用-->
  <button @click.once="btn2Click">按钮2</button>
</div>

条件判断

key的问题

//切换类型后还会保留原来的内容,因为vue在进行dom渲染时,会复用存在的元素,而不是创建新的元素,添加不同的可以就能解决这个问题
<div id="app">
  <span v-if="isUser">
    <label for="username">用户账号</label>
    <input type="text" id="username" placeholder="用户账号" >
  </span>
  <span v-else>
    <label for="email">用户邮箱</label>
    <input type="text" id="email" placeholder="用户邮箱" >
  </span>
  <button @click="isUser = !isUser">切换类型</button>
</div>
<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="email">用户邮箱</label>
    <input type="text" id="email" placeholder="用户邮箱" key="email">
  </span>
  <button @click="isUser = !isUser">切换类型</button>
</div>

v-if和v-show的区别

v-if:条件为false,不会存在dom中

v-show:条件为false,会添加行内样式display:none

循环遍历

遍历数组

<div id="app">
  <!--1.在遍历的过程中,没有使用索引值(下标值)-->
  <ul>
    <li v-for="item in names">{{item}}</li>
  </ul>

  <!--2.在遍历的过程中, 获取索引值-->
  <ul>
    <li v-for="(item, index) in names">
      {{index+1}}.{{item}}
    </li>
  </ul>
</div>

遍历对象

<div id="app">
  <!--1.在遍历对象的过程中, 如果只是获取一个值, 那么获取到的是value-->
  <ul>
    <li v-for="item in info">{{item}}</li>
  </ul>


  <!--2.获取key和value 格式: (value, key) -->
  <ul>
    <li v-for="(value, key) in info">{{value}}-{{key}}</li>
  </ul>


  <!--3.获取key和value和index 格式: (value, key, 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: "why",
        age: 18,
        height: 1.88
      }
    }
  })
</script>

遍历时添加key

//可以高效更新虚拟dom
<ul>
    <li v-for="item in letters" :key="item">{{item}}</li>
  </ul>

检查数组更新

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
// 1.push方法
        // this.letters.push("aaa")
         this.letters.push("aaaa", "bbbb", "cccc")

        // 2.pop(): 删除数组中的最后一个元素
         this.letters.pop();

        // 3.shift(): 删除数组中的第一个元素
         this.letters.shift();

        // 4.unshift(): 在数组最前面添加元素
        // this.letters.unshift()
         this.letters.unshift("aaa", "bbb", "ccc")

        // 5.splice作用: 删除元素/插入元素/替换元素
        // 删除元素: 第二个参数传入你要删除几个元素(如果没有传,就删除后面所有的元素)
        // 替换元素: 第二个参数, 表示我们要替换几个元素, 后面是用于替换前面的元素
        // 插入元素: 第二个参数, 传入0, 并且后面跟上要插入的元素
        // splice(start)
        // splice(start):
				
				//第二个参数:不传=删除后面所有,传3=替换3个,传0=插入的元素
        this.letters.splice(1, 3, "m", "n", "l", "x")
        // this.letters.splice(1, 0, "x", "y", "z")

        // 5.sort()
         this.letters.sort()

        // 6.reverse()
         this.letters.reverse()

        // 注意: 通过索引值修改数组中的元素
        // this.letters[0] = "bbbbbb";
        // this.letters.splice(0, 1, "bbbbbb")
        // set(要修改的对象, 索引值, 修改后的值)
        // Vue.set(this.letters, 0, "bbbbbb")

双向绑定

v-model的原理

首先需要实时获取数据,那么就需要:vlalue.
然后修改数据时,同步到data.那么就需要@input方法实时把数据发到data
<div id="app">
  <!--<input type="text" v-model="message">-->
  <input type="text" :value="message" @input="valueChange">
  <!-- <input type="text" :value="message" @input="message = $event.target.value"> -->
  <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>

修饰符

<div id="app">
  <!--1.修饰符: lazy-->
  <input type="text" v-model.lazy="message">
  <h2>{{message}}</h2>


  <!--2.修饰符: number-->
  <input type="number" v-model.number="age">
  <h2>{{age}}-{{typeof age}}</h2>

  <!--3.修饰符: trim-->
  <input type="text" v-model.trim="name">
  <h2>您输入的名字:{{name}}</h2>
</div>

组件化开发

步骤解析

  1. Vue.extend()创建一个组件构造器,同时传入自定义组件模板
  2. Vue.component()注册组件,并给他起一个标签名.所以需要传组件构造器和标签名
  3. 挂载Vue的实例下,否则不会生效

组件数据返回值

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>当前计数: {{counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  // 1.注册组件
  const obj = {
    counter: 0
  }
  Vue.component("cpn", {
    template: "#cpn",
    // data() {
    //   return {
    //     counter: 0
    //   }
    // },
    data() {
      return obj
    },
    methods: {
      increment() {
        this.counter++
      },
      decrement() {
        this.counter--
      }
    }
  })

  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊"
    }
  })
</script>

props基本用法

//在这里传值,message是父组件的数据对象
<cpn :cmessage="message" :cmovies="movies"></cpn>


//数组中的字符串就是传递时的名称
props: ["cmovies", "cmessage"]
  
//这种可以设置默认值,类型
props: {
      // 1.类型限制
      // cmovies: Array,
      // cmessage: String,

      // 2.提供一些默认值, 以及必传值
      cmessage: {
        type: String,
        default: "aaaaaaaa",
        required: true
      },
      // 类型是对象或者数组时, 默认值必须是一个函数
      cmovies: {
        type: Array,
        default() {
          return []
        }
      }
}

子组件向父组件传值

自定义事件流程
1.在子组件通过$emit()来触发事件
2.在父组件通过v-on来监听子组件的事件
<!--父组件模板-->
<div id="app">
  <cpn @item-click="cpnClick"></cpn>
</div>

<!--子组件模板-->
<template id="cpn">
  <div>
    <button v-for="item in categories"
            @click="btnClick(item)">
      {{item.name}}
    </button>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>

  // 1.子组件
  const cpn = {
    template: "#cpn",
    data() {
      return {
        categories: [
          {id: "aaa", name: "热门推荐"},
          {id: "bbb", name: "手机数码"},
          {id: "ccc", name: "家用家电"},
          {id: "ddd", name: "电脑办公"},
        ]
      }
    },
    methods: {
      btnClick(item) {
        // 发射事件: 自定义事件
        this.$emit("item-click", item)
      }
    }
  }

  // 2.父组件
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊"
    },
    components: {
      cpn
    },
    methods: {
      cpnClick(item) {
        console.log("cpnClick", item);
      }
    }
  })
</script>

组件访问

<div id="app">
  <cpn></cpn>
  <cpn></cpn>

  <cpn ref="aaa"></cpn>
  <button @click="btnClick">按钮</button>
</div>

<template id="cpn">
  <div>我是子组件</div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊"
    },
    methods: {
      btnClick() {
        // 1.$children
        console.log(this.$children);
        for (let c of this.$children) {
          console.log(c.name);
          c.showMessage();
        }

        // 2.$refs => 对象类型, 默认是一个空的对象 ref="bbb"
        console.log(this.$refs.aaa.name);
      }
    },
    components: {
      cpn: {
        template: "#cpn",
        data() {
          return {
            name: "我是子组件的name"
          }
        },
        methods: {
          showMessage() {
            console.log("showMessage");
          }
        }
      },
    }
  })
</script>
//子组件访问父组件
//不推荐使用,耦合太高了

// 1.访问父组件$parent
 console.log(this.$parent);
 console.log(this.$parent.name);

// 2.访问根组件$root
console.log(this.$root);
console.log(this.$root.message);

插槽slot

封装原则:保留共性,将不同暴露为插槽

  • 如果有多个值, 同时放入到组件进行替换时, 一起作为替换元素

插槽作业域

父组件替换插槽的标签,内容由子组件提供

<div id="app">
  <cpn></cpn>

  <cpn>
    <!--目的是获取子组件中的pLanguages-->
    <template slot-scope="slot">
      <!-- <span v-for="item in slot.data"> - {{item}}</span> -->
      <!-- <span>{{slot.data.join(" - ")}}</span> -->
    </template>
  </cpn>

</div>

<template id="cpn">
  <div>
    <slot :data="pLanguages">
      <ul>
        <li v-for="item in pLanguages">{{item}}</li>
      </ul>
    </slot>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: "你好啊"
    },
    components: {
      cpn: {
        template: "#cpn",
        data() {
          return {
            pLanguages: ["JavaScript", "C++", "Java", "C#", "Python", "Go", "Swift"]
          }
        }
      }
    }
  })
</script>

Webpack

导入

// 1.使用commonjs的模块化规范
const {add, mul} = require("./js/mathUtils.js")

console.log(add(20, 30));
console.log(mul(20, 30));

// 2.使用ES6的模块化的规范
import {name, age, height} from "./js/info";

console.log(name);
console.log(age);
console.log(height);

// 3.依赖css文件
require("./css/normal.css")

Vue-router

history.pushStath({},"","/home")  //有历史记录
historyreplaceState({},"","/foo/bar")	//没历史记录

history.back() 等价于 history.go(-1)
history.forward() 则等价于 history.go(1)

使用vue-router步骤

  1. 创建router实例并挂载到vue实例中
  2. 创建路由组件
  3. 配置路由映射关系:组件和路径的映射关系
  4. 使用路由:通过<router-link>和<router-view>
router实例
import VueRouter from "vue-router"
import Vue from "vue"

import Home from "../components/Home"
import About from "../components/About"

//注入插件
Vue.use(VueRouter)

//定义路由
const routes =[
  {path:"",redirect:"/home"},
  {path:"/home",component:Home},
  {path:"/about",component:About}
]

//创建router实例
const router = new VueRout({
  routes,
  mode:"history",
  linkActiveClass:"active"
})
export default router
挂载到vue实例中
import Vue from "vue"
import App from "./App"
import router from "./router"

new Vue({
  el:"#app",
  router,
  render:h=>h(App)
})
使用路由
<template>
  <div id="app">
    <router-link to="/home">首页</router-link>
		<router-link to="/about">关于</router-link>
		<router-view></router-view>
		//可以用这种方法替代组件
		//<button @click="homeClick">首页</button>
    //<button @click="aboutClick">关于</button>
	</div>
</template>

export default{
  name:"App",
  methods:{
    homeClick(){
      //相当于pushstate
      this.$router.push("/home")
    },
    aboutClick(){
      this.$router.replace("/about")
    }
  }
}

router-link

tag: tag可以指定<router-link>之后渲染成什么组件, 比如上面的代码会被渲染成一个<li>元素, 而不是<a>
replace: replace不会留下history记录, 所以指定replace的情况下, 后退键返回不能返回到上一个页面中
active-class: 当<router-link>对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active的class

		<router-link to="/home" tag="button" replace active-class="active">首页</router-link>
    <router-link to="/about" tag="button" replace active-class="active">关于</router-link>

动态路由

//router
routes这么配置
{
    path: "/user/:id",
    component: User,
    meta: {
      title: "用户"
    },
},
//地址这么写
<router-link to="/user/123">用户</router-link>
//路由对应的组件
<h2>{{userId}}</h2>

<h2>{{$route.params.id}}</h2>

//这样也行

computed: {
      userId() {
        return this.$route.params.id
      }
},

路由懒加载

//在router这么导入组件
const Home = () => import("../components/Home")

嵌套路由

步骤

  1. 创建子组件,并在路由映射中配置
  2. 在组件内部使用<router-view>标签
{
    path: "/home",
    component: Home,
    meta: {
      title: "首页"
    },
    children: [
      //可以配置默认路由
      // {
      //   path: "",
      //   redirect: "news"
      // },
      {
        path: "news",
        component: HomeNews
      },
      {
        path: "message",
        component: HomeMessage
      }
    ]
},
home组件
<router-link to="/home/news">新闻</router-link>
<router-link to="/home/message">消息</router-link>

<router-view></router-view>

传递参数

params的类型:

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

query的类型:

配置路由格式: /router, 也就是普通配置 传递的方式: 对象中使用query的key作为传递方式 传递后形成的路径: /router?id=123, /router?id=abc

<router-link :to=""/user/"+userId">用户</router-link>

<router-link :to="{path: "/profile", query: {name: "why", age: 18, height: 1.88}}">
js方式
profileClick() {
      this.$router.push({
        path: "/profile",
        query: {
          name: "kobe",
          age: 19,
          height: 1.87
        }
      })
}

获取参数

获取参数是通过$route对象获取

<h2>{{$route.query.name}}</h2>
<h2>{{$route.query.age}}</h2>
<h2>{{$route.query.height}}</h2>

<h2>{{$route.params.id}}</h2>

route和router区别

route可以获取name,path,query,params等

routers vueRouter的实例,导航到不同的URL就用$router.push()方法

导航守卫

导航钩子的三个参数解析: to: 即将要进入的目标的路由对象. from: 当前导航即将要离开的路由对象. next: 调用该方法后, 才能进入下一个钩子.

可以利用beforeEach来完成标题的修改

步骤

  1. 在路由中添加标题
  2. 利用导航守卫修改标题
  {
    path: "/about",
    component: About,
    meta: {
      title: "关于"//在这定义标题
    },
    beforeEnter: (to, from, next) => {	//创建路由独享守卫
      // console.log("about beforeEnter");
      next()
    }
  },
// 前置守卫(guard)
router.beforeEach((to, from, next) => {
  document.title = to.matched[0].meta.title//修改标题
  // console.log("执行完这行就执行afterEach方法");
  next()
})
// 后置钩子(hook)不需要主动调用next()函数.
router.afterEach((to, from) => {
  // console.log("----");
})

Keep-alive

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

//include - 字符串或正则表达,只有匹配的组件会被缓存
//exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
<keep-alive exclude="Profile,User">//不要随便加空格
      <router-view/>
</keep-alive>

Promise

//普通方式
new Promise((resolve,reject){
    setTimeout(()=>{
      //成功执行resolve
      resolve("Hello World")
      //失败执行reject
      reject("error message")
    })
}).then((data)=>{
  //处理代码
  conssole.log(data)
}).catch((err)=>{
  //错误时执行这里
  console.log(err)
})
//另外一种方式,resolve和reject写在then里
new Promise((resolve,reject)){
  setTimeout(()=>{
    //正确时执行
    resolve("Hello")
    //错误时执行
    reject("error")
  },1000)
  
}.then(data=>{
  console.log(data)
},err=>{
  console.log(err)
})
//链式编程
new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("aaa")
    }, 1000)
  }).then(res => {
    // 1.自己处理10行代码
    console.log(res, "第一层的10行处理代码");
  
    // 2.对结果进行第一次处理
    return new Promise((resolve, reject) => {
      // resolve(res + "111")
      reject("err")
    })
  }).then(res => {
    console.log(res, "第二层的10行处理代码");
  
    return new Promise(resolve => {
      resolve(res + "222")
    })
  }).then(res => {
    console.log(res, "第三层的10行处理代码");
  }).catch(err => {
    console.log(err);
  })
//普通写法
return new Promise((resolve,reject)=>{
	resolve(res+"111")
})

//缩写
return Promise.resolve(res+"111")

//省略
return res+"111"

异步操作

普通方式
1. 发送对象
	a.对象里携带参数信息
	b.成功执行的方法
2.action里发起async

//组件方法
updateInfo() {

  this.$store.dispatch("aUpdateInfo", {
    message: "我是携带的信息",
    success: () => {
      console.log("里面已经完成了");
    }

}
                       
//action方法
 aUpdateInfo(context, payload) {
    setTimeout(() => {
      context.commit("updateInfo")
      console.log(payload.message);
      payload.success()
    }, 1000)
  }                      



promise方式
1.发送参数信息
2.action返回promise对象
	a.promise对象里发起async
3.在组件执行then方法

//组件方法
updateInfo() {

  this.$store
  .dispatch("aUpdateInfo", "我是携带的信息")
  .then(res => {
    console.log("里面完成了提交");
    console.log(res);
  })

}
                       
//action方法                                      
aUpdateInfo(context, payload) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        context.commit("updateInfo");
        console.log(payload);

        resolve("1111111")
      }, 1000)
    })
  }

all方法

Promise.all([

    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({name: "why", age: 18})
      }, 2000)
    }),
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({name: "kobe", age: 19})
      }, 1000)
    })
]).then(results => {
  console.log(results);
})

VueX

核心概念

  • State
  • getters
  • Mutation
  • action
  • module

getters

//普通写法
powerCounter(state) {
    return state.counter * state.counter
}
//传参数写法
//在组件中这么写
<h2>{{$store.getters.moreAgeStu(12)}}</h2>
//getters这么写
moreAgeStu(state) {
    // return function (age) {
    //   return state.students.filter(s => s.age > age)
    // }
    return age => {
      return state.students.filter(s => s.age > age)
    }
}

mutation

//不传参数写法
//在组件这么写方法
subtraction() {
  this.$store.commit("decrement")
}
//在mutation这么写
decrement(state) {
    state.counter--
}
//传参数写法
//在组件中这么写方法
addCount(count) {
  // payload: 负载
  // 1.普通的提交封装
  //这么写,payload就是参数
  // this.$store.commit("incrementCount", count)

  // 2.特殊的提交封装
  //如果这么写,mutation要拿到参数需要payload.参数
  this.$store.commit({
    type: "incrementCount",
    count
  })
},
  
//在mutation中这么写
incrementCount(state, payload) {
    // console.log(count);
    state.counter += payload.count
  },

响应规则

//可以实时响应
Vue.set(state.info, "address", "洛杉矶")
Vue.delete(state.info, "age")


//不可以实时响应
state.info["address"] = "洛杉矶"
delete state.info.age

action

没参数

//调用action方法,在组件中这么写
asyncUpdateName() {
  this.$store.dispatch("aUpdateName")
}
//action方法
aUpdateName(context) {
      console.log(context);
      setTimeout(() => {
        context.commit("updateName", "wangwu")
      }, 1000)
}

有参数时

//有参数
//在组件这么写
updateInfo() {
        // this.$store.dispatch("aUpdateInfo", {
        //   message: "我是携带的信息",
        //   success: () => {
        //     console.log("里面已经完成了");
        //   }
        // })
        this.$store
          .dispatch("aUpdateInfo", "我是携带的信息")
          .then(res => {
            console.log("里面完成了提交");
            console.log(res);
          })
  }
//在action这么写

  // aUpdateInfo(context, payload) {
  //   setTimeout(() => {
  //     context.commit("updateInfo")
  //     console.log(payload.message);
  //     payload.success()
  //   }, 1000)
  // },
  aUpdateInfo(context, payload) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        context.commit("updateInfo");
        console.log(payload);

        resolve("1111111")
      }, 1000)
    })
  }

module

//获取a模块的state
<h2>{{$store.state.a.name}}</h2>

//调用a模块的mutation,getters直接调用就行,不用加模块名

Getters接收根节点的数据

getters: {
    fullname(state) {
      return state.name + "11111"
    },
    fullname2(state, getters) {
      return getters.fullname + "2222"
    },
    fullname3(state, getters, rootState) {
      return getters.fullname2 + rootState.counter
    }
}

action接收根节点数据

//局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState
actions: {
    aUpdateName(context) {//也可以用对象结构aUpdateName({state,commit,rootState}){}
      console.log(context);
      console.log("iiiii");
      setTimeout(() => {
        context.commit("updateName", "wangwu")
      }, 1000)
    }
  }

axios

export function request(config) {
  // 1.创建axios的实例
  const instance = axios.create({
    baseURL: "http://123.207.32.32:8000",
    timeout: 5000
  })

  // 2.axios的拦截器
  // 2.1.请求拦截的作用
  instance.interceptors.request.use(config => {
    // console.log(config);
    // 1.比如config中的一些信息不符合服务器的要求

    // 2.比如每次发送网络请求时, 都希望在界面中显示一个请求的图标

    // 3.某些网络请求(比如登录(token)), 必须携带一些特殊的信息
    return config
  }, err => {
    // console.log(err);
  })

  // 2.2.响应拦截
  instance.interceptors.response.use(res => {
    // console.log(res);
    return res.data
  }, err => {
    console.log(err);
  })

  // 3.发送真正的网络请求
  return instance(config)
}

Vue配置

添加别名

//vue.config.js文件
module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        "assets": "@/assets",
        "common": "@/common",
        "components": "@/components",
        "network": "@/network",
        "views": "@/views",
      }
    }
  }
}