vue基础

vue的安装

  1. 安装node.js
  2. 安装npm:npm install -g cnpm --registry=https://registry.npm.taobao.org
  3. 使用cnpm安装vue:cnpm install vue -g
  4. 安装vue命令行工具:cnpm install vue-cli -g
  5. 安装vue-devtools调试工具:
  6. 创建vue脚手架:vue init webpack myproject
    1. vue init webpack myproject
    2. cd myproject // 进入目录
    3. cnpm install // 安装依赖
    4. cnpm run dev // 开启服务
    - src 主开发目录,所有的单文件组件都会放在这个目录下
    - static 项目静态目录,所有的css、js都会放在这个文件夹下
    - dist 项目打包发布文件夹,最后要上线单文件夹项目都在这个文件夹中 - node_modules node的包目录
    - config 配置目录
    - build 项目打包时依赖的目录
    
  7. 常用命令
    1. v-html:将内容按照html格式进行插入
    2. v-text:将内容按照文本格式进行插入,但会覆盖原有标签内的内容,不会有加载的闪烁问题
    3. v-cloak:解决加载时的闪烁问题
  8. 绑定属性:v-bind 或者 直接写 冒号 如果我们需要设置的模板变量是一个属性,比如a标签的href属性
  9. 绑定事件:v-on 或者 @ 符号:给元素绑定对应事件。
  10. 表单绑定 v-model:
  11. 动态绑定

当某些情况下,无法确定表单中所代表的属性值,可以使用v-bind进行动态绑定,v-> model获取到的表单输入 此时则是我们定义的v-bind属性值

  1. v-if 指令用于条件性的渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候渲染
  2. 与v-if不同的是: v-show 的元素始终会被渲染并保留在 DOM 中 v-show 只是简单地切换元素的 CSS 属性 display
  3. Vue实例生命周期
- beforeCreate 数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象 
- created 数据已经绑定到了对象实例,但是还没有挂载对象
- beforeMount 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的 $el属性
---------------------------------------------------------------------
$el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创建这个html片段, 准备注入到我们vue实例指明的el属性所对应的挂载点 -------------------------------------------------------------------------- 
- mounted 将$el的内容挂载到了el,相当于我们在jQuery执行了$(el).html($el),生成页面上真正的dom
-------------------------------------------------------

上面我们就会发现页面的元素和我们$el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并进 行各种操作 ----------------------------------------------------------------------------

- beforeUpdate 数据发生变化时调用
- updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子
- beforeDestroy Vue实例销毁前 - destroyed Vue实例销毁后
  1. 过滤器
{{ 0 | myfilter }}


  //过滤器
  filters: {
            myfilter: function (value) {

                if(value==1){
                    return '已支付';
                }else{
                    return '未支付';
                }
      
    }
  },
  1. 子组件
    components: {
       // 'mh_test':mh_test
  },
  1. 计算属性
data () {
      return {
        message:'hello world 你好',
        },
    //计算属性
    computed:{

        reverse_message:function(){

            return this.message.split('').reverse().join('')

        }

    },
  1. 监听属性
    //监听属性
    watch : {
        kilometers:function(val) {
            this.kilometers = val;
            this.meters = this.kilometers * 1000
        },
        meters : function (val) {
            this.kilometers = val/ 1000;
            this.meters = val;
        }
    },
  1. 函数
data () {
      return {
            datalist:[],
        },

    totalCount : function(){
      var total = 0;
      for (var i = 0,l = this.datalist.length;i<l;i++) {
        total+=this.datalist[i].num;
      }
      return total;
    },
  1. 样式
<style>

.on {
			background: #cdcbff;
		}
.off {
    background: #fefdff;

}

</style>

一 路由拦截器

项目中,用户不登录只能去登录页面,不可以访问别的页面,这种情况的话,可以用路由拦截器

  1. 先说下区分下route与router
  • route:相当于当前正在跳转的路由对象。可以从里面获取name,path,params,query等。
    如取路由带来的参数:this.$route.params
  • router:VueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象,例如history对象。。。经常用的跳转链接就可以用this.$router.push,和router-link跳转一样
//带参数路由跳转
this.$router.push({path:'/home',params:{id:123}})
//取参数
this.$route.params.id //123
  1. 言归正传说路由拦截
//路由拦截器
//to为向后走的路由对象,包括路由的完整信息
//from为从哪跳来的路由对象
//next()控制路由向下走,重新定义路由跳转的路由next(‘路由路径)
/** 验证用户是否登录 **/
router.beforeEach((to,from,next) => {
    if(to.matched.some( m => m.meta.auth)) {
        // console.log("先判断是否登录");
        if(to.name=='Login'){
            next();
        }else{
          if(localStorage.getItem('token')){

          //访问服务器缓存数据,判断当前token是否失效
            Vue.http.get("http:xxxx/Login/UserIsLogin?token="+localStorage.getItem('token')+"&url="+to.name,{withCredentials: true}).then(response => response.json()).then(num => {
                    // console.log('是否登录',num);
                    if(num.code==1001){
                        next();
                    }else{
                        alert('您的token已超时,请重新登录');
                        next('/Login');
                    }
            })
          }else{
            next('/Login');
          }

        }
   } else {
        console.log("请先登录");
        next()
    }
})

//或者简洁的可以:
router.beforeEach((to,from,next)=>{
    if(localStorage.getItem('token')||to.name=='login'){
          next()
    }else{
          //如果没有token值,则跳到登录页面
          next({path:'/login'})
    }
   next()
})

二 请求拦截

统一处理错误及配置请求信息

  1. 安装 axios , 命令: npm install axios --save-dev
  2. 在根目录的config目录下新建文件 axios.js ,内容如下:
    import axios from ‘axios’
    // 配置默认的host,假如你的API host是:http://api.htmlx.club
    axios.defaults.baseURL = ‘http://api.htmlx.club’
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  return config
}, function (error) {
  // 对请求错误做些什么
return Promise.reject(error)
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error)
});

请求拦截 根据自己的需求加对应的代码

三、父子组件传参

  • 父组件
<template>
    <div>
         <h1>hello</h1>
         <v-child :msg='msg' @cmsg="cmsg"></v-child>
         {{childmsg}}
    </div>
</template>

<script>
import child from '@/components/child'
export default {
    name:'parent',
    data:function(){
        return {
            'msg': 'hello everybody',
            childmsg: ''
        }
    },
    methods:{
        cmsg:function(obj){
            this.childmsg =obj
        }
    }
    ,
    components:{
        'v-child': child
    }
}
</script>
  • 子组件
<template>
    <div>
       
            {{msg}}
           <button @click="toparent">传值到父组件</button>
    </div>
</template>

<script>
export default {
    name:'child',
    data:function(){
        return {

        }
    },
    methods:{
        toparent:function(){
            this.$emit("cmsg", "来自子组件的数据")
        }
    }
    ,
    props:['msg']
}
</script>

四、Vuex状态管理

  • 使用场景:大型项目
  • 安装: cnpm install --save vuex
  • 使用:
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import axios from 'axios'
    import Vuex from 'vuex'
    
    Vue.config.productionTip = false
    Vue.prototype.axios = axios
    Vue.use(Vuex);
    
    // vuex的配置
    const store = new Vuex.Store({
        
    });
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      // 使用vuex.任何组件使用同一个store的数据时,只要store的数据变化,对应的组件也会更新。
      store: store,
      components: { App },
      template: '<App/>',
    })
    
  • 任何组件使用同一个store的数据时,只要store的数据变化,对应的组件也会更新。
  • 数据保存在vuex的state字段内。
    // vuex的配置
    const store = new Vuex.Store({
      state:{
        // 计数器。在任何组件内,可以直接通过$store.state.count读取
        count: 0
      }
    });
    
    • 可以直接通过$route.state.count读取。也可以用一个计算属性来显示
    <template>
        <div>
          {{ $store.state.count }}
          <br>
          {{ count }}
        </div>
    </template>
    
    <script>
        export default {
            name: "x1",
          computed:{
              count: function () {
                // 通过计算属性显示
                return this.$store.state.count;
              }
          }
        }
    </script>
    
    • store的数据只能读取,不能手动修改。改变方式是:定义mutations.
    • 在组件内,通过this.#store.commit()方法来执行在mutations中定义的函数。
    • mutations可以接受第二个参数。
        // vuex的配置
        const store = new Vuex.Store({
          state:{
            // 计数器。在任何组件内,可以直接通过$store.state.count读取
            count: 0
          },
          mutations:{
            increment(state){
              state.count++;
            },
            // ES6: n=1是当参数没有传值时,使用的默认值
            // 当一个参数不够用时,可以传入一个对象
            decrement(state, n=1){
              state.count-=n;
            }
          }
        });
    
      {{ count }}
      <br>
      <button v-on:click="handlIncrement">+1</button>
      <button v-on:click="handlDecrement">-2</button>
      
      
      methods:{
          handlIncrement:function () {
            this.$store.commit("increment");
          },
        handlDecrement:function () {
          this.$store.commit('decrement', 2)
        }
      }
    
    • 提交mutation的另一种方式是直接使用包含type属性的对象。比如:
    // vuex的配置
    const store = new Vuex.Store({
      state:{
        // 计数器。在任何组件内,可以直接通过$store.state.count读取
        count: 0
      },
      mutations:{
        increment(state, params){
          state.count+= params.count;
        }
      }
    });
    
      methods:{
          handlIncrement:function () {
            // this.$store.commit("increment");
            this.$store.commit({
              type:'increment',
              count: 10
            })
          }
      }
    

高级用法。getters、actions、modules

  • 仅仅获取小于10的数字。常规用法
// main.js
// vuex的配置
const store = new Vuex.Store({
  state:{
    list: [1, 5, 8, 10, 30, 50]
  },
  mutations:{
    
  }
});
<template>
    <div>
      <h3>vuex高级用法</h3>
    <li v-for="i in list">{{i}}</li>
    </div>
</template>

<script>
    export default {
        name: "vuex2",
      computed:{
          list:function () {
            // 过滤数组,仅仅显示小于10的数字
            return this.$store.state.list.filter(item => item < 10);
          }
      }
    }
</script>

<style scoped>

</style>

  • getters的使用
const store = new Vuex.Store({
  state:{
    count++,
    list: [1, 5, 8, 10, 30, 50]
  },
  getters:{
    filterList:state=>{
      return state.list.filter(item => item < 10);
    },
    listCount:function (state, getters) {
      // getters的依赖,一个getters可以依赖于另一个getters
      return getters.filterList.length;
    }
  }
  ,
  mutations:{
    increments(state){
        state.count++;
    }
  }
});
  • actions的使用
    • 多此一举的操作。actions中context.commit('increment', {count: 2});。vue组件中this.$store.dispatch('increment')
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import Vuex from 'vuex'

Vue.config.productionTip = false
Vue.prototype.axios = axios
Vue.use(Vuex);

// vuex的配置
const store = new Vuex.Store({
  state:{
    // 计数器。在任何组件内,可以直接通过$store.state.count读取
    count: 0,
    list: [1, 5, 8, 10, 30, 50]
  },
  getters:{
    filterList:state=>{
      return state.list.filter(item => item < 10);
    },
    listCount:function (state, getters) {
      // getters的依赖
      return getters.filterList.length;
    }
  }
  ,
  mutations:{
    increment(state, params){
      state.count+= params.count;
    },
    decrement(state, n=1){
      state.count-=n;
    }
  },
  actions:{
    increment(context){
      context.commit('increment', {count: 2});
    }
  }
});

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  // 使用vuex.任何组件使用同一个store的数据时,只要store的数据变化,对应的组件也会更新。
  store: store,
  components: { App },
  template: '<App/>',
})


<template>
    <div>
      <h3>vuex高级用法</h3>
      {{listCount}}
    <li v-for="i in list">{{i}}</li>
      <br>
      {{this.$store.state.count}}
      <br>
      <button v-on:click="handleActionIncrement">+2</button>
    </div>
</template>

<script>
    export default {
        name: "vuex2",
      methods:{
          handleActionIncrement:function () {
            this.$store.dispatch('increment');
          }
      },
      computed:{
          list:function () {
            // 过滤数组,仅仅显示小于10的数字
            // return this.$store.state.list.filter(item => item < 10);
            return this.$store.getters.filterList;
          },
        listCount:function () {
          return this.$store.getters.listCount;
        },

      }
    }
</script>

<style scoped>

</style>

  • module将一个store分割到不同的模块。
const moduleA = {
  state:{
    msg: 'moduleA'
  },
  mutations:{},
  actions:{},
  getters:{}
};

const moduleB = {
  state:{
    msg: 'moduleB'
  },
  mutations:{},
  actions:{},
  getters:{}
};

// vuex的配置
const store = new Vuex.Store({
  state:{
    // 计数器。在任何组件内,可以直接通过$store.state.count读取
    count: 0,
    list: [1, 5, 8, 10, 30, 50],
    a: moduleA,
    b: moduleB
  },
  getters:{
    filterList:state=>{
      return state.list.filter(item => item < 10);
    },
    listCount:function (state, getters) {
      // getters的依赖
      return getters.filterList.length;
    }
  }
  ,
  mutations:{
   
  },
  actions:{
    
  }
});
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值