Vue2总结

Vue框架
上层框架 只关注数据驱动 借鉴MVVM模式

MVVM模式
  • M Model层 数据模型层
  • V View 视图层
  • VM ViewModel层 视图数据层

M层发生变化VM层中得Data Bindings监听到M层变换通知V层及时更新
V层发生变化VM层中得DOM Listeners监听到V层变化通知M层及时更新

生命周期 **************************

从vue实例创建到虚拟dom产生到数据绑定数据监听到销毁得过程

  • 实例创建阶段
    • beforeCreate 实例创建前
      初始化默认事件和默认生命周期,此时实例还没创建完成,无法访问data数据和methods方法
    • created 实例创建完成
      初始化数据注入和数据监听,此时实例创建完成,可以访问data数据和methods方法
      最早得异步请求
  • 实例挂载阶段
    • beforeMount 实例与模板绑定之前 完成模板编译
      查看有无el选项,有查看有无template选项,没有template选项会把el外部html作为模板编译,
      有el选项,有template选项,将template作为模板使用render函数编译。如果没有el选项,使用
      实例方法$mount()完成模板编译
      此时模板与实例还未绑定 无法访问dom元素
    • mounted 实例与模板绑定完成 创建$el代替el选项
      此时可以访问dom元素
  • 实例更新阶段 只要数据发生改变就会触发生命周期
    • beforeUpdate 实例更新前
      此时可以获取到最新得数据 但是使用到数据dom元素还未更新完成 旧dom元素
    • updated
      此时可以获取到最新得数据 使用到数据dom元素更新完成 新dom元素
  • 实例销毁阶段 $destroy销毁组件
    • beforeDestroy 实例销毁前 此时可以修改数据和方法
    • destroyed 实例销毁完成 此时移除监听器、子组件和事件监听,修改数据和方法失败,但是可以访问

此外还有三个

  • activited 组件激活
  • deactivated 组件未激活
  • errorcaptured 错误调用
事件修饰符

.stop           阻止事件冒泡
. prevent     阻止默认事件的触发
. capture     捕获事件
. self           仅当前元素是event.target触发
. once         执行一次事件
. passive     事件的默认行为立即执行,无需等待事件回调执行完毕。

指令总结

绑定事件     v-on:事件类型=“事件处理程序”       (@事件类型=“程序”)
绑定变量     v-bind:变量名=“值名”                    (:变量名=“值名”)
双向绑定     v-model = “ ” (一般用于表单)
模板语法     {{ }}          v-text=“ 不会解析代码”        v-html=“ 会解析代码”        ref=“ 获取dom元素 ”
执行一次性插值     v-once(后续数据发生变化 插值处数据不发生改变)
条件渲染               v-if、v-else-if、v-else
显示与隐藏            v-show
循环     v-for=“(item,index) in/of items” :key=“id”
             v-for=“(value,key,index) in obj” :key=“id”

style动态绑定       v-bind:style= “ ”
class动态绑定      v-bind:class=“ ”
具名插槽               v-slot:插槽名
自定义指令           directive (与创建组件相同)

自定义指令 v-xxx

全局注册

Vue.directive('指令名称',{

    //当被绑定元素插入到父节点调用
    inserted(el,binding,vnode,oldNode){
      el--------->绑定指令dom元素
      binding---->元素数据 value 
      vnode ----->虚拟节点 dom对象内存中数据表示
      oldNode---->旧节点
    },

    //执行一次性初始化设置 
    bind(el,binding,vnode,oldNode){    }

    //组件vnode更新触发
    update(el,binding,vnode,oldNode){   }
  })

局部注册

directives:{
    myshow:{
      inserted(){

      },
      bind(){

      },
      update(){}
    }
  }
模板语法
<body>
    <!-- 视图 -->
    <div id="app">
        1.Mustache 文本插值  只会把变量当作普通文本进行渲染  不会解析html代码
        {{msg}}                       <!-- hello vue2 -->
        <div>{{content}}</div>        <!-- <p>我是段落标签<a href='https://www.baaidu.com'>百度一下</a></p> -->
        <div v-text="content"></div>  <!-- <p>我是段落标签<a href='https://www.baaidu.com'>百度一下</a></p> -->
         2.v-html  解析html代码片段 
        <div v-html="content"></div>    <!-- 我是段落标签 百度一下  -->

         3.绑定变量 v-bind:   简写为 :
        <div title="{{title}}">我是一个div</div>     <!-- 鼠标放上显示:{{title}}-->
        <div v-bind:title="title">我是一个div</div>  <!-- 鼠标放上显示:我是div的提示说明-->
        <div :title="title">我是一个div</div>        <!-- 鼠标放上显示:我是div的提示说明-->

        4.js表达式  双花括号内部可以直接使用js表达式
        {{str.split(' ').reverse().join(' ')}}
        {{Boolean(msg)}}
        {{3>2?'YES':'NO'}}
        <!-- world hello true YES -->
    </div>

    <script>
        //创建VEU得实例
        let vm=new Vue({
            //绑定模板
            el:'#app',
            //数据模型 存放vue变量
            data:{
                msg:'hello vue2',
                str:'hello world',
                title:"我是div的提示说明",
                content:"<p>我是段落标签<a href='https://www.baaidu.com'>百度一下</a></p>"
            },
            //函数和事件处理程序
            methods:{
            },
        });
    </script>
事件机制

使用v-on绑定事件 v-on:事件类型 简写为@
每一个事件处理程序都有一个事件对象

 div @click='handler("hello",12,$event)'
 handler(a,b,c){
   console.log(event,a,b,c,'c就是事件对象')
 }
表单双向数据绑定 v-model

监听用户输入事件以更新数据 创建双向数据绑定

v-model修饰符:
lazy         输入事件input事件 change事件 失焦或者按下回车
number   将输入框双向绑定得数据设置为number类型
trim         过滤绑定数据前后空格

双向数据绑定实现Object.defineProperty()
 <p></p>
 <input type='text'>
 let obj = {
   name:""
 }
 input.oninput = function(){
   obj.name = this.value;//获取用户输入框输入得内容
 }
 Object.defineProperty(obj,'name',{
   get(){
     return obj.name
   },
   set(newValue){
     newValue --->this.value;
     p.innerHTML = newValue;
   }
 })
v-if和v-show区别**********************************
  • v-if 对应的是组件创建和销毁,满足条件对应的组件创建,不满足则销毁。
    v-if是惰性的,如果初始条件不满足,dom元素就不会被渲染
  • v-show无论初始条件满不满足,都会渲染到模板中,对应的是css属性显示与隐藏,满足显示元素,不满足条件隐藏元素
  • v-if :引起重排,有更高切换开销,如果条件很少改变情况可以使用v-if指令渲染;
    v-show :引起重绘,有更高初始渲染,用于频繁切换
style绑定 与class绑定
 内联样式绑定 
   style='{color:currentColor}'
   style='styleObj'
   style='[styleObj,styleObj1]'
   styleObj:{
     color:"red",
     fontSize:28
   }
  :class='type==="xxx"?"current":""'
  :class='{active:isActive}'
  :class='{active:isActive,error:hasError}'
  :class='[{active:isActive,error:hasError},{class:true}]'
组件注册

可复用的vue实例,封装了重复的代码,可以多次调用组件/重复使用。

全局注册
  Vue.component('组件名称',{
    data(){  return {  }  },
    methods:{ },
    ...
    template:`    <div>组件模板</div>   `
  })
局部注册
  components:{
    '组件名称':组件配置项{ }
  }
动态组件

component标签动态切换组件,使用is属性切换组件
使用component切换组件,组件会不停的创建和销毁,如果想在第一次创建时候缓存组件,可以
使用keep-alive包裹

  • 与keep-alive相关生命周期:
    • activated          使用keep-alive缓存的组件激活(进入)的时候触发
    • deactivated      使用keep-alive缓存的组件失活(离开)的时候触发
    • errorCaptured   捕获后代组件错误时触发
      • error(错误对象)
      • vm(发生错误的组件)
      • info(错误提示字符串)
<body>
  <div id="app">
    <!-- 使用component动态切换组件 is属性 组件名称  -->
    <!-- <component v-bind:is="current"></component> -->
    
    <!-- keep-alive作用:希望第一次创建组件时候被缓存 后续切换不会重新创建和销毁  -->
    <!-- <keep-alive> -->
      <component v-bind:is="current"></component>
    <!-- </keep-alive> -->
    <button @click="current='my-person'">加载个人组件</button>
    <button @click="current='my-company'">加载企业组件</button>
  </div>
  <script>
    let myPerson = {
      template: ` <div>个人组件</div> `,
      created() { console.log('个人组件创建') },
      destroyed() { console.log('个人组件被销毁')}
    };

    // 声明后代组件
    let companyChild = { template:`  <div>{{subMsg}}</div> ` };

    let myCompany = {
      components:{ 'company-child':companyChild },
      template: ` <div>企业组件<company-child></company-child></div> `,
      created() {console.log('企业组件创建') },
      destroyed() { console.log('企业组件被销毁')},
      activated(){console.log('被keep-alive缓存的组件激活的时候触发 进入组件时候触发')},
      deactivated(){ console.log('被keep-alive缓存的组件失活的时候触发 离开组件时候触发')},
      // 捕获后代组件发生错误时触发
      errorCaptured(err, vm, info){
        console.log(err,'发生错误')
        console.log(vm,'发生错误组件')
        console.log(info,'字符串信息提示')
      },
    }
    
    new Vue({
      el: "#app",
      components: {
        'my-person': myPerson,
        'my-company': myCompany
      },
      data: {
        current: 'my-person'
      },
      methods: {

      }
    })
  </script>
</body>
key作用:

vue采用得是diff算法,会高效复用组件,当组件相似的时候,一般往往是复用而不是重新创建,这样渲染效率会变得低下。
如果不希望被复用,就可以给组件设置一个唯一标识key,告诉vue是不希望被复用得节点

组件data为什么是一个函数不是一个对象

(如果是对象,引用地址一样,改一即该三)
因为组件实例是可以被复用得,如果data是一个对象就会全局可见,只要其中一个使用到该组件得组件修改了数据,剩下使用到该组件得组件数据也会被修改。data只能返回一个函数返回一个对象,对象数据只在当前组件内可见!

  • 组件是一个可复用的实例,当你引用一个组件的时候,组件里的data是一个普通的对象,所有用到这个组件的都引用的同一个data,就会造成数据污染。
  • 不使用return包裹的数据会在项目的全局可见,会造成变量污染;
    使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
  • 当一个组件被定义, data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
计算属性
computed:{
    reverse(){
      return this.msg.xxx()
    },
    fullName:{
      get(){  },
      set(){  }
    }
  }
  {{reverse}}
  • 对data中数据进行逻辑处理返回一个响应式数据(基于响应式依赖(data),只要响应式依赖不发生改变,计算属性就不会重新计算,多次调用计算属性会返回之前计算得结果)
  • 有缓存性
  • 计算属性默认只提供getter,只可读,不允许修改,
  • 想要修改计算属性,需要提供setter函数。

处理响应式依赖选项,对data中数据进行处理再返回基于data响应式数据的依赖,计算属性会在第一次把计算结果进行缓存,如果响应式依赖没有发生改变,再次调用计算属性会立即返回 第一次得结果,而不会重新计算。计算属性默认只提供getter函数,只能进行读取,如果修改计算属性, 提供setter函数。

侦听器

只有监听数据发生改变才会触发监听器

watch:{
   监听基本数据类型
   page(n,o){
     console.log(n,o,新数据,原始数据)
   }
   监听引用数据类型
   params:{
     handler(n,o){
       this.getArticle();
     },
     //开启深度监听
     deep:true
   }
 }
计算属性与methods方法区别?
  1. 计算属性具有缓存性,data数据不发生改变多次调用会返回第一次缓存得结果
  2. methods无缓存性,调用一次方法执行一次
  3. methods可以处理异步操作,计算属性一般不用于异步操作
计算属性和watch区别?
  1. 计算属性具有缓存性,响应式依赖不变,计算属性就不会重新计算,而是会返回之前得计算结果。
  2. watch无缓存性,只有数据发生改变,侦听器才会执行。
  3. watch一般用于异步操作(监听分页)或者开销较大操作
  4. 计算属性一般不用于异步操作,只提供getter,默认可读,设置setter就可修改。
组件通信/传值方式?*******************************************

vuex也可以实现传值

1.父组件给子组件传值:

  • props
    • 在父组件的子组件标签中写入父组件传递的数据 向下传递prop
    • 在子组件内声明props选项接收父组件传递的数据
      props:[‘’,‘’,‘’] 或props:{ , , ,} (这个是对传递的数据进行类型验证)
  • provide与 inject
    • 父组件使用provide提供传递数据或者方法
      provide(){ return{ 变量名:值} }
    • 子组件使用 inject:[‘变量名’] 注入传递的数据或者方法
  • 定义事件总线导出实例对象
    $emit 和 $ on
    • 新建event.js
      import Vue from ‘vue’;
      export default new Vue();
    • 在父组件新建方法中使用$emit发射自定义事件同时传递参数
      import Bus from ‘./event.js’
    • 在子组件新建created(){}中使用.$ on监听自定义事件同时接收参数
      import Bus from ‘./event.js’
      Bus.$on(‘自定义事件名称’,(a,b)=>{ })

2、子组件给父组件传值:

  • &emit
    • 发射自定义事件(在子组件中新建方法)给父组件同时传递数据
      this.$emit(‘自定义事件名’,传递数据1,传递数据2);
    • 在父组件模板中(在子组件标签上)声明自定义事件
      <子组件标签 @自定义事件名=‘事件处理程序’> </子组件>
      事件处理程序(接收子组件传递的数据1,数据2){ }
  • 作用域插槽

请添加图片描述

请添加图片描述

3、兄弟组件传值/通信

  • 同父传子方法3
    定义事件总线导出实例对象
    $emit 和 $ on
    • 定义事件总线 新建xxx.js
      import Vue from ‘vue’;
      export default new Vue();
    • 在一个兄弟组件中引入事件总线
      import Bus from ‘./event.js’
      使用Bus.$emit(‘自定义事件名称’,传递的数据)
    • 在另一个兄弟组件中引入事件总线
      import Bus from ‘./event.js’
      使用Bus. $on(‘emit发射自定义事件名称’,(a,b)=>{})
      监听发射自定义事件 同时接收数据

4、祖先后代组件传值/通信

  • 同父传子方法2
    • 祖先组件使用provide提供数据
    • 后代组件使用inject注入数据
props验证
对父组件传值的校验
  props:{
    propA:String,
    propB:[String,Number,Boolean],
    propC:{
      required:true,
      type:String
    },
    //基本数据类型
    propD:{
      type:Number,
      default:10
    },
    //引用数据类型
    propE:{
      type:Array,
      default(){
        return [1,2,3,4]
      }
    },
    //自定义校验器
    propF:{
      validator(val){
        return ['success','warning'].includes(val)
        return true
      }
    }
  }
单向数据流

数据从上层流向下层,上层(父组件)修改数据子组件数据也会被修改,但是反过来不可以。
(父组件会修改自己和子组件,而子组件只能改自己)

axios

基于promise的http库,可以运行在浏览器和nodejs。

特性:

  1. 运行在浏览器和nodejs
  2. 基于promise(可以使用promise实例方法)
  3. 可以对请求和响应拦截处理
  4. 运行在浏览器创建XMLHttpRequests
  5. 运行在nodejs创建http请求
如何使用axios发起请求?
  1. 安装
    cnpm/npm install axios -S
    bootcdn

axios({
   请求路径 url:“”,                 //必需参数
   请求方式 method:“”,       (axios默认发起的是get请求)
   请求头 headers:{},
   url参数 params:{},
   请求体参数 data:{},
   超时处理 timeout:2000,
   基础路径 baseURL:‘’
})

  • 方法别名/快捷方法:
    • axios.get(url,请求配置项)
      无参: axios.get(url)
      有参: axios.get(url,{ params:{参} })
    • axios.post(url,data,请求配置项)
      axios发起post请求默认数据格式是json数据格式—登录
      axios发起表单格式post请求,需要设置请求头Content-type:application/x-www-form-urlencoded

3.全局默认值

  • axios.defaults.baseURL = ‘’;
  • axios.defaults.headers[‘Auth’]=‘token’;
  • axios.defaults.headers.post[‘Content-Type’]=‘application/x-www-form-urlencoded’
axios二次封装

创建实例

const instance = axios.create({
  baseURL:"",
  timeout:5000,
  .....
})

请求拦截器:对请求的数据进行认证

let id = axios.interceptors.request.use(config=>{
    if(token){
      config.headers['Authorization']='adasfdaff'
    }
    return config
  },error=>{
    return Promise.reject(error)
  })

响应拦截器:对响应的数据进行拦截,处理

let id = axios.interceptors.response.use(response=>{
    return response.data
  },error=>{
    return Promise.reject(error)
  });

封装get 、post 、postJSON

  export function get(url,params){
    return axios.get(url,{
      params
    })
  }
  export function postJSON(url,data){
    return axios.post(url,data)
  }
  export function post(url,data){
    return axios.post(url,Qs.stringify(data))
  }
//导出创建的实例
export default instance

移除拦截器

axios.interceptors.request.eject(id)
axios.interceptors.response.eject(id)
插槽 slot

父组件传递模板给子组件,子组件使用插槽声明slot元素承载分发内容出口。

  • 默认插槽:父组件提供给子组件模板,默认会填充到默认插槽中
    < slot name=‘default’></ slot>
  • 具名插槽:父组件提供了具体的模板,填充到具名插槽中
    < template v-slot:header></ template>
    < slot name=‘header’></ slot>
  • 作用域插槽:父组件作用域使用子组件数据
      1. 在子组件默认插槽中动态绑定插槽prop
        < slot v-bind:user=‘user’>
      1. 在父组件模板中使用v-slot='插槽prop’接收子组件数据
        < template v-slot=‘scope’>
              {{scope.user.xxxx}}
        </ template>
render函数

需要js完全编程能力,比模板更接近编译器,编译模板

  render(createElement){
    return createElement(标签名称,{标签属性},子节点数组)
  }
  render(createElement){
    return createElement(标签名称,{},[this.$slots.default,...lis])
  }
过滤器     filter

格式化文本,时间都可以使用过滤器,使用在双花括号内部,使用在v-bind表达式

全局注册过滤器
  Vue.filter('过滤器名称',function(val){
    val---->需要格式化文本
    return val.toUpperCase();
  })
局部注册过滤器
  filters:{
    'fmtDate'(val){
      return moment(val).format('YYYY-MM-DD')
    }
  }
  
  过滤器使用
  {{msg | fmtDate}}
  <div v-bind:title='title | fmtDate'></div>
  
  串联使用
  {{msg | filterA | filterB}}
  
  过滤器js函数,可以传递参数
  {{msg | filterA('hello',{name:"terry"})}}

插件      install 、 use

添加Vue的全局功能,开发插件必须暴露install方法

开发插件:
    let myPlugin = {
      install(Vue,options){
        Vue.Method = function(){

        };
        Vue.directive('focus',{

        });
        Vue.filter('filterA',function(val){

        });
        Vue.prototype.$message = function(){

        }
      }
    }
  使用插件(new Vue之前)
  Vue.use(myPlugin)
混入     mixin

来分发Vue组件中可复用的功能,一个混入对象可以包含任意组件选项。
当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
可以对数据和对象选项进行混入,接收组件任意选项。

全局混入:
     Vue.mixin({
       data(){
         return {

         }
       },
       methods:{

       },
       computed:{

       }
     })let mixin = {

   }
   局部混入:
     mixins:[mixin]
   全局混入对象会影响到每一个组件,谨慎使用。

混入规则:

  1. data选项会进行合并,如果data数据发生冲突,会保留组件内的数据。
  2. ==生命周期(钩子函数)==会被合并到一个数组并依次调用,混入对象的生命周期先调用。
  3. 值为对象选项(methods,computed,watch,directive)也会合并到一个对象中,如果对象
    冲突保留组件内的键值对。
路由机制

通过路由加载组件的方式,主要处理单页面应用程序。

let myA = {};
let myB = {};

1.声明路由对象数组
const routes = [
  路由所要加载组件---组件所对应的路由
  {
    path:"/myA",
    component:myA
  },
  {
    path:"/myB",
    component:myB,
    给路由设置名称
    name:'myB',
    重定向
    redirect:'/other',{name:''}
    给路由设置别名
    alias:'/bb'
  }
]


2.创建路由器实例对象 
const router = new VueRouter({
  routes:routes,
  路由模式
  mode:''
});


3.将路由器实例注册vue根实例
new Vue({
  router
})


4.通过router-link标签访问组件
<router-link to='/myA'>A组件</router-link>
路由出口匹配
<router-view></router-view>
嵌套路由—>子路由
  {
    path:'/user',
    component:User,
    children:[
    //  存放子路由对象
      { path:"childA"  },
      {   path:"childB" },
      {  path:"childC"  }
    ]
  }
动态路由匹配

不同用户加载同一个组件,通过动态路径参数实现动态路由匹配。

< user>用户组件–{{id}}–{{username}}</ user>

{ path:‘/user/:id/:username’ }

响应路由参数变化?监听路由url地址栏变化***************************

1.使用watch监听路由对象

watch:{
  $route(to,from){
    to--->即将进入的路由params对象,可以获取到最新的路由参数
    to.params存放着最新动态路径参数
    from--->正在离开的路由
  }
}

2.使用组件内导航守卫 beforeRouteUpdate 组件更新触发

beforeRouteUpdate(to,from,next){
    to--->即将进入的路由
    to.params存放着最新动态路径参数
    from--->正在离开的路由
}
  • 注意:使用created钩子获取路由对象参数只能获取到最初进入组件内路由的参数(因为只执行一次))
编程式导航进行页面跳转

$router.push()           会在浏览器产生一条历史记录
$router.replace()       不会在浏览器产生历史记录
$router.go(num)        前进或者后退几个页面
window.open();
location.assign();       push相似 会在浏览器产生一条历史记录
location.replace();      页面替换 不会在浏览器产生历史记录

编程式导航传参***********************

name params      一次性数据携带 参数不会拼接在地址栏 刷新页面数据会丢失
path query          刷新页面数据不会丢失 参数拼接在地址栏
name query        刷新页面数据不会丢失 参数拼接在地址栏

路由模式 hash history 区别?************************
  1. hash会在地址栏拼接#,路由路径会拼接在#后面,
    history地址栏正常
  2. hash原理是利用hashchange事件,可以通过newURL获取最新的路径,通过oldURL获取原始路径
    history原理是利用history对象中的一些api,pushState,replaceState,go,back,forward方法
  3. hash刷新页面会重新加载路由对应的组件,不会对后端产生影响
    history刷新页面会重新请求服务器,一般报错404。
  4. hash支持低版本的浏览器
    history不支持低版本浏览器,利用h5新增api pushState方法
导航守卫
  1. 全局守卫
    • 全局前置守卫:用户身份验证,做路由拦截(判断去的路由是否正确,是则继续向下,否则去正确的路由,可代替重定向)
      router.beforeEach((to,from,next)=>{ next(); })

    • 全局后置守卫:(不接受next(),也不改变导航本身,没大用)
      router.afterEach((to,from)=>{ })

      to---->即将进入的路由
      form—>正在离开的路由
      next() 拦截路由是否继续向下执行

  2. 路由独享守卫:进入该路由时候触发,做路由拦截
    • beforeEnter(to,from,next){ next();}
  3. 组件内导航守卫
    三者区别:this指向获取组件实例
    • beforeRouterEnter(to,from,next){ }
      进入组件时候触发,next((vm)=>{ vm---->组件实例 })
      this指向windows全局对象 ,此时无法获取组件实例
    • beforeRouteUpdate(to,from,next){ }
      路由发生改变 , 但是复用该组件时候触发 /user/1/terry
      this指向组件实例(因为被创建了实例)
    • beforeRouteLeave(to,from,next){}
      离开路由时候触发
      this指向组件实例
vuex*****************************

状态管理模式 ,维护公共状态的大型项目

A组件中分发工作(发起异步请求)—>获取数据—>提交突变(将数据提交给突变 )
通过突变修改状态 其他页面就可以渲染数据

  let vuex = {
    state:{},      类似data 存储状态/数据
    getters:{},    类似于computed 对state处理后再进行返回
    mutations:{},  突变--->同步操作 修改state唯一一种方式
    actions:{},    动作--->异步操作 获取数据后提交给突变
    modules:{}     分模块仓库 
  }
辅助函数
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.6.2/vuex.js"></script>
</head>
<body>
  <div id="app">
    <!-- 获取状态 $store.state/getters,
    没有辅助函数的写法:
    {{$store.state.public}}
    {{$store.getters.Upper}}
    {{$store.state.token}}
    <button @click="$store.commit('SET_TOKEN','ejhwksdfdskjfhsdkhgkasdjflas')">提交突变</button>
    <button @click="$store.dispatch('login',{username:'admin1',password:123321})">分发动作</button>
     -->
    
    <!--  若为辅助函数的写法 -->
    {{public}}
    {{token}}
    <button @click="SET_TOKEN('假的token')">提交突变</button>
    <button @click="login({username:'admin1',password:123321})">分发动作</button>
   
  </div>


  <script>
   // 引入辅助函数从Vuex中
   let {mapState,mapGetters,mapActions,mapMutations} = Vuex;
   // 1.声明状态机配置项 
   let storeConfig = {
      //类似于data 存储公共状态 存储数据
      state:{
        public:'hello vuex',
        token:""
      },

      // 类似于计算属性 对state中数据进行处理然后再返回
      getters:{
        Upper(state){
          return state.public.toUpperCase();
        }
      },

      // 突变 同步操作 修改state中的数据的唯一一种方式
      mutations:{
        SET_TOKEN(state,payload){
          // state是vuex默认提供的 payload载荷 提交突变传参 payload接收突变传递参数
          state.token = payload
        },
      },

      // 动作 异步操作 
      actions:{
        // 登录获取token 提交突变 把token传给突变 突变-->设置给state中token
        login(sto,payload){
          // sto类仓库对象 默认提供 commit提交突变  dispacth
          // 假设发送完成异步请求
          let token = 'esfkhsdakfjlskjfdlsjglkasdkfskfdasdasfksadf';//token就是后端获取数据token
          // 将token提交给突变
          sto.commit('SET_TOKEN',token);
          console.log(sto,payload,'22222');
        }
      }
    };


    // 2.创建状态机实例 
    let store = new Vuex.Store(storeConfig);

    //3.注册状态机实例
    new Vue({
      el:"#app",
      store,
      data:{      },
      methods:{
        //辅助函数的写法
        ...mapMutations(['SET_TOKEN']),
        ...mapActions(['login']),
        // 相当于 login(){}
      }computed:{
        // 引入辅助函数所对应的状态/数据 mapState('命名空间',['','',''])
        ...mapState(['public','token']),
        ...mapGetters(['Upper'])
       },
    })
  </script>
</body>
  • 46
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值