Vue学习记录(三)——脚手架的使用和Vuex

Vue脚手架

安装使用

  1. 运行安装脚手架
    npm i vue-cli -g
  2. 创建vue
    vue create xxx(创建的名字)
  3. 运行
    npm run serve

关于不同版本的Vue

vue.js和vue.runtime.xxx.js的区别
  1. vue.js是完整版的Vue,包含核心功能+模板解析器
  2. vue.runtime.xxx.js是运行版的Vue,只包含核心功能,没有模板解析器
  3. vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容

ref属性

  1. vue中用来给元素或子组件注册引用信息(id的替代)
  2. 应用在html标签上是获取真实dom元素,在组件标签上是获取组件的实例对象
  3. 使用: <h1 ref='xxx'></h1>
  4. 获取:this.$refs.xxx

配置项props

功能:让组件接收外部传入的数据

传递数据

<Demo name='xxx'></Demo>

接收数据
  1. 只接收
    props: ['name']
  2. 限制类型
     props: {
         name: String
     }
    
  3. 限制类型、限制必要性、指定默认值
     props: {
         name: {
             type: String, //类型
             required: true, //必要性
             default: 'testName' //默认值
         }
     }
    
注意事项
  1. props只读,Vue底层会监视,不可修改,若要修改,可以复制props中的数据,在对复制的数据进行修改
  2. props传过来的值如果是对象类型的,修改对象中属性的值时Vue不会报错,但不推荐这么做
适用范围
  1. 父组件=>子组件 直接向子组件传值
  2. 子组件=>父组件 需要父组件先向子组件传递函数,子组件通过函数传参的方式向父组件传值

mixin混入

  1. 功能:把多个组件共用的配置提取成一个混入对象
  2. 使用:
     //定义
     export const xx = {
         data(){...}
         methods:{...}
     }
     //使用
     //(1)局部混入:
     import xx from xxxx;
     mixins:['xx']
     //(2)全局混入
     Vue.mixin(xxx);
    

plugins插件

  1. 功能:用于增强Vue
  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个参数及以后是插件使用者传递的数据
  3. 定义插件:
    对象.install = function(Vue, options){
        Vue.filter(...)
        Vue.directive(...)
        Vue.mixin(...)
        Vue.prototype.$myMethod = function(){...}
        Vue.prototype.$myProperty = function(){...}
    }
    
  4. 使用插件:Vue.use()

scoped样式

  1. 作用:让样式在局部生效,防止冲突
  2. 使用:<style scoped></style>

组件化编码流程

  1. 拆分静态组件:组件按照功能点进行拆分,命名不要与html元素冲突
  2. 实现动态组件:
    • 若是一个组件在用:放在组件自身
    • 若是多个组件在用:放在共同的父组件上(状态提升
  3. 实现交互:从绑定事件开始

组件的自定义事件

  1. 组件中的通信方式,适用于:子组件 => 父组件,事件的回调要在父组件中
  2. 绑定自定义事件
    • 方法一:在父组件中<Demo @自定义名xxx称="xxx"></Demo><Demo v-on:自定义名称="xxx"></Demo>
    • 方法二:在父组件中
    <Demo ref="xxx"></Demo>
    ...
    mounted(){
        this.$refs.xxx.$on(绑定的自定义名称, 参数)
    }
    
    • 若想让自定义事件只触发一次,可以使用once修饰符或者$once方法
  3. 触发自定义事件:
     this.$emit(绑定的自定义名称, 数据)
    
  4. 解绑自定义事件:
     this.$off('aaa') //解绑一个自定义事件
     this.$off(['aaa', 'bbb']) //解绑多个
     this.$off() //解绑所有
    
  5. 组件上可以绑定原生dom事件(如:click),需要使用native修饰符
     <Parent ref="parent" @click.native="show"></Parent>
    
  6. 注意:通过this.$refs.xxx.$on(绑定事件的名称,回调)绑定自定义事件时,回调要么配置在methods中,要么使用箭头函数,防止因为this的指向出现问题

全局事件总线(GlobalEventBus)

  1. 一种组件间通信的方式,适用于任意组件间通信
  2. 安装全局事件总线:
     new Vue({
         ...
         beforeCreated(){
             Vue.prototype.$bus = this; //安装全局事件总线,$bus就是当前应用的vm
         },
         ...
     })
    
  3. 使用事件总线:
    1. 接收数据:
    methods(){
        //方法一
        demo(data){
            ...
        }
        ...
        mounted(){
            this.$bus.$on('xxx', this.demo)
        }
        //方法二
        mounted(){
            this.$bus.$on('xxx', ()=>{
                ...
            })
        }
    }
    
    1. 提供数据:this.$bus.$emit('xxx', 数据)
  4. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件
     beforeDestroy(){
         this.$bus.$off('xxx')
     }
    

消息订阅与发布(pubsub)

  1. 一种组件间通信的方式,适用于任意组件之间通信
  2. 使用:
    • 安装 npm i pubsub-js
    • 引入 import pubsub from 'pubsub-js'
    • 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
    methods(){
        demo(data){...}
        ...
        mounted(){
            //订阅类似于定时器,需要给一个名称方便销毁
            this.pubId = pubsub.subscribe('xx', this.demo);//订阅消息
        }
    }
    
    • 提供数据:
    pubsub.publish('xx',数据)
    
    • 最好在beforeDestroy钩子中,使用pubsub.unsubscribe(pubId)销毁订阅

$nextTick()

  1. 使用:this.$nextTick(回调函数)
  2. 作用:在下一次DOM更新结束后执行其指定的回调
  3. 使用时间:当改变数据后,基于要更新的dom进行某些操作时,要在nextTick所指定的回调函数中执行

过渡与动画

作用:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式名
注:过渡动画前提是组件|元素务必有v-if|v-show指令才可以进行过渡

使用方法
  1. 元素进入:
    • v-enter:进入的起点
    • v-enter-active:进入过程中
    • v-enter-to:进入的终点
  2. 元素离开:
    • v-leave:离开的起点
    • v-leave-active:离开过程中
    • v-leave-to:离开的终点
  3. 使用transition包裹要过渡的元素,并配置name属性(单个)
    // 可以通过appear设置节点在初始渲染的过渡
    <transition name="xxx" appear>
        ...
    </transition>
    
  4. 若有多个元素需要过渡,需要使用transition-group,且每个元素都需要配置key值
  5. 可以引入外部包来增强使用效果(如:animate.css),具体的使用可以去npm官网查看
    npm install animate.css
    
图解

vue官网图片

脚手架配置代理

在vue.config.js中配置代理规则

方法一
  1. 使用:
    devServer: {
       proxy: 'http://localhost:xxxx'
    }
    
  2. 优点:配置简单,请求资源时直接发给前端(8080)即可
  3. 缺点:不能配置多个代理,不能灵活控制请求是否走代理
  4. 工作方式:优先从前端资源查找,若前端资源不存在,则转发给服务器
方法二
  1. 使用:
    devServer: {
        proxy: {
            '/api_1': { //匹配所有以api_1开头的路径
                target: 'http://localhost:aaa', //代理目标的基础路径
                ws: true, //用于支持websocket
                changeOrigin: true, //用于控制请求头中的host值(若为false,则req.get(host)获得的host为本机端口好,为true则为代理的端口号,默认为true)
                pathRewrite: {'^/api_1', ''} //重写路径,必写
            },
            '/api_2': { //匹配所有以api_1开头的路径
                target: 'http://localhost:bbb', //代理目标的基础路径
                ws: true, //用于支持websocket
                changeOrigin: true, //用于控制请求头中的host值(若为false,则req.get(host)获得的host为本机端口好,为true则为代理的端口号,默认为true)
                pathRewrite: {'^/api_2', ''} //重写路径,必写
            }
        }
    }
    
  2. 优点:可以请求多个资源
  3. 缺点:比较繁琐,请求的资源地址需要加前缀

axios请求资源

使用:

//发起get请求
axios.get('url',{params:{/*参数*/}}).then(callback)
//发起post请求
axios.get('url',{/*参数*/}).then(callback)
//具体发起请求
axios({
   method: 'GET', //'POST'
   url: '',
   params: {}, //get
   data: {} //post
}).then(function(res){
   console.log(res.data)
})

vue-resource插件(了解)

  1. 安装插件: npm install vue-resource
  2. 引入:
    import vueResource from 'vue-resource';
    Vue.use(vueResource);
    
  3. 使用: this.$http.get()axios.get()用法一样

插槽

  1. 作用:让父组件可以向子组件指定位置插入html结构,是一种组件间通信的方式,适用于父组件=>子组件
  2. 分类:默认插槽、具名插槽、作用域插槽
默认插槽
//父组件中
<Category>
    <div>html结构</div>
</Category>
//子组件中
<template>
    <div>
        <slot>插槽默认内容</slot>
    </div>
</template>
具名插槽
//父组件中
<Category>
    <template slot="xxx1">
        <div>html结构</div>
    </template>
    <template slot="xxx2">
        <div>html结构</div>
    </template>
</Category>
//子组件中
<template>
    <div>
        <slot name="xxx1">插槽默认内容</slot>
        <slot name="xxx2">插槽默认内容</slot>
    </div>
</template>
作用域插槽
  1. 条件:数据在组件本身,但根据数据生成的结构需要组件的使用者来决定(games数组在Category组件中,但使用数据所遍历出来的结构由App组件决定)
  2. 使用:
//父组件
<Category>
    <template scope="{games}">
        <ul>
            <li v-for="(g, index) in games" :key="index"></li>
        </ul>
    </template>
</Category>
<Category title="游戏">
    <template slot-scope="{games}">
        <h4 v-for="(g, index) in games" :key="index">{{ g }}</h4>
    </template>
</Category>
//子组件
<template>
    <div class="category">
        <h3>{{ title }}分类</h3>
        <slot :games="games">default</slot>
    </div>
</template>
<script>
export default {
    name: 'Category',
    props: ['title'],
    data() {
        return {
            games: ['LOL', 'CF', 'Rise of the Tomb', 'PUBG']
        }
    }
}
</script>

Vuex

概念

在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间的通信方式,适用于任意组件间通信

图解

vue官网图片

何时使用

当多个组件需要共享数据时

搭建Vuex环境

  1. 创建文件:src/store/index.js
     import Vue from 'vue';
     import Vuex from 'vuex';
     Vue.use(Vuex);
     const actions = {};
     const mutations = {};
     const state = {};
     export default new Vuex.Store({
         actions,
         mutations,
         state
     })
    
  2. 在main.js创建vm时传入store配置项
     import store from './store';
     new Vue({
         el: '#root',
         store,
         render: h => h(App)
     })
    

使用

  1. 组件中读取vuex中的数据:$store.state.xxx
  2. 组件中修改vuex中的数据:$store.dispatch('action中的方法名', 数据)$store.commit('action中的方法名', 数据)
  3. 注:若没有网络请求或其他业务逻辑,组件中可以直接越过actions,不写dispatch,直接写commit
  4. getters使用(当state中的数据需要经过加工后再使用时,可以使用getters加工)
     ...
     const getters = {
         xxx(state){
             return state.aaa
         }
     }
    

4个map方法的使用

mapState

用于帮助映射state中的数据为计算属性

computed(){
    // 借助mapState生成计算属性,对象写法
    ...mapState({sum:'sum', school:'school', subject:'subject'})
    // 借助mapState生成计算属性,数组写法
    ...mapState(['sum', 'school', 'subject'])
}
mapGetters

用于帮助映射getters中的数据为计算属性

computed(){
    // 借助mapGetters生成计算属性,对象写法
    ...mapGetters({func:'func'})
    // 借助mapGetters生成计算属性,数组写法
    ...mapGetters(['func'])
}
mapActions

用于借助mapActions生成对应的方法,方法中会调用dispatch去联系actions

methods(){
    // 借助mapActions生成,对象写法
    ...mapActions({func:'func'})
    // 借助mapActions生成,数组写法
    ...mapActions(['func'])
}

注:使用时需要传递参数,在模板中绑定事件时传递参数,否则参数是事件对象

mapMutations

用于借助mapMutations生成对应的方法,方法中会调用commit去联系mutations

methods(){
    // 对象
    ...mapMutations({increment:'Increment', decrement:'Decrement'})
    // 数组 同上
}

注:使用时需要传递参数,在模板中绑定事件时传递参数,否则参数是事件对象

模块化+命名空间

  1. 目的:让代码更好维护,多种数据分类更加明确
  2. 修改store.js
const a = {
    namespaced: true, //开启命名空间
    state: {
        x: 1
    },
    actions: {
        actionsExample(context, value){
            context.commit('mutationsExample', value);
        }
    },
    mutations: {
        mutationsExample(context, value){
            console.log(context, value);
        }
    },
    getters: {
        //此处的state拿到的数据是上面的state里的数据,不是全局state里的数据
        gettersExample(state) {
            return state.personList[0].name;
        }
    }
}
const store = new Vuex.Store({
    modules: {
        a //在vuex中使用
    }
})
  1. 开启命名空间后,组件中读取state数据
// 方法一: 直接读取
this.$store.store.a.x
// 方法二: 借助mapState
...mapState('a', ['x'])
  1. 开启命名空间后,组件中读取getters数据
// 方法一
this.$store.getters['a/gettersExample']
// 方法二
...mapGetters('a', ['gettersExample'])
  1. 开启命名空间后,组件中调用dispatch
// 方法一 直接dispatch
this.$store.dispatch('a/actionsExample', data);
// 方法二 借助mapActions
...mapActions('a', {test:'actionsExample'})
// 若参数名和参数相同,可使用数组写法
...mapActions('a', ['actionsExample'])
  1. 开启命名空间后,组件中调用commit
// 方法一 直接commit
this.$store.commit('a/mutationsExample', data);
// 方法二 借助mapMutations
...mapMutations('a', {test:'mutationsExample'})
...mapMutations('a', ['mutationsExample'])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值