Advertisement

【前端系列笔记007】Vue(三)第四章第五章

阅读量:

第四章:Vue中的ajax

4.1 解决开发环境中Ajax跨域问题

方法一

vue.config.js中添加如下配置:

复制代码
    //开启代理服务器(方式一)
    devServer:{
    proxy:'http://localhost:5000'
    }
    
    
    js

说明:

  1. **优点:**配置简单,请求资源时直接发给前端(8080)即可
  2. **缺点:**不能配置多个代理,不能灵活地控制请求是否走代理
  3. **工作方式:**若按照上述配置代理,当请求了前端不存在的资源时,那么请求会转发给服务器(优先匹配前端资源)
方法二

编写vue.config.js配置具体代理规则:

复制代码
    //开启代理服务器(方式二)
    devServer:{
        proxy:{
            '/student':{//匹配所有以'/student'开头的请求路径
                target:"http://localhost:5000",//代理目标的基础路径
                pathRewrite:{'^/student':''},
                ws:true, //用于支持webSocket
                changeOrigin:true //默认为true,用于控制请求头中的host值,值为true时,服务器收到的请求头中的host为:localhost:5001,值为true时,服务器收到的请求头中的host为:localhost:8080
            },
            'car':{//匹配所有以'/car'开头的请求路径
                target: "http://localhost:5001",//代理目标的基础路径
                pathRewrite:{'^/car':''},
                ws:true, //用于支持webSocket
                changeOrigin:true //默认为true,用于控制请求头中的host值,值为true时,服务器收到的请求头中的host为:localhost:5001,值为true时,服务器收到的请求头中的host为:localhost:8080
            }
        }
    }
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/GNCASHUMRvhtwTDqcLe6gJO9mban.png)

说明:

  1. **优点:**可以配置多个代理,且可以灵活地控制请求是否走代理
  2. **缺点:**配置略显繁琐,请求资源时必须加前缀

4.2 github用户搜索案例

main.js

复制代码
    //引入Vue
    import Vue from "vue";
    //引入App
    import App from "./App";
    //关闭vue的生产提示
    Vue.config.productionTip=false
    //创建vm
    new Vue({
    el:"#root",
    render:h=>h(App),
    beforeCreate() {
        Vue.prototype.$bus=this
    }
    })
    
    
    js
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/7PiT4BaXt26nJVqyfHYrk9MWCvjU.png)

App.vue

复制代码
    <template>
      <div class="container">
    <Search></Search>
    <List></List>
      </div>
    </template>
    
    <script>
    // import 'assets/css/bootstrap.css'
    
    import Search from "./components/Search";
    import List from "./components/List";
    export default {
      name: "App",
      components: {List, Search}
    }
    </script>
    
    <style>
    
    </style>
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/JbLARM1yqWjt3nSiTHxPsXfN58rI.png)

List.vue

复制代码
    <template>
      <div class="row">
    <!--  展示用户列表  -->
    <div v-show="info.users.length" class="card" v-for="user in info.users" :key="user.id">
      <a :href="user.html_url" target="_blank">
        <img :src="user.avatar_url" style='width: 100px'/>
      </a>
      <p class="card-text">{{user.login}}</p>
    </div>
    <!--  展示欢迎词  -->
    <h1 v-show="info.isFirst">欢迎使用!</h1>
    <!--  展示加载中  -->
    <h1 v-show="info.isLoading">加载中...</h1>
    <!--  展示错误信息  -->
    <h1 v-show="info.errMsg">{{info.errMsg}}</h1>
      </div>
    </template>
    
    <script>
    export default {
      name: "List",
      data(){
    return {
      info:{
        isFirst:true,
        isLoading:false,
        errMsg:"",
        users:[]
      }
    }
      },
      mounted() {
    this.$bus.$on('updateListData',(dataObj)=>{
      console.log(dataObj)
      this.info={...this.info,...dataObj}
    })
      },
      beforeDestroy() {
    this.$bus.$off('updateListData')
      }
    }
    </script>
    
    <style scoped>
    .album {
      min-height: 50rem; /* Can be removed; just added for demo purposes */
      padding-top: 3rem;
      padding-bottom: 3rem;
      background-color: #f7f7f7;
    }
    
    .card {
      float: left;
      width: 33.333%;
      padding: .75rem;
      margin-bottom: 2rem;
      border: 1px solid #efefef;
      text-align: center;
    }
    
    .card > img {
      margin-bottom: .75rem;
      border-radius: 100px;
    }
    
    .card-text {
      font-size: 85%;
    }
    </style>
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/YUMuBG2cWlxq30THwdkmn8E7pNfJ.png)

Search.vue

复制代码
    <template>
      <section class="jumbotron">
    <h3 class="jumbotron-heading">Search Github Users</h3>
    <div>
      <input type="text" placeholder="enter the name you search" v-model="keyWord"/>&nbsp;
      <button @click="searchUsers">Search</button>
    </div>
      </section>
    </template>
    
    <script>
    import axios from 'axios'
    
    export default {
      name: "Search",
      data(){
    return{
      keyWord:""
    }
      },
      methods:{
    searchUsers() {
      //请求前更新list数据
      this.$bus.$emit('updateListData',{
        isFirst:false,
        isLoading:true,
        errMsg:'',
        users:[]
      })
    
      axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
          response=>{
            console.log('请求成功',response.data)
            //请求成功后
            this.$bus.$emit('updateListData',{
              isLoading:false,
              errMsg:'',
              users:response.data.items
            })
          },
          error=>{
            console.log('请求失败了',error.message)
            //请求失败后
            this.$bus.$emit('updateListData',{
              isLoading:false,
              errMsg:error.message,
              users:[]
            })
          }
      )
    }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/CtgUpdeYwFPjk35TJn70SHu6Ml2z.png)

4.3 插槽

**作用:**让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于:父组件=== >子组件

**分类:**默认插槽、具名插槽、作用域插槽

使用方式:

复制代码
1. 

默认插槽:

复制代码
    父组件中的:

    <Category>
    	<div>html结构...</div>
    </Category>
    子组件中:
    <template>
    	<div>
            <!--定义插槽-->
            <slot>插槽内容...</slot>
        </div>
    </template>
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/wlbuCv8xStOQ9cBmAr4EHj6g0iRW.png)

具名插槽:

复制代码
    父组件中:

    <Category>
    	<template slot="center">
        	<div>html结构1</div>
        </template>
        
        <template v-slot:footer>
        	<div>html结构2</div>
        </template>
    </Category>
    子组件中:
    <template>
    	<div>
            <!--定义插槽-->
            <slot name="center">插槽默认内容...</slot>
            <slot name="footer">插槽默认内容...</slot>
        </div>
    </template>
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/Xx6ubdpCQyKGRmheVNzLj3J5r7ci.png)

作用域插槽:

理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。 (games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)
具体编码:

复制代码
    父组件中的:

    <Category title="游戏">
      <template scope="youxis">
        <ul>
          <li v-for="(item,index) in youxis.games" :key="index">{{item}}</li>
        </ul>
      </template>
    </Category>
    <Category title="游戏">
      <template scope="youxis">
        <ol>
          <li v-for="(item,index) in youxis.games" :key="index">{{item}}</li>
        </ol>
        <h4>{{youxis.msg}}</h4>
      </template>
    </Category>
    
    
    子组件中:
    <template>
    <div class="category">
      <h3>{{title}}分类</h3>
      <slot :games="games" :msg="msg">我是默认的内容</slot>
    </div>
    </template>
    
    <script>
    export default {
      name: "Category",
      props:['title'],
      data() {
        return {
          games:['红色警戒','LOL','cf','超级玛丽'],
          msg:"你好!"
        }
      }
    }
    </script>
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/SgFjWi6ynuZ0fNC8kYcarvQdBsKp.png)

第五章:vuex

5.1 理解vuex

5.1.1 vuex是什么
  1. 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的 共享状态进行集中式的管理(读写),也是一种组件间通信的方式,且适用于任意组件间通信
  2. Github地址:https://github.com/vuejs/vuex
5.1.2 什么时候使用Vuex
  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态
5.1.3 Vuex工作原理图
在这里插入图片描述

5.2 搭建vuex环境

创建文件:src/store/index.js

复制代码
    //该文件用于创建vuex中最为核心的store

    
    //引入Vuex
    import Vuex from "vuex";
    //引入vue核心库
    import Vue from "vue";
    
    //使用vuex插件
    Vue.use(Vuex)
    
    //准备actions---用于响应组件中的动作
    const actions={}
    
    //准备mutations---用于操作数据(state)
    const mutations={}
    
    //准备state---用于存储数据
    const state={}
    
    //创建并暴露store
    export default new Vuex.Store({
    actions:actions,
    mutations,
    state
    })
    
    
    js
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/5k9ZVTfNI3QwGFjUd4L1DPK7zgsu.png)

main.js中创建vm时传入store配置项

复制代码
    //引入Vue

    import Vue from "vue";
    //引入App
    import App from "./App";
    //引入store
    import store from "./store";
    //关闭vue的生产提示
    Vue.config.productionTip=false
    //创建vm
    new Vue({
    el:"#root",
    render:h=>h(App),
    store,
    beforeCreate() {
        Vue.prototype.$bus=this
    }
    })
    
    
    js
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/f6ea1RsrPB2MvOxmuXSQADdbNc5l.png)

5.3 基本使用

初始化数据,配置actionsmutations,操作文件store.js

index.js

复制代码
    //该文件用于创建vuex中最为核心的store

    
    //引入Vuex
    import Vuex from "vuex";
    import Vue from "vue";
    
    //使用vuex插件
    Vue.use(Vuex)
    
    //准备actions---用于响应组件中的动作
    const actions={
    /*add(context,value){
        context.commit('ADD',value)
    },
    jian(context,value){
        context.commit('JIAN',value)
    },*/
    jiaOdd(context,value){
        if (context.state.sum%2){
            context.commit('ADD',value)
        }
    }
    }
    
    //准备mutations---用于操作数据(state)
    const mutations={
    ADD(state,value){
        state.sum+=value
    },
    JIAN(state,value){
        state.sum-=value
    }
    }
    
    //准备state---用于存储数据
    const state={
    sum:0,//当前的和
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    actions:actions,
    mutations,
    state
    })
    
    
    js
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/lzvNjSAPyGuBXmEZ23gOH5V4irba.png)

组件中读取vuex中的数据:$store.state.sum

组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)$store.commit('mutations中的方法名',数据)

**备注:**若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

在组件中的使用方法:

Count.vue

复制代码
    <template>
    <div>
      <h1>当前求和为:{{$store.state.sum}}</h1>
      <select v-model.number="n">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
      </select>
      <button @click="increment">+</button>
      <button @click="decrement">-</button>
      <button @click="incrementOdd">当前求和为奇数再加</button>
      <button @click="incrementWait">等一等再加</button>
    </div>
    </template>
    
    <script>
    export default {
      name: "Count",
      data() {
    return {
      n:1,//用户选择的数字
    }
      },
      methods:{
    increment(){
      //this.$store.dispatch('add',this.n)
      this.$store.commit('ADD',this.n)
    },
    decrement(){
      //this.$store.dispatch('jian',this.n)
      this.$store.commit('JIAN',this.n)
    },
    incrementOdd(){
      this.$store.dispatch('jiaOdd',this.n)
    },
    incrementWait(){
      setTimeout(()=>{
        this.$store.dispatch('add',this.n)
      },1000)
    }
      },
      mounted() {
      }
    }
    </script>
    
    <style scoped>
    </style>
    
    
    vue
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/CyfEWNc9aZJlHbs7IMgpL6Bduz5U.png)

5.4 getters的使用

**概念:**当state中的数据需要进行加工后再使用时,可以使用getters加工

store.js中追加getters配置:

复制代码
    //准备getters——用于将state中的数据进行加工

    const getters={
    bugSum(state){
        return state.sum*10
    }
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    actions:actions,
    mutations,
    state,
    getters
    })
    
    
    js
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/hO2QHi04FSy73m1cf9ItAv8njaod.png)

组件中读取数据: $store.getters.bigSum

复制代码
    <h1>当前求和放大10倍后为:{{$store.getters.bugSum}}</h1>

    
    
    vue

5.5 四个map方法的使用

mapState

**mapState方法:**用于帮助我们映射state中的数据作为计算属性

复制代码
    computed:{
      //借助mapState生成计算属性,从state中读取数据(对象写法)
      ...mapState({sum:"sum",school:"school",subject:"subject"}),
      //借助mapState生成计算属性,从state中读取数据(数组写法)
      ...mapState(['sum','school','subject']),
    }
    
    
    vue
mapGetters

**mapGetters方法:**用于帮助我们映射getters中的数据作为计算属性

复制代码
    computed:{
      	//借助mapGetters生成计算属性,从getters中读取数据(对象写法)
    	...mapGetters({bigSum:'bigSum'})
    	//借助mapGetters生成计算属性,从getters中读取数据(数组写法)
    	...mapGetters(['bigSum'])
    }
    
    
    vue
mapActions

**mapActions方法:**用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

复制代码
    //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:"incrementWait"}),
    //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
    ...mapActions(['incrementOdd','incrementWait']),
    
    
    vue
mapMutations

**mapMutations方法:**用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

复制代码
    //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
    ...mapMutations({increment:'ADD',decrement:'JIAN'}),
    //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
    ...mapMutations(['increment','decrement']),
    
    
    vue

5.6 模块化+命名空间

**目的:**让代码更好维护,让多种数据分类更加明确

修改store.js:

复制代码
    //人员管理功能相关的配置

    const personOptions={
    namespaced: true,//开启命名空间,默认关闭
    actions: {...},
    mutations:{...},
    state:{x:1...},
    getters:{
        firstPersonName(state){
            return state.personList[0].name
        }
    }
    }
    
    const countOptions= {
    namespaced:true,//开启命名空间,默认关闭
    actions:{...},
    mutations:{...},
    state:{
        sum:0,
    },
    getters:{
        bigSum(state){
            return state.sum*10
        }
    }
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    modules:{
        countOptions,
        personOptions
    }
    })
    
    
    js
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/bczlu5UPS4mORMyt0JFID7vY8fXC.png)

开启命名空间后,组件中读取state数据:

复制代码
    //方式一:自己直接读取

    this.$store.state.personOptions.personList
    //方式二:借助mapState读取
    ...mapState('countOptions',['sum','school','subject'])
    
    
    vue

开启命名空间后,组件中读取getters数据:

复制代码
    //方式一:自己直接读取

    this.$store.getters["personOptions/firstPersonName"]
    //方式二:借助mapGetters读取
    ...mapGetters('countOptions',['bigSum'])
    
    
    vue

开启命名空间后,组件中调用dispatch:

复制代码
    //方式一:自己直接dispatch

    this.$store.dispatch('personOptions/addPersonWang',person)
    //方式二:借助mapActions读取
    ...mapActions('countOptions',{incrementOdd:'jiaOdd',incrementWait:"incrementWait"})
    
    
    vue

开启命名空间后,组件中调用commit:

复制代码
    //方式一:自己直接commit

    this.$store.commit('personOptions/ADD_PERSON',person)
    //方式二:借助mapMutations读取
    ...mapMutations('countOptions',{increment:'ADD',decrement:'JIAN'}),
    
    
    vue

全部评论 (0)

还没有任何评论哟~