vue基础总结

Vue总结

vue引入与导出

引入一个js文件,如果js文件中有 export default xxx 的内容
就这样引入:  import 名称 from '路径'
如果js文件中没有 export default xxx 内容
需要这样引入: import '路径'   (此时window增加一个全局变量 initGeetest)

只有在index.html和main.js引入才是全局引入

vue第一天

vue

Vue是一个优秀的前端框架
开发者按照Vue的规范进行开发
Vue能做什么?
1. 和DOM解耦    与DOM关系不多
2. 适应当前SPA的项目开发  single page application  单一页面应用
3.掌握Vue的开发语法 相当于掌握了新的开发模式,可以适应目前绝大多数的技术环境
特点:
1. 数据驱动视图  可以让我们只关注数据
2. MVVM 双向绑定 
3. 通过指令增强了html功能 新特性
4. 组件化 复用代码

实例选项-el

- 作用:当前Vue实例所管理的html视图
- 值:通常是id选择器(或者是一个 HTMLElement 实例)
- 不要让el所管理的视图是html或者body!

实例选项-data

- Vue 实例的数据对象,是响应式数据(数据驱动视图) 数据变化 => 视图变化
- 可以通过 vm.$data 访问原始数据对象
- Vue 实例也代理了 data 对象上所有的属性,因此访问 vm.a 等于 vm.$data.a
- 视图中绑定的数据必须显式的初始化到 data 中 ,显示到视图中的数据在data中必须定义
- 数据对象的更新方式 直接 采用 实例.属性 = 值  vm.name = "张三"

实例选项-methods

- methods是一个对象
- 可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。
- 方法中的 this 自动绑定为 Vue 实例。
- methods中所有的方法 同样也被代理到了 Vue实例对象上,都可通过this访问, vm.fn()
- 注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined

插值表达式(重要)

作用:会将绑定的数据实时的显示出来:

形式: 通过 {{ 插值表达式 }}包裹的形式

通过任何方式修改所绑定的数据,所显示的数据都会被实时替换(响应式数据)

 a , a = 10 , a == 10 , a > 10, a + b + c
 "1" + "2" + "3", a.length.split(''), a > 0 ? "成功" : "失败"
注意:不能写 var a = 10; 分支语句 循环语句,不可以带有JS关键字
例:
<p>{{ count === 1 }}</p>  #返回Boolean类型
<!-- count 为data中的数据 -->
<p>{{ count === 1 ? "成立" : "不成立" }}</p>
<p>{{ fn() }}</p>   #调用方法

指令(重要)

  • 指令 (Directives) 是带有 v- 前缀的特殊特性。

  • 指令特性的值预期是单个 JavaScript 表达式(v-for 是例外情况,稍后我们再讨论)。

  • 指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

  • 指令位置: 起始标签

    插值表达式: 更新标签中局部的内容
    v-text 更新整个标签中的内容
    v-html 更新标签中的内容/标签,可以渲染内容中的HTML标签(少用,容易造成危险)
    v-if 和 v-show v-show本质是通过修改标签的display值
    v-if="isShow" isShow: false
    场景: 需要根据条件决定 元素是否显示 使用以上指令
    使用: v-if 和 v-show 后面的表达式返回的布尔值 来决定 该元素显示隐藏
    注意 : v-if 是直接决定元素 的 添加 或者删除 而 v-show 只是根据样式来决定 显示隐藏

    v-on绑定事件:
    <input type="text" @change="fn()"> #fn()默认参数为$event,methods内的函数默认第一个参数也是event
    v-on:事件名.修饰符="方法名" ,v-on:可以用@代替
    注意 方法名 中 可以采用$event的方式传形参 也可以直接写事件名 默认第一个参数为event事件参数
    传递$event的时候,$必须加,如果不写,methods中的函数默认第一个参数为event事件参数
    例:fn(count,$event)
    修饰符(可不写)
    .once - 只触发一次回调。
    .prevent - 调用 event.preventDefault()。

    获取当前input中输入的值:

    event事件中target指的是触发该事件的元素 是DOM对象

    console.log(event.target.value);
    @change:鼠标失去焦点输出
    @input:value值变化就输出

遍历数组和对象v-for

 注意 v-for写的位置 应该是重复的标签上  不是其父级元素上 需要注意
     item in items   // item为当前遍历属性数组项的值
      (item,[index]) in items   //item为当前遍历属性数组项的值 index为数组的索引
      v-for 指令需要使用 item in items 或者 item of items 形式的特殊语法,in/of 一样
      items 是源数据数组 /对象    <p v-for="item in list">{{item}}</p>
对象:
      item in items  // item为当前遍历属性对象的值
      (item,[ key], [index]) in  items //item为当前遍历属性对象的值 key为当前属性名的值  index为当前索引的值

vue第二天

v-for-key

- 场景:列表数据变动会导致 视图列表重新更新 为了 提升性能 方便更新 需要提供 一个属性 key
- 使用: 通常是给列表数据中的唯一值 也可以用索引值
语法:
	<li v-for="(item,index) in list" :key="index">

v-if和v-for优先级

<p v-if="index>1" v-for="(item,index) in list"></p>
v-for 的优先级大于v-if ,所有v-if才能使用v-for的index变量
如果遇到 v-if判断数组变量 需要在循环体外再建立一个判断 v-if
<div v-if="list.length >4">
    <li v-if="index>2" v-for="(item,index) in list" :key="index">
       {{ item }}
     </li>
 </div>

v-bind

- 作用:绑定标签上的任何属性
- 场景: 当标签上的属性是变量/动态/需要改变的 
<p v-bind:id="ID"></p>   // ID为数据对象中的变量值 
<p :id="ID"></p>  // 简写

v-bind-绑定class-对象语法

绑定class对象语法    :class="{ class名称: 布尔值 }"
<p :class="{left:showClass}">内容</p>
 showClass:true
如果showClass的值为true,则加上left类,若为false,则不加
<p v-bind:class="name"></p>
 name: "test"    加上test类
绑定class和原生class会进行合并

v-bind-绑定class-数组语法

绑定class数组语法 :class="[class变量1,class变量2..]" #绑定class和原生class会进行合并
<p :class="[activeClass,selectClass]" class="default">内容</p>

v-bind-绑定style-对象语法

<p :style="{fontSize:fontSize,color:color,fontWeight:fontWeight}">Hello world</p>
复合标签必须采用小驼峰命名
当属性名和 值的变量名一致是  可以简写 为 color:color => color
<p :style="{fontSize,color,fontWeight}">Hello world</p>
data: {fontSize: "48px",  color: "red",fontWeight: "bold"}   #data数据如下

v-bind-绑定style-数组语法

语法:  :style="[对象1,对象2...]"
对象可以是多个属性的 集合  同样里面的css属性需要遵从小驼峰命名的规则
例:
	<p v-bind:style="[obj1,obj2]" style="color:blue">Hello world</p>
	 data: {
          obj1: {fontSize: "48px",color: "red", backgroundColor: "black"},
          obj2: { backgroundColor: "yellow" }
        }
       原有内联CSS会先执行,后加CSS如有重复会覆盖内联样式

v-model-基础用法

作用: 表单元素的绑定
特点: 双向数据绑定
 数据发生变化可以更新到界面
 通过界面可以更改数据
 v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。应该在 data选项中声明初始值。

<input type="text" v-model="name" />
<p v-text="name"></p>
语法糖原理
<input type="text" @input="changeInput" :value="name" />
changeInput(){this.name = event.target.value;}
通过v-on指令和 v-bind指令 组合实现v-model效果
利用input事件,获取value实时变化的值,用v-bind绑定value的初始值与data数据一致

v-model绑定其它表单

当表单type属性为Checkbox的时候,获取的是当前表单value值
当表单type属性为Checkbox的时候,未选中默认为false,选中为true

v-cloak

解决页面初次渲染时 页面模板闪屏现象
<div v-cloak id="app"> #可以一次性 将v-cloak引用在实例视图上  避免多次写入标签
[v-cloak] {    display: none; }

v-once

- 作用: 使得所在元素只渲染一次  
- 场景:静态化数据 
 <p>{{ name }}</p>
 <p v-once>{{ name }}</p> #数据不再变化
 <input type="text" v-model="name" />

全局过滤器

1. 在创建 Vue 实例之前定义全局过滤器Vue.filter()
2. Vue.filter('该过滤器的名字',(要过滤的数据)=>{return 对数据的处理结果});
3. 在视图中通过{{数据 | 过滤器的名字}}或者v-bind使用过滤器
 <p>{{ name | toUpper }}</p>  #应用过滤器
1 注册过滤器
Vue.filter("toUpper", function(value) {
        // 2 实现过滤逻辑
        return value.charAt(0).toUpperCase() + value.substr(1);
      });

局部过滤器

 filters: {
          // 和全局过滤器区别只是注册位置不同 应用范围不同
          toUpper(value) {
            return value.charAt(0).toUpperCase() + value.substr(1);
          } }
 filters比全局多了个s,写在Vue实例中,只有当前实例可以调用 ,和全局过滤器区别只是注册位置不同 应用范围不同
 第一个参数永远是value,第二个参数可以是索引
 过滤器可定义多个,也可一起使用
 <p>{{ text | toUpper(2) | reverse }}</p> // 语法 多个过滤器用 | 分割

使用过滤器完成日期 格式处理

1 . 引入 第三方格式化日期插件 moment.min.js
2 . 定义格式化日期过滤器
3 .  实现其格式化功能 
4 .  使用过滤
format(value, format) {
  return moment(value).format(format);
}  // 过滤器代码
 <td>{{item.date|format("YYYY-MM-DD hh:mm:ss")}}</td>

vue第三天

ref 操作 DOM

- 作用: 通过ref特性可以获取元素的dom对象
- 使用:  给元素定义 ref属性, 然后通过$refs.名称 来获取dom对象
<input type="text" ref="myInput" /> // 定义ref
focus() {
  this.$refs.myInput.focus();
}  // 获取dom对象 聚焦  methods中定义方法

自定义指令-全局自定义指令

- 使用场景:需要对普通 DOM 元素进行操作,这时候就会用到自定义指令 
- 分类:全局注册和局部注册
1. 在创建 Vue 实例之前定义全局自定义指令Vue.directive()
2. Vue.directive('指令的名称',{ inserted: (使用指令的DOM对象) => { 具体的DOM操作 } } );
3. 在视图中通过"v-自定义指令名"去使用指令  v-focus
 // 定义指令
//  自定义指令是不需要加v-前缀的
// 第二个参数为一个对象  对象中要实现 inserted的方法
// inserted中的参数为当前指令所在元素的dom对象
Vue.directive("focus", {
        inserted(dom) {
          dom.focus();
        }
      });
局部自定义命令写在vm实例中

computed

  • 场景:当表达式过于复杂的情况下 可以采用计算属性 对于任何复杂逻辑都可以采用计算属性

  • 使用: 在Vue实例选项中 定义 computed:

  • 说明: 计算属性的值 依赖 数据对象中的值 数据对象发生改变 => 计算属性发生改变=> 视图改变

  • methods 和 计算属性的区别

  • methods 每次都会执行

  • 计算属性 会每次比较更新前后的值 如果前后一致 则不会引起视图变化

  • methods每次都会执行 性能较计算属性较差

  • 计算属性中一定是同步操作,如果有异步操作,则该业务逻辑就会失败

    {{newList}} //调用计算属性
    

    computed: {
    newList(){
    var arr= this.list.filter(function(value,index){
    return value>5;
    })
    return arr;
    }} // 定义计算属性

axios

  • 本地引入axios文件

  • 在npm 中引入axios文件

    axios.get(url).then((res) => {
    // 请求成功 会来到这 res响应体
    }).catch((err) => {
    // 请求失败 会来到这 处理err对象
    })

表格案例

获取数据:
mounted() {
     // 渲染完成事件
     axios.get("http://localhost:3000/brands").then(result => {
       this.list = result.data;});}
删除数据:
delItem(id) {
       if (confirm("确定删除此条记录")) {
         axios
           .delete("http://localhost:3000/brands/" + id)
           .then(result => {
             this.getList(); // 重新调用拉取数据}); } }
添加数据:
addItem() { // 添加商品 
       axios.post("http://localhost:3000/brands", {
           name: this.name,
           date: new Date()
         })
         .then(result => {
           if (result.status == 201) {
             this.getList(); // 请求数据
             this.name = ""; // 清楚文本框内容}});

watch(监听属性)

 watch:{    //watch也是vm实例的一个对象
                city:function(oldName,newName){
                   var arr = this.list.map(function(i){
                        i.name = newName;
                        return i;
                    });
                    this.list = arr;} }

vue第四天

组件

组件特点: 组件是一个特殊的 Vue实例

和实例相似之处: data/methods/computed/watch 等一应俱全

注意:data和Vue实例的区别为 组件中data为一个函数 没有el选项
data选项是一个函数的时候,每个实例可以维护一份被返回对象的独立的拷贝,这样各个实例中的data不会相互影响,是独立的。

template 代表其页面结构 (有且只要一个根元素)

每个组件都是独立的 运行作用域 数据 逻辑没有任何关联

<content-a></content-a>   /  //使用组件
Vue.component("content-a", {   //  // 组件名称 abc abcD adc-d  推荐 abc-d的模式 而且全小写
        template: `<div>
        {{count}}
        </div>`,
        data() {  
          return {
            count: 1
          };
        }});
// 组件能够实现数据独立  因为在data中return 了一个新的对象
 // 组件中 data必须是一个函数 而且必须返回一个对象(重点)
// 这是组件和Vue实例的最大区别

局部组件

局部组件写在vm实例对象内部,components:{},需要加个s
 components:{ "content-a": { template: ``}}
使用组件中的实例不要忘记加this

component嵌套

var comA = {template: `<div>我是子组件</div>`};  //先定义子组件
 var parentA = {   //再定义父组件
    template: `<div>
     我是父组件
     <com-a></com-a>       //调用子组件
    </div>`,
    components: {'com-a': comA }   //组件同样拥有注册局部组件选项
  };
 components: { 'parent-a":parentA}    //根组件再调用父组件

组件传值

父组件→子组件

  • props作用: 接收父组件传递的数据

  • props就是父组件给子组件标签上定义的属性

  • props是组件的选项 定义接收属性

  • props的值可以是字符串数组 props:["绑定的属性"] , 来源于外部的(组件的外部)

    父组件传递给子组件的数据是只读的,即只可以用,不可以改
    1. //调用子组件时,给子组件标签用v-bind绑定属性
    data() {return { name: "张三",age: 18};
    2. props: ["title", "age"] // 父组件传递后,子组件要用props接收传递属性
    3.{{ title }}

    {{age}}

    //子组件接收完属性就可以进行调用属性,不是属性值

子组件→父组件

  • 通过在子组件中触发$emit事件,然后在父组件中监视此事件 进行追踪

    methods: {
    selectCity() {
    // this当前实例 this.属性名直接可以获取props属性值 所以props不能和data属性重名 也不能和方法重名
    //console.log(this.city);
    // $emit是当前实例的方法 (自定义事件名称(可随意定义),params...)
    this.$emit("changecity", this.city); //抛出一个事件
    }
    子组件通过抛出事件,父组件定义事件接收 @changecity="change",事件名与$emit中一致,change(city)可以拿到实参

SPA

  • 传统模式 每个页面及其内容都需要从服务器一次次请求 如果网络差, 体验则会感觉很慢
  • spa模式, 第一次加载 会将所有的资源都请求到页面 模块之间切换不会再请求服务器
    优点:
    用户体验好,因为前段操作几乎感受不到网络的延迟
    完全组件化开发 ,由于只有一个页面,所以原来属于一个个页面的工作被归类为一个个组件.

缺点

  1. 首屏加载慢->按需加载 不刷新页面 之请求js模块

  2. 不利于SEO->服务端渲染(node->自己写路由->express-art-template+res.render())

  3. 开发难度高(框架) 相对于传统模式,有一些学习成本和应用成本

  4. vue适合开发SPA , SPA不利于SEO

  5. SPA-实现原理

    前端自由切换模块
    刷新页面模块依然还在当前视图

    • 可以通过页面地址的锚链接来实现
    • hash(锚链接)位于链接地址 #之后
    • hash值的改变不会触发页面刷新
    • hash值是url地址的一部分,会存储在页面地址上 我们可以获取到
    • 可以通过事件监听hash值得改变
    • 拿到了hash值,就可以根据不同的hash值进行不同的模块切换
      location 可以拿到hash

路由

体验:
 <!-- router-link 最终会被渲染成a标签,to指定路由的跳转地址 -->
        <router-link to='/bj'>北京</router-link>    //设置导航内容
  <!-- 路由匹配到的组件将渲染在这里 -->
        <!-- 设置容器 -->
        <router-view></router-view>    // 设置容器
        <script src="./vue-router.js"></script>  ///引入vue-router.js
        var router = new VueRouter({   //实例化一个vue-router
            routes:[{    //编写页面路由 配置路由表
                path:'/bj',
                component:{
                    template: `<div>北京</div>`
                }}]
           router:router    //将router挂载到Vue实例上
点击link标签,跳转到相应路径路由,将对应模板 显示到view上,其它模板被销毁

vue第五天

vue-router-动态路由

  • 点击列表页 跳转到详情页时,跳转的链接需要携带参数,会导致页面path不同

  • 当页面path不同却需要对应同一个组件时,需要用到动态路由这一概念,可以通过路由传参来实现

    this.$route 获取当前路由对象 并通过params获取定义的参数id
    path:"/team/:teamname", //定义动态路由
    component:{
    template:<div>我是{{$route.params.teamname}}队粉丝</div> }
    //{{$route.params.teamname}}{{$route.params.postname}} ,两个参数需要拿两次
    勇士 //传入实参

    路由规则 匹配路径 $route.params
    /user/:username /user/evan { username: 'evan' }
    /user/:username/post/:post_id /user/evan/post/123

vue-router-to属性赋值

 <!-- <router-link to="/sport">体育</router-link> -->
      <!-- 变量 -->
      <!-- <router-link :to="path">体育</router-link> -->
      <!-- 根据对象name跳转 -->
      <!-- <router-link :to="{name:'abcdefg'}">体育</router-link> -->
      <!-- 根据对象path跳转 -->
      <!-- <router-link :to="{path:'/sport'}">体育</router-link> -->
      <!-- 带参数的跳转 -->
      <router-link :to="{name:'abcdefg',params:{a:1}}">体育</router-link>

注意:如果提供了 path,params 会被忽略,上述例子中的name并不属于这种情,你可以提供路由的 name 并手写完整的参数params:**

vue-router-重定向

当希望某个页面被强制中转时 可采用redirect 进行路由重定向设置

 path: "/sport",
 redirect: "/news", // 强制跳转新闻页

vue-router-编程式导航

  • 跳转不同的组件 不仅仅可以用router-link 还可以采用代码行为
  • (Vue实例)this.$router 可以拿到当前路由对象的实例
  • 注意 前面小节获取数据用到的是 $route,这里用到的是$router
  • 路由对象的实例方法 有 push replace, go()
  • push 方法 相当于往历史记录里推了一条记录 如果点击返回 会回到上一次的地址
  • replace方法 想相当于替换了当前的记录 历史记录并没有多 但是地址会变
  • go(数字) 代表希望是前进还是回退,当数字大于0 时 就是前进 n(数字)次,小于0时,就是后退n(数字)次

可以通过vue实例 获取当前的路由实例 $router

goPage() {
  // 跳转到新闻页面
     this.$router.push({
       path: "/news"});}

vue-router-routerlink-tag-激活样式

当前路由在导航中是拥有激活class样式的,设置激活class样式即可
<a href="#/news" class="router-link-exact-active router-link-active">新闻</a>

vue-router-嵌套路由

  • 如果存在组件嵌套,就需要提供多个视图容器

  • 同时,router-link和router-view 都可以添加类名、设定样式

  • 注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。

    {
    path:'/music',
    children:{
    path:'/pop' }} //此时该条路由 就是 /pop
    // 如果想使用 /music/pop 可以这样
    {
    path:'/music',
    children:{
    path:'/music/pop' }} //此时该条路由 就是 /music/pop
    // 或者
    {
    path:'/music',
    children:{
    path:'pop' }} //此时该条路由 就是 /music/pop
    二级路由需要写在一级路由的组件中,包括视图
    {
    path:"/hx",
    //二级路由要写在组件中
    component:{
    template:<div> 我是化学 <router-link to="/hx/h2">语文</router-link> <router-link to="/hx/o2">数学</router-link> <router-link to="/hx/h2o">外语</router-link> <router-view></router-view> </div>
    },
    children:[{
    path:"/hx/h2",
    component:{
    template:
    <div>语文</div>
    }},
    {
    path:"/hx/o2",
    component:{
    template:
    <div>数学</div>
    }},
    {
    path:"/hx/h2o",
    component:{
    template:
    <div>外语</div>
    }
    }]
    },

CSS 过渡和动画 中自动应用 class

  • 基本用法就是给我们需要动画的标签外面嵌套transition标签 ,并且设置name属性(就是class)

  • Vue 提供了 transition 的封装组件,在下列元素更新,移除,新增 情形中,可以给任何元素和组件添加进入/离开过渡

    <button @click="show=!show">显示/隐藏





    class状态

    1. v-enter:定义进入过渡的开始状态。
    2. v-enter-active:定义进入过渡生效时的状态。
    3. v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。
    4. v-leave: 定义离开过渡的开始状态。
    5. v-leave-active:定义离开过渡生效时的状态。
    6. v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。

vue-cli工具介绍

  • 介绍: vue-cli是一个辅助开发工具=> 代码编译 + 样式 + 语法校验 + 输出设置 + 其他 ...
  • 作用: 可以为开发者提供一个标准的项目开发结构 和配置 开发者不需要再关注

ES6模块的导入和导出

ES6提供import 别名 from 路径 语法 来引入 组件

提供 export default { } 语法来导出组件

上面的代码 换成import

export default vue //导出对象 vue

import vue from 'vue'

扩展---

export const function  fn1() {} // 方法1
export const function  fn2() {} // 方法2
export const function  fn3() {} // 方法3

import { fn1,fn2, fn3 } from '文件'

Vue-单文件组件及入口解析

注意Vue 选项中的 render 函数若存在,则 Vue 构造函数不会从 template 选项或通过 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数。

介绍: 在cli开发模式下, 一个*.vue文件就是一个组件

  • template 组件的页面结构 代表它的 html 结构
    • 必须在里面放置一个 html 标签来包裹所有的代码
  • 我们在其他地方写好了一个组件,然后就可以在当前template中引入
  • script 组件的逻辑结构及数据对象

vuex

vue兄弟组件传值

1.创建 eventBus.js ,存储一个负责通信的 Vue 的实例(让搜有组件都能够使用)

import Vue from 'vue'
// 负责通信的 vue
const vue = new Vue()
export default vue

2.兄弟组件分别引入通信vue实例

传值组件
 <button @click="handle">点我</button>
  methods: {
    handle () {
      this.count++
      eventBus.$emit('change', this.count)
    }}
data中定义count,点击按钮调用方法,触发事件eventBus.$emit('change', this.count),将值传给兄弟

3.接收值组件

created () {
    // 注册事件
    eventBus.$on('change', (num) => {
      this.num = num
    })}
data中定义num,钩子函数调用用于接收值的事件,将count值赋值给num,实现兄弟传值

store

1.创建store

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutation: {
    setCount (state) {
      state.count++
    }
  }
})
export default store

2.Vue 实例中配置 Store

// 注册 store
import store from './store'
new Vue({
  // 配置 store
  store,    //挂载了store,vue实例中就有了$store,挂载router,就多了$router
  render: h => h(App)
}).$mount('#app')

3.组件中使用状态数据

{{ this.$store.state.count }}

// 调用 mutation 修改 state
this.$store.commit('setState')
# 注意:state状态不能直接修改,不然devtools监测不到
# 需要在store.js中通过 mutation 的方式,修改 state 状态
 mutation需要在使用状态数据的组件通过commit方式调用,写在methods中
 methods: {
    handle () {
      this.$store.commit('setCount')
    }
  }
# 这种方法修改state状态,页面上变化,devtools中也会跟着变化

state

  • Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态
  • 使用计算属性简化组件中访问 State
    // 在组件中
    computed: {
    count () {
    return this.$store.state.count
    }
    }
    // 使用 {{ count }}

Getter

  • 如果对某个状态值进行计算的结果在多个组件中都需要使用,此时在多个组件中定义计算属性会变得重复
  • Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)
    • 定义 getter
      // stote/index.js 中
      getters: {
      reverseMsg (state) {
      return state.msg.split('').reverse().join('')
      }
      }
    • 组件中使用 getter {{ $store.getters.reverseMsg }}

Mutation

  • 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation

  • Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)

  • 回调函数会接受 state 作为第一个参数

    • 定义 mutation
      // stote/index.js 中
      mutations: {
      increment (state) { //increment就是时间类型
      // 变更状态
      state.count++
      }
      }
    • 组件中使用
      this.$store.commit('setCount')
  • 提交载荷 (Payload)

    • 向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):
      mutations: {
      // n 即是载荷
      increment (state, n) {
      state.count += n
      }
      }
      // 在组件中
      this.$store.commit('increment', 10)
    • 在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读:
      mutations: {
      increment (state, payload) {
      state.count += payload.amount
      }
      }
      // 在组件中调用
      this.$store.commit('increment', {
      amount: 10
      })
  • 对象方式的提交

    • 提交 mutation 的另一种方式是直接使用包含 type 属性的对象:

      // 组件中的调用
      store.commit({
      // mutation的名字
      type: 'increment',
      amount: 10
      })

  • 使用常量替代 Mutation 事件类型,详情见官方文档

  • 注意

    • Mutation 中的操作都是同步的 ,为了让 devtools 能够跟踪 state 的变化
    • 如果想要做异步操作更新 state ,需要使用 Action
posted @ 2019-08-22 11:05  “匆匆”  阅读(144)  评论(0编辑  收藏  举报