vue的基础与进阶

1.comput ed与watch的区别

computed:监听多个数据或者一个数据来维护返回一个状态值,只要其中一个或多个数据发生了变化,则会重新计算整个函数体,重新返回状态值
watch:只能一个一个监听数据,只要这个数据发生变化,就会返回两个参数,第一个是当前的值,第二个是变化前的值。每当变化的时候,则会触发函数体的逻辑行为,根据逻辑行为做后续的操作

2.key的作用

1. key是辅助diff算法的  做最小量的更新   key 为了提高渲染效率 进行新旧虚拟dom的对比时一个标识 如果有相同的key 直接复用  如果不同的则创建新的对象进行替换的操作
2. diff算法的规则 深度优先  同层比较
注:使用key的时候兄弟元素之间不能有相同的key值

3.// <!-- 1.虚拟DOM中key的作用:
   key是虚拟DON对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DON,
   随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
.对比规则:
     (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:.若虚拟DOM中内容没变,直接使用之前的真实DOM!
     ②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
     (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
     创建新的真实DOM,随后渲染到到页面。

4.//用index作为key可能会引发的问题:
   ①若对数据进行:逆序添加、逆序删除等破坏顺序操作:
   会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
   ②如果结构中还包含输入类的DOM:
   会产生错误DOM更新==>界面有问题。
5.//开发中如何选择key?:
 ① 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
 ② 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。 
6. //v-for 使用key的作用:
 ① 为了高效的更新虚拟dom, 提高列表渲染效率  提高页面的性能(减少dom操作)
 ② 底层的原理通过diff算法 对操作前后的dom树 进行一一对比, 默认没有key时 是逐个替换 
  有key 保证了元素的唯一性,在对比时不再逐个替换 而是在合适的位置添加或删除


3.v-for与v-if

1. <!-- vfor 和 vif 在一起 并没有减少循环次数,而是先解析vfor 再解析v-if。v-for的等级比v-if的高。-->

        <div>
            <div v-for="(obj, index) in lists" :key="obj.id" v-if="obj.price>= 500">{{obj.name}}</div>
//这个时候页面上并没有把obj.price的内容显示出来,但是也没有减少渲染的次数,可以说是先渲染了,在删除
        </div>
2.解决方法
 <!-- 使用过滤方法 -->
        <div>
            <div v-for="(obj, index) in lists.filter(item => item.price>=500)" :key="obj.id">{{obj.name}}            </div>
        </div>

4.模板的使用

<!-- template 模板  h5 提出的新标签  不会渲染到页面中  display:none  (可以写到Vue实例中,或者当作组件的模板)
        使用该标签做为模板
        不会产生额外的新标签 
        要使用 id选择器
    -->

 <div>
        <template id="a">
            <div>
                999
            </div>
        </template>
    </div>
    <!-- 不会显示 -->

    <div id="app">
        <template>
            <div>
                123
            </div>
        </template>
        <div>
            <div>
                1234
            </div>
        </div>
        <com></com>
    </div>
    <!-- 里面的都会显示 -->
    <script src="../../vue/vue.js"></script>
    <script>
        Vue.component("com", {
            template: "#a"
        })
        let app = new Vue({
            el: "#app",
            data: {

            },
            methods: {

            }
        })

5.computed与methods的区别

 1. 区别 方法需要调用(其实在方法中data中的数据发生改变的时候,方法的调用也会更新)
 2. 计算属性有缓存 方法没有
 3. 如果这些函数的名字相同优先使用method
   prop ->  method -> data -> computed -> watch

6.class与style

1.<!-- 没有进行属性绑定就是一个普通的类名 -->
        <div class="test">123</div>
        <div :class="active">动态绑定 active声明在data中: 字符串 对应类名</div>
        <div :class="{active:'value'}">key是类名,value意思是true或者false</div>//这里的active为类名,data里可以不用定义
        <span :class="{active: BMI > 0 && BMI < 18.5}">偏瘦</span>//后面为true时执行,利用改变BMI的值来确定active的样式,是否显示
        <!-- value 变量  必须要声明,表示true或者false-->
        <div :class="{active:value}">对象的另外一种形式</div> 
        <div :class="['red','blue']">value是字符串的时候,值为style里定义的类名</div>
        <div :class="[red,blue]">value是变量的时候其值要在Data里面定义,且定义时red,blue为类名</div>
        <div :class="[{color:'blue'},{fontSize:'50px'}]">变量为数组类型</div>
2.
 <div :style="'color:pink'">style样式</div>
<div :style="styleObj">对象的形式 </div>
 <div :style="styleArray">数组的形式 </div>lue

      Data{
         styleObj: {
                    color: "blue",
                    "font-size": "40px",
                    backgroundColor: "yellow"
                },
                styleArray: [{
                    color: "blue"
                }, {
                    fontSize: '50px'
                }],
}

7.数组的更新

1.通过下标修改不是响应式的,因为不会触发set函数
2. vue 把数据的7个方法进行了重写   调用以下7个方法 可以实现响应式
     push()pop()shift()unshift(),splice(),sort()reverse()
3.发filter(),concat(),slice()是替换数组,生成新的数组,并不改变原数组的值

8.对象的增删实现响应式

1. data中所声明的变量 会通过defineReactive方式 调用definePropety方法 生成对应的set get函数
而没有声明 后续添加上 或者 删除都是非响应式的
2.   解决动态添加为响应式
//1.使用实例方法
   this.$set(this.obj,"gf","lili");

//2.静态方法
  Vue.set(this.obj,"gf","nana");
//3.调用assign方法  可以添加多个
 this.obj  = Object.assign({},this.obj,{gf:"nana",money:"200000"});

9.数组的增删实现响应式

 this.array[0] = 100;//不是响应式
 this.array.length = 10;//不是响应式

                    // 数据响应式
 this.$set(this.array,0,100);

  Vue.set(this.array,0,100);

  this.array.splice(0,1,100);//从数组的索引号为0开始,更改的个数,更改为100,如果更改多个数,后面的参数可为多个

 this.array = [100,2,3,4,5,6]//直接给数组赋一个新值

10.响应式原理

 1. 响应式原理: 数据劫持 + 观察者模式
 2. data中所声明的变量 会通过defineReactive方式 调用definePropety方法 生成对应的set get函数,当data中数据发生变化后,会通知对应的监听器,重新生成新的虚拟dom对象,根据diff算法 把新老虚拟dom做对比,如果存在差异 则替换或删除创建元素 并打补丁  patch(上树)

11.自定义按键修饰符


 1.Vue.config.keyCodes.a = 65;
        // 配置多个
 2. Vue.config.keyCodes = {
            a:65,
            v:86,
            up:[38,87]
        }
        

12.表单提交

1. <!-- 使用vmodel   必须要指定value属性   值要和sex中的值相同 才能被选中-->
        <input type="radio" name="" id="" v-model="sex" value="男"><input type="radio" name="" id="" v-model="sex" value="女"> 女
data{
    sex:"男"
}
2.
 <!-- 使用vmodel   必须要指定value属性   值要和sex中的值相同 才能被选中-->
        <input type="checkbox" name="" id="" v-model="gfs" value="lili"> 丽丽
        <input type="checkbox" name="" id="" v-model="gfs" value="shasha"> 莎莎
        <input type="checkbox" name="" id="" v-model="gfs" value="nana"> 娜娜
data{
    gfs:["lili","shasha"]
}
3.
 <select name="" id="" v-model="city1">
            <option value="1">北京</option>
            <option value="2">郑州</option>
            <option value="3">上海</option>
 </select>
data {
    city1:1
}

13.异步刷新

1.$nextTick的用法   在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。
所以那些同步的代码会先执行。
用法如下:
  methods:{
2     testClick:function(){
3       let that=this;
4       that.testMsg="修改后的值";
5       that.$nextTick(function(){
6         console.log(that.$refs.aa.innerText);  //输出:修改后的值
7       });
8     }
9   }
 

14.传递数据(父传子,子传父)

1.  <!-- 父向子传值   
            1.父组件中 通过自定义属性 进行数据的传递
            2. 子组件 通过 props:[] 进行接收
        -->
            
2. // 单向数据流 子组件中不要修改父组件中的数据   只能向下流动 (否则会造成数据流混乱)

   // 子向父传递数据
     1.子组件中  this.$emit('xxx',val)
     2.父组件中  绑定自定义事件类型 @xxx='事件处理函数'//不传参的时候默认传的也是$event,即子向父传递的数据。如果有参数一定是$event

15.props的命名问题

   1. <div id="app">
        <com mydata="123" my-data1="456" my-data2="789" MyData3="abc" my-data4="def"></com>//这里可以带-,但不区分大小写
    </div>
    <template id="a">
        <div>
            <h1>展示数据:
                {{mydata}} -- {{myData1}}  -- {{myData2}} -- {{mydata3}} -- {{MyData4}}
            </h1>
        </div>
    </template>
    <script src="../../vue/vue.js"></script>
    <script>
        
        // 1.自定义属性为 - 连接 ,接收时可以使用 - 接收, 使用时必须是小驼峰
        // 2.自定义属性为 - 连接 ,接收时小驼峰 ,使用时小驼峰
        // 3.自定义属性为 - 连接 ,接收时大驼峰 ,使用时大驼峰
        // 4.自定为大驼峰浏览器转换为小写,接收时用小写,使用时也用小写
        Vue.component("com", {
            props: ["mydata", "my-data1", "myData2", "mydata3", "MyData4"],
            // template:"#a"
            template: `<div>{{myData1}}--{{ my-data1}}</div>` //总结:不管是模板字符串,还是上面的模板都不可以带-。但是组件名是可以带-
        })
        
        2.组件标签用的时候,是在html中,不区分大小写,但是可以用-横线连接的方式

16.格式化时间

1.  引入  <script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>//Day.js的一个插件
 <h1>dayjs插件 格式化事件 {{now | fdate}}</h1>
  let app = new Vue({
            filters: {
                formatMessage(v, a) {
                    return v + a
                },
                fdate: function(v) {
                    //Day.js中需要传入一个Date的实例对象
                    return dayjs(v).format("YYYY年MM月DD日")//2022年08月31日
                }
            }
        })
  
  2.过滤器
  <h1>全局过滤器 默认将|前的值 当作过滤器第一个参数: {{price | formatPrice}}</h1>
  <h1>全局过滤器 传递两个参数: {{2022 | formatStr(price,31)}}</h1>//也可以传递data里面的值如price

17.Vue实例在页面的渲染

 let app = new Vue({
                el: "#app",//没有挂载el元素的时候,后面需要执行app.$mount(document.querySelector('#app'))来挂载
                template: "#a", //有模板的时候直接就渲染的是模板的内容了。就不渲染 <div id="app"> </div>的内容了
                data: {
                    msg: "1232"
                }
                })

18.生命周期函数

 let app = new Vue({
                el: "#app",
                template: "#a", //有模板的时候直接就渲染的是模板的内容了。就不渲染 <div id="app"> </div>的内容了
                // 生命周期函数 钩子   从组件的生 到 死的过程  8 + 2
                //1.创建阶段
                // 2.更新阶段
                // 3.销毁阶段
                // 创建阶段 4 
                // 主要使用 created 和 mounted 进行网络请求的发送
                beforeCreate() {
                    // 创建之间  data还没有被初始化
                },
                created() {
                    //data 已经被初始化   可以使用了
                },
             beforeMount() {
                    // 虚拟dom生成 并没有生成真是dom 挂载到页面中
                },
                mounted() {
                    // 真实dom已经生成  并挂载到页面中  可以访问dom节点了
                },
                // 2.更新阶段
                beforeUpdate() {
                    // 数据已经是最新值 但是页面中还是旧数据
                },
                // 不要尝试在updated函数中修改data中的数据  死循环
                updated() {
                    // 已经更新完毕  页面中已经是最新的数据了
                },
                // 3.卸载阶段  Destroy 销毁
                // 
                beforeDestroy() {
                    // 清除 事件监听  定时器 延时器的清除
                },
                destroyed() {
                    // 销毁完成
                },
            })

19.父子组件中生命周期的执行顺序

  1父子创建的执行顺序
        //  父组件 beforeCreate
        //  父组件 created
        //  父组件 beforeMount
        //  子组件 beforeCreate
        //  子组件 created
        //  子组件 beforeMount
        //  子组件 mounted
        //  父组件 mounted

 2父子更新的执行顺序
        // 父组件 beforeUpdate
        // 子组件 beforeUpdate
        // 子组件 updated
        // 父组件 updated

  3.子组件更新的顺序
        // 子组件 beforeUpdate
        // 子组件 updated

 4.父组件更新
        // 父组件 beforeUpdate
        // 父组件 updated


  5.父子销毁的执行顺序 
        //   父组件 beforeDestroy
        //  子组件 beforeDestroy
        //  子组件 destroyed
        //   父组件 destroyed

 6. 子组件销毁
        // 父组件 beforeUpdate
        // 子组件 beforeDestroy
        // 子组件 destroyed
        // 父组件 updated


20.手写v-model指令,并熟悉自定义指令的用法

 <div id="app">
        <input type="text" v-mymodel="num"> {{num}}
    </div>
    <script src="../libs/vue.js"></script>
    <script>
        let app = new Vue({
            el: "#app",
            data: {
                num:123
            },
            directives:{
                mymodel:{
                    inserted(el,bind,vnode){
                        el.value = bind.value;//bind.value为指令绑定的值
                        el.oninput = function () {
                            vnode.context[bind.expression] = this.value//vnode.context为Vue的实例,bind.expression为指定绑定的属性名
                        }
                    }
                }
            }
        })

21.使用template标签当作模板时,应注意的点


22.子组件直接修改,父组件传过来的值,控制台会报错,用props传过来的值,需要接一下

//子组件可以使用data和computed来接受父组件传的值,之后做相关操作

1.          props: ['subnum'],
            data() {
                return {
                    count:this.subnum
                }
            }
      -->this.$emit("sub", --this.count);//且用data来接受父组件的值时,数据是非响应式的。即在父组件中修改这个值。子组件里的这个值不会变。因为data里的数据只初始化一次。

2.computed 来接收
 // 为什么使用中间变量接收 是因为计算属性默认只定义了 get函数 没有set函数
// 如果定义set 就必定又触发修改父组件传递过来的值  所以定义中间变量 只获取计算属性中的值
            computed: {
                cnum(){
                    return this.subnum
                }
     --> var num = this.cnum
     --> this.$emit("sub", --num);//注用computed来接受父组件的值做相应操作的时候。数据是响应式的。即父组件中改变这个值。子组件也会改变。
                


23.ref的使用

 // ref reference 引用  主要是用来在vue中获取dom元素的
 // vue不建议直接操作dom元素
如:
 <div id="app">
        <input type="text" ref="input">
  </div>
----------------------------------------------------
 let app = new Vue({
            el: "#app",
            data: {
            },
   methods: {
     handle() {
         this.$refs.d1.innerText = 455;
             }

24.mixin混入的应用

 // mixin 混入(组件中可以使用mixin里的数据和方法)
// 把相同的业务逻辑抽离出来 封装在一个单独js文件中  公用js代码(有局部混入和全局混入)
 1.尽可能不要使用全局混入
        // 注意传递为一个对象
        // Vue.mixin(mixin);
 2.局部混入
       var mixin = {
            data() {
                return {
                    show:true,
                    msg:123
                }
            },
            methods: {
                handle(){
                    this.show = false;
                }
            }
 --------------------------------------------
        Vue.component("modal",{
            template:"#a",//可以使用引入的mixin里的属性和方法
            // 局部混入
            mixins:[mixin]
         }
  3.模板中用到一些方法和数据的时候的执行顺序
    // 1.优先执行混入的生命周期函数  
    // 2.计算属性,过滤器,方法,data的值 都优先使用组件的
           

25.兄弟间的传值

方法一
//思路
 // 1.子 发射给父组件
 // 2.父组件保存
 // 3.父prop 传递另外一个子组件

方法二  bus
 // 思路
        // this.$emit() 发射
        // this.$on() 监听
        // this.$off() 解绑
         注意!!!// 发射时机问题  一定要先监听 后 发射
   如:  
         var vm = new Vue();

        Vue.component("comb", {
            template: "#b",
            data() {
                return {
                    content: "123"
                }
            },
            mounted() {
                vm.$on("send", (v) => {
                    // 注意this指向的问题!!!,普通函数里的this指向vm这个实例
                    this.content = v;//用content接受兄弟组件传过来的值
                })
            }
        })
        Vue.component("coma", {
            template: "#a",
            data() {
                return {
                    msg: "i am A"
                }
            },
            mounted() {
                  setTimeout(() => {
               vm.$emit("send", this.msg);//使用延时器使触发在监听之后
                  }, 1000);
            }
        })


26.插槽

 // 插槽就是子组件向父组件提供一个容器 用来显示 组件标签中间内容的  中间的内容可以是 字符串  标签 组件
 // 一般用在大多数样式结构相同 极个别不相同时使用
 <!-- 作用域插槽:的作用是子组件的有些数据展示样式,想要父组件决定,此时可以用作用域插槽 -->
1.匿名插槽
 <div id="app">
        <weather>
            多云转晴
        </weather>
</div>
-----------------------
 Vue.component("weather",{
            template:"<div>
            <h1>天气预报情况:</h1>
              <slot></slot>//显示的内容则为 多云转晴
                     </div>",
           
        })
2.具名插槽
 <!-- v-slot:xxx  #xxx   使用在模板中或者组件中-->
 <com>
   <template v-slot:header>
          <div>
          头内容
          </div>
   </template>
 <template #default>
          <div>
          匿名内容
          </div>
   </template>
</com>
--------------------------
   Vue.component("com", {
            template: "
            <div>
                <h1>网页头部</h1>
                <slot name="header"></slot>//头内容
            </div>
       "
        })
3.作用域插槽
父:
<div id="app">
        <com>
            <!-- 作用域插槽:的作用是子组件的有些数据展示样式,想要父组件决定,此时可以用作用域插槽 -->
            <!-- obj是子组件插槽slot中动态绑定的数据组成的一个对象.名字可以随便定义 -->
            <template v-slot:header="obj">//可以结构赋值 <template v-slot:header="{uname,age,list">,名字要相同
                <div>
                    <span v-for="(item, index) in obj.list" :key="index">{{item}}</span>
                </div>
            </template>
        </com>
</div>
子:
Vue.component("com", {
            template: "
        <div>
            <slot name="header" :list="list" :uname="name" :age="age"></slot>
        </div>
    ",
            data() {
                return {
                    name: "张三",
                    age: 20,
                    list: ["丽丽", "莎莎", "娜娜"]
                }
            },
        })

26.监听器的使用

 1.使用场景:当一条数据影响多条数据的时候就需要用watch     
watch: { //监听数据的变化,并根据监听的数据的变化,做出相应的操作。监听的函数名,必须是data里定义的数据
                // 简写
               msg(newValue,oldValue){
               console.log("新值: ",newValue,"老值:",oldValue);
               if(typeof newValue == "number"){
                    alert("我变成了一个数");
               }
            }

                // 深层时 直接监听外层对象 无效,下面这个代码无效
                 "gf"(n,o){
                 console.log("新值: ",n,"老值:",o);
               }

                // 可以监听到数据的变化的,但是可以监听对象里的属性
                "gf.age"(n,o){
                   console.log("新值: ",n,"老值:",o);
               }

                //如果想要监听一个对象,可以深度监听
                gf: {
                    deep: true, // 是否要深度监听
                    immediate: true, // 是否立即监听,第一次渲染组件的时候就执行,无需数据发生变化才执行。这个时候的第一次,n为当前的值,o为undefined
                    // 函数名称必须为 handler
                    handler(n, o) {
                        console.log("新值: ", n, "老值:", o);
                    }
                }

            }
        })

27.当是爷组件和孙组件之间的传值的时候,不能直接传递,方法有

1.需要一层一层的用动态属性加props和发射时间进行传递,十分麻烦。
2.可以参考兄弟组件之间的传值,借助一个公共的bus总线,进行传值
 var bus = new Vue();
 bus.$emit("send",res.data);//发射事件之后。监听事件会自动执行
 bus.$on("send",(v) => {
                    this.lists = v;
                })//一定要注意顺序,先监听,在发射。

28.动态组件

 <div id="app">
        <!-- component 决定显示哪个组件  会频繁创建销毁  影响性能 -->
       <component :is="cname"></component>//根据变量cname来切换不同的组件,但会频繁的创建于销毁,所以用以下的方法
        <!-- component keep-alive 内置组件  -->
        <!-- 提升性能  会缓存 不会频繁的创建和销毁  -->
        <keep-alive>
            <component :is="cname"></component>
        </keep-alive>
        <!-- <home></home>
        <home></home> -->
    </div>

28.keep-alive的用途

1.作用
实现组件缓存,保存这些组件的住状态,以避免反复渲染导致的性能问题。
2.场景
tabs标签页,后台导航,vue性能优化
3.原理
vue.js内部将dom节点抽象成了一个个vnode节点,keep-alive组件的缓存也是基于vnode节点,而不是直接存储dom结构。它将满足条件的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染

29.兄弟组件之间的周期函数的执行顺序(适用于传值时候的发射于监听事件)

1.两个兄弟组件传值,用发射$emit和监听$on,一定要注意顺序,监听一定要在发射的前面。所以如果都写在mounted的周期函数里。大多可能是发射发生在监听之前了。
2.可以让监听事件写在beforeMount函数之前。发射事件写在mounted函数里。这样就可以保证监听在发射之前了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mVXhmjGF-1681263996215)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220905190512256.png)]

30.路由传参的方式

1.通过查询字符串的形式进行传递$route.query的对象的形式
①<router-link to="/home?name=娜娜&age=18">首页</router-link><template id="home">
        <div>
            <!-- $route 当前路由信息的对象 包含路由信息 路由参数 -->
            <!-- <h1>接收路由传递的参数:{{$route.query.name}}  -- {{$route.query.age}}</h1> -->
            <h1>接收路由传递的参数:{{$route.query.name}}  -- {{$route.query.age}}</h1>
        </div>
    </template>const router = new VueRouter({
            routes:[
                {path:"/home",component:home}
            ]
        })

2.动态路由传参 $route.params
①<router-link to="/user/1">用户1</router-link>
 <router-link to="/user/2">用户2</router-link>
 <router-link to="/user/3">用户3</router-link>var usercom = {//一个组件来回切换的时候,created等周期函数只执行一次。只不过数据发生了改变
            template:"#user",
            // 解决办法:
            computed:{
                id(){
                    return this.$route.params.id//获取了传过来的id
                }
            }
        }// 注意事项:  动态路由  必须要添加:
        const router = new VueRouter({
          routes:[
            {path:"/user/:id",component:usercom}//需要写:id
          ]  
        })
        
 3. 使用命名路由由params字段传值,使用$route.params接收数据
    使用query对象传值,使用$route.query接收数据
  ①  <!-- 根据名称 进行路由的跳转 -->
        <!-- 一定要记得动态绑定下 -->
        <router-link :to="{path:'/home',query:{id:1,uname:'张三',age:18}}">home</router-link>
        <router-link :to="{name:'home',query:{id:1,uname:'张三',age:20}}">home</router-link>
        <!-- 如果要使用params进行传递参数  必须使用命名路由  path的方式是获取不到数据的 -->
        <router-link :to="{name:'about',params:{id:2,uname:'李四',age:18}}">about</router-link>
        <!-- 下面的有问题的,因为使用params传值,不能使用path路径 -->
        <router-link :to="{path:'/about',params:{id:2,uname:'李四',age:18}}">about</router-link><template id="about">
        <div>
            <h1> params :传递参数:{{$route.params.id}} -- {{$route.params.name}} --{{$route.params.age}}</h1>
        </div>
    </template>const router = new VueRouter({
            routes: [{
                path: "/about",
                name: "home",
                component: home
            }]
        })
4.props传参
① bool模式
使用动态路由和使用命名路由由params字段传递的值将被返回出去,组件里用props接受,即props接收$.route.params的值
  <router-link :to="{name:'about',params:{id:2,uname:'李四',age:18}}">bool 模式 </router-link>//bool模式传参
  <router-link to="/about/1">bool模式</router-link>//bool模式传参
② 函数模式
 在函数中把使用命名路由由params字段传值,使用query对象传值,返回出去,然后在组件里用props接收
  一.<router-link :to="{name:'home',params:{id:1,uname:'张三',age:20}}">函数模式</router-link>. const router = new VueRouter({
            routes: [{
                    path: "/home",
                    name: "home",
                    component: home,
                    props: function($route) {//函数的第一个参数为$route即路由对象,可以起别名
                            return $route.params;
                        } 
                }]).var home = {
            template: "#home",
            props: ['id', 'uname', 'age']
        }
 ③ 对象模式
  <router-link :to="{name:'search'}">对象模式</router-link>

const router = new VueRouter({
            routes: [{
                  path: "/search",
                   name: "search",
                    component: search,
                    props: {
                        id: "3",
                        uname: "王五",
                        age: 20
                    } //传一些静态的值
                }])

31.路由监听

路由监听①在组件的watch监听器中对$route这个字段进行监听
       ②全局监听路由在app.vue组件中,watch监听$route
       ③也可以在全局路由守卫beforeEach函数中操作全局路由
1.<router-link to="/user/1">用户1</router-link>
  <router-link to="/user/2">用户2</router-link>

2. var usercom = {
                template: "#user",
                data() {
                    return {
                        id: ''
                    }
                },
                created() {//只有当组件渲染的时候执行一次,所以后面切换路由的时候,id不变化
                    // console.log(this.$route);
                    // this.id = this.$route.params.id;
                },

                // 解决办法: 计算属性见 -2   
                // 监听器
                watch: {
                    // 1 配合 (1) data中赋值  (2) 生命周期函数中赋值         (ps:二选一即可)
                    // $route(to,from){
                    //     this.id = to.params.id;
                    // }

                    // 2.无需配合  (1) data中赋值  (2) 生命周期函数中赋值   
                    // 第一次加载该组件时 立即执行该函数  immediate
                    $route: {
                        immediate: true,
                        handler(to, from) { //第一次渲染组件的时候就执行了。此时to为当前的,from为undefined
                            console.log("111111", to, from);
                            this.id = to.params.id;
                        }
                    }
                }

            }
3.  const router = new VueRouter({
            routes: [{
                path: "/user/:id",
                component: usercom
            }]
        })

32.前置路由守卫(全局路由守卫)

 const router = new VueRouter({
            routes: [{
                    path: "/home",
                    component: home
                },
               // meta 对象中的key自定义
                {
                    path: "/about",
                    component: about,
                    meta: {
                        author: true
                    }
            ]
        })

        // 购物车页面必须时登录之后才可以访问 否则跳转到登录页面
        // 路由的前置守卫:当:初始化时执行、每次路由切换前执行。(此时ruoter挂载了前置路由守卫,当在路由规则里定义的路由发生变化时,则会执行该路由守卫),只是后面的参数发生改变的时候,也会执行,该前置守卫
        router.beforeEach((to, from, next) => {
            console.log(1111111);
            // to and from are both route objects. must call `next`.
            console.log(to);
            if (!to.meta.author) {//to为即将跳转的路由的参数对象,相当于$route。在跳转到to对应的路由时,要先经过这个路由守卫,执行里面的逻辑操作
                next();
            } else {
                var token = localStorage.getItem("token");
                if (token) {
                    next();
                } else {
                    next({
                        path: "/login",
                        query: {
                            fpath: to.path
                        }
                    }); //next的参数,还可以是一个对象
                }
            }
        })

33.组件的路由守卫

  var com = {
            template: "#a",
            data() {
                return {
                    lists: []
                }
            },      
            // watch:{
            //     $route(to,from){
            //         this.getInfo(to.params.id)
            //     }
            // }

            // 组件内的路由守卫
            beforeRouteEnter(to, from, next) {
                // ...
                // 路由参数的切换不会调用该函数  只有当前路由第一次进入时有效
                // 不要在此发送网络请求
                console.log("enter", to);
                next(); // 必须要调用next函数  放行
            },
            beforeRouteUpdate(to, from, next) {
                // ...
                console.log("beforeRouteUpdate", to);
                this.getInfo(to.params.id);
                next();

            },
            // 当路由地址与当前组件不对应时 触发离开,如果只是路由参数发生变化,不会调用该函数
            beforeRouteLeave(to, from, next) {
                // ...
                console.log("beforeRouteLeave");
            }


        }

34.编程式导航

声明式导航如<router-link to="/user/1">用户1</router-link>,渲染成a标签,需要点击才会执行。而编程式导航是执行该代码的时候,就跳转到对应的路由

1.this.$router.push的参数
 // 字符串路径
 router.push('/users/eduardo')

 // 带有路径的对象
 router.push({ path: '/users/eduardo' })

   // 命名的路由,并加上参数,让路由建立 url
 router.push({ name: 'user', params: { username: 'eduardo' } })

   // 带查询参数,结果是 /register?plan=private
 router.push({ path: '/register', query: { plan: 'private' } })

  // 带 hash,结果是 /about#team
  router.push({ path: '/about', hash: '#team' })

2. // 把当前的页面替换为对应的页面,因此替换不会产生历史记录
  this.$router.push({ path: '/home', replace: true })
   // 相当于
  this.$router.replace({ path: '/home' })
3.this.$router.go(-1);

35.vue中如何写动画



36.代理服务器

1.在vue.config.js文件中写入
  devServer: {
        host: "localhost",
        port: "8081", //使程序运行在8081这个端口
        open: true, //在终端运行的时候,立即打开这个页面
        proxy: { //代理服务器的用法
            "/dy": {
                target: "http://capi.douyucdn.cn/api",
                pathRewrite: { //去掉前缀/dy
                    "^/dy": ""
                },
                changeOrigin: true
            },


        }
    }

2.发送请求时
 created() {
    this.$axios({
      method:"get",
      // 127.0.0.1:8080/dy/v1/getColumnList
      // 替换成
      // http://capi.douyucdn.cn/api/dy/v1/getColumnList

      // pathRewrite  去掉了前缀dy
      // http://capi.douyucdn.cn/api/v1/getColumnList

      url:"/dy/v1/getColumnList"
    }).then((res) => {
  
      console.log(res.data)
    })
  }

37.组件中data为什么是一个函数

1.一个组件被复用多次的话,也就创建了多个实例。实质上,这些实例用的都是同一个构造函数
2.如果data是对象的话,对象属于引用类型,会 影响到所有实例,所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。拥有单独的作用域

38.特殊的函数形参

1.  function test({
            x = 0,
            y = 0
        } = {}) {
            console.log(x, y);
        }
        test(); // 0 0
        test({}); // 0  0
        test({
            x: 1,
            y: 1
        }); //  1  1
        test({
            a: 1,
            b: 2
        }); // 0  0

2. function test2({
            x,
            y
        } = {
            x: 0,
            y: 0
        }) {
            console.log(x, y)
        }

        test2(); //0 0
        test2({}) // undefined  undefined
        test2({
                x: 10
            }) //10 undefined
        test2({
                x: 10,
                y: 100
            }) //10 100

39. .native的用法

1.在父组件中写入子组件标签,并给子组件标签写入事件函数,是没有任何效果的,需要使用.native的方法
.native 在父组件中把子组件当作普通的html标签   进行事件的绑定

 <Room v-for="(item) in lists" :key="item.room_id" :item="item" @click.native="handle"/>//这个时候写入该事件,点击的时候,是有效的

40.样式穿透::v-deep的使用

1.在给一些element-ui和vant-ui里的组件修改样式的时候,直接写一个类名,给相应的样式的时候,是不能修改成功的,因为此时,如写在了HomeView.vue组件里用element-ui里的组件的时候,HomeView.vue组件是element-ui里的组件的父组件。HomeView.vue组件里写的样式,其子组件不能用,即使里面的标签有相同的类名也不可以,这个时候,父组件在写样式的时候,需要用到深度选择器即样式穿透。这个啥时候,子组件里的标签写入一样的类名,也就拥有相同的样式了

2.方法
① 1. >>>  只能用在原生的css中 
② 2. /deep/  脚手架 3以上无效
③3. ::v-deep 常用
::v-deep .el-input__icon {
  line-height: 30px;
}

41.scoped的作用

1.在页面的<style></style>里面
一定要写上scoped:(代表仅在当前页面生效),
如果没有写上这个,就代表是全局样式,容易污染到其他页面的element样式)

42.json-serve的使用

1.安装npm i json-server -g插件
2.建立一个文件夹,在文件夹中放入如db.json文件
3.让这个文件夹在终端中打开,执行语句json-server --watch db.json --port 5001
之后就可以发送请求,进行deleteget,put,post请求了

43.axios的使用

 1. 发送get 请求 
	2.  get 请求传递参数
     2.1  通过传统的url  以 ? 的形式传递参数
	axios.get('http://localhost:3000/axios?id=123').then(function(ret){
      console.log(ret.data)
    })
    2.2  restful 形式传递参数 
    axios.get('http://localhost:3000/axios/123').then(function(ret){
      console.log(ret.data)
    })
	2.3  通过params  形式传递参数 //使用params传递的参数。后台也用req.query来获取
    axios.get('http://localhost:3000/axios', {
      params: {
        id: 789
      }
    }).then(function(ret){
      console.log(ret.data)
    })

 3 axios delete 请求传参     传参的形式和 get 请求一样 (也可以用?链接的那种还有restful的那种)
 
 4  axios 的 post 请求//默认传递json形式的数据,此时服务端需要设置相关的配置
    4.1  通过选项传递参数
    axios.post('http://localhost:3000/axios', {
      uname: 'lisi',
      pwd: 123
    }).then(function(ret){
      console.log(ret.data)
    })

5  axios put 请求传参   //和 post 请求一样 
    axios.put('http://localhost:3000/axios/123', {//123是id写到了url里面了
      uname: 'lisi',
      pwd: 123
    }).then(function(ret){
      console.log(ret.data)
    })

44.使用this.$route.push(‘path’,query{ })获取的数据,一刷新,就没有了

1. 存储在sessionStorage中 
2. vuex

3.动态路由    拼接在地址中  /a/1/2/3/4  地址栏变得丑陋
①.通过this.$route.push({name:'xx',params:{id:123}})     传递一个id到组件中,然后在组件中通过id来获取这个数据,因为id是存在url之后的,不管怎样刷新,都是存在的
②.且在路由的routes[{
    path:'/home/:id'
}]来动态定义一下id
③.使用this.$route.params.id

45.router里的routes地path路径里什么时候写:id什么时候不用

1.
动态路由传参 $route.params
①<router-link to="/user/1">用户1</router-link>
 <router-link to="/user/2">用户2</router-link>
 <router-link to="/user/3">用户3</router-link>// 注意事项:  动态路由  必须要添加:
        const router = new VueRouter({
          routes:[
            {path:"/user/:id",component:usercom}//需要写:id
          ]  
  })
        
2.this.$router.push({ name: 'detail', params: { id: item.id } })const router = new VueRouter({  
  [{
        path: '/detail/:id',//来获取params里面地id,是url地址栏有/id(用于刷新页面会丢失数据)使用params传值,如果想要里面的数据连接在url地址上,就使用:写一下
        name: 'detail',
        component: () =>
            import ('../views/Detail')
    }]
}

vuex的概念

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

46.vuex中四个map方法的使用

引入:import { mapState,mapMutations,mapAction,mapGetters} from ‘vuex’

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

    computed: {
        //借助mapState生成计算属性:sum、school、subject(对象写法)
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum','school','subject']),
    },
    
  2. mapGetters方法:用于帮助我们映射getters中的数据为计算属性

    computed: {
        //借助mapGetters生成计算属性:bigSum(对象写法)
        ...mapGetters({bigSum:'bigSum'}),
    
        //借助mapGetters生成计算属性:bigSum(数组写法)
        ...mapGetters(['bigSum'])
    },
    
  3. mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

    methods:{
        //靠mapActions生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
        //靠mapActions生成:incrementOdd、incrementWait(数组形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
  4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

    methods:{
        //靠mapActions生成:increment、decrement(对象形式)
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
        
        //靠mapMutations生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }
    

备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

47.模块化+命名空间

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

  2. 修改store.js

    const countAbout = {
      namespaced:true,//开启命名空间
      state:{x:1},
      mutations: { ... },
      actions: { ... },
      getters: {
        bigSum(state){
           return state.sum * 10
        }
      }
    }
    
    const personAbout = {
      namespaced:true,//开启命名空间
      state:{ ... },
      mutations: { ... },
      actions: { ... }																																
    }
    
    const store = new Vuex.Store({
      modules: {
        countAbout,
        personAbout
      }
    })
    
  3. 开启命名空间后,组件中读取state数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
    
  4. 开启命名空间后,组件中读取getters数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
  5. 开启命名空间后,组件中调用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  6. 开启命名空间后,组件中调用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

48.store.js中四种对象的使用方法

1.state:{
count:0
}
2.mutations: {
    add(state,step){
      //第一个形参永远都是state也就是$state对象
      //第二个形参是调用add时传递的参数
      state.count+=step;
    }
  }

3.actions: {
  addAsync(context,step){//context为store对象
    setTimeout(()=>{  
      context.commit('add',step);
    },2000)
  }
}

  4.getters:{
    //添加了一个showNum的属性
    showNum : state =>{
      return '最新的count值为:'+state.count;
    }
  }
})

49.路由器的两种工作模式

1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。

2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。

3. hash模式:(默认)想要更改为history要new VueRouter({mode: 'history' })

   1. 地址中永远带着#号,不美观 。
   2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
   3. 兼容性较好。

4. history模式:可以前进和后退,不能刷新

   1. 地址干净,美观 。
   2. 兼容性和hash模式相比略差。
   3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。(或者前端配置webpack
在devServer中存在historyApiFallback配置项,只需要将其设置成true就可以解决刷新404问题前端配置)

 5.原理的区别
    hash原理:hash通过监听浏览器的onhashchange()事件变化,查找对应的路由规则
    history原理: 利用H5的 history中新增的两个API pushState()replaceState() 和一个事件onpopstate监听URL变化
4、hash ——由于 hash 值变化不会导致浏览器向服务器发出请求,而且 hash 改变会触发 hashchange 事件(hashchange只能改变 # 后面的url片段);虽然hash路径出现在URL中,但是不会出现在HTTP请求中,对后端完全没有影响,因此改变hash值不会重新加载页面,基本都是使用 hash 来实现前端路由的。

5、history —— 利用了 HTML5 History Interface 中新增的 pushState()replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。还有最重要一点是history路由害怕刷新,因为切换路由后浏览器中url改变,再刷新的话会重新向服务器发送请求,所以后端需要做简单的配置

50.Storage的api(localStorage,sessionStorage)

1. xxxxxStorage.setItem('key', 'value');
   	该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
2. xxxxxStorage.getItem('person');
   		该方法接受一个键名作为参数,返回键名对应的值。
3. xxxxxStorage.removeItem('key');
   		该方法接受一个键名作为参数,并把该键名从存储中删除。
4.  xxxxxStorage.clear()
   		该方法会清空存储中的所有数据。

51.props的配置项(props可以是一个数组,也可以是一个对象)

1. 功能:让组件接收外部传过来的数据

2. 传递数据:<Demo :name="xxx"/>

3. 接收数据:

   1. 第一种方式(只接收):props:['name'] 

   2. 第二种方式(限制类型):props:{name:String}

   3. 第三种方式(限制类型、限制必要性、指定默认值):
      props:{
      	name:{
      	type:String, //类型
      	required:true, //必要性
      	default:'老王' //默认值
      	}
      }   
   > 备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

52. r o u t e r 与 router与 routerroute

1.router为VueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象,例如history对象。。经常用的跳转链接,就可以用this.$router.push,和router-link跳转一样
2.route 相当于当前正在跳转的路由对象。可以从里面获取name,path,params,query对象

53,vue.页面刷新 vuex 数据丢失 所以需要持久化

vuex-persist 插件

npm install  vuex-persist -S下载
// 1.引入
import VuexPersistence from "vuex-persist"

// 2.添加配置项
const vuexLocal = new VuexPersistence({
  storage: window.localStorage
})

export default new Vuex.Store({
  //3.挂载 
  plugins: [vuexLocal.plugin],
})

54.name的作用

export default {
    name:"erzi",
    props:["msg"],
    methods: {
        handle(){
            this.$emit("send",1234);
        }
    },
}
1.递归自身组件 
2.辅助keepalive 
3.方便调试使用 vuedevtool中查看
4.指定组件名称 vant element 
https://blog.csdn.net/weixin_45811256/article/details/109498407

55.动态标题,给组件取名字

 1.vue-wechat-title 插件   mian.js中注册   home bus页面  根元素中添加了 v-wechat-title="xxxx"
 https://blog.csdn.net/m0_61672533/article/details/126194995
2. 路由定义 meta信息  
 全局路由守卫 设置document.title = to.meta.xxxx

56.在vuex中如何给state中的对象,添加响应式的属性

 mutations: {
        tianjia(state, item) {
            //第一个形参永远都是state也就是$state对象
  
            Vue.set(item, 'num', 1);//item之前是没有num这个属性的
            Vue.set(item, 'flag', false) //可以响应式的给对象添加属性
                // item.flag = false,不能响应式的给对象添加属性
            state.goodlist.push(item);
        },

57. computed中的数据是不能直接更改的,没有setter函数,会报错。如何给computed添加setter函数

 computed: {
    ...mapState(["goodlist"]),
    flag: {
      set(isCheked){//isChecked是当前给flag赋的值
        console.log(this.goodlist);
        this.goodlist.forEach(el=>{
          el.flag =  isCheked;
        })

      },
      get()
       return this.goodlist.every(el=>el.flag==true)
      }
    },

58.多选框的选中与取消,用v-model是双向的赋值,用checked是单向的

      <input  style="margin:30px 30px" type="checkbox" name="" id=""   v-model="flag">
      //此时flag为true则为选中,为false为不选中。当点击该多选框的时候,也会更改flag的数据

59.重写VueRouter的push和replace方法

在router.js的文件中写入这些代码

// 重新push方法
let originalPush = VueRouter.prototype.push;
let originalReplace = VueRouter.prototype.replace;

// 第一个参数: 告诉原来push方法,你往哪里跳
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}
VueRouter.prototype.replace = function push(location) {
  return originalReplace.call(this, location).catch(err => err)
}

60.bus总线传值

main.js中
var bus=new Vue;
Vue.prototype.$bus = bus;


A.
 mounted() {
        this.$bus.$on("send", (res) => {
            this.msg = res;
        })
    
B.
  methods: {
        handle(){
            this.$bus.$emit("send",123);
        }
    },

61.监听路由的变化,触发相应的函数

许多时候,仅仅用mounted,和created周期函数,来做一些首次渲染页面调用相应的函数,是远远不够的。因为comunted和rreated只触发一次(只是在渲染这个页面的时候触发一次,当仅是url的参数变的时候是不会在触发),当仅仅是url的参数发生改变,是不会触发的
watch:{
    $route:{//监听路由的变化,此时正在跳转的路由url的参数发生变化,也会触发改函数
      deep:true,
      immediate:true,//首次渲染的时候就执行,无需数据发生变化,此时newn和oldn为初始值和undefineds
      handler(newn,oldn){
        this.getlist(); 
      this.getcontentlist()

      }
    }
  }

62.git的使用

1.创建一个仓库,并将项目托管到该仓库
首先在该项目所在路径下打开终端执行以下命令
① git init
②  git remote add origin https://gitee.com/tan-xiaocui/test.git(仓库的地址)
③  git push -u origin "master"

2.克隆
右键点击git bash here,执行以下命令
git clone xxx(项目仓库的https地址)
出现 一个项目文件夹

3.创键一个新的分支
git checkout -b login //创建一个新分支,并切换到该分支上(一般在master分支下执行)
git add .
git commit -m "登录"
git pull 同步,拖拽
git push -u origin login//第一次将新分支,上传到云端
git checkout master
git merge login //将login分支,合并到master中(在master分支中运行)
git push //将新master上传到云端
git status 状态

4.clone出来地项目文件夹,云端上有所有分支,但在该文件夹终端中执行git branch只有一个master分支,意思是本地工作区只有一个master分支,若想从远程仓库克隆到本地 将分支也配置到本地的命令
创建本地分支并与远程分支关联
git checkout -b dev origin/dev 
//--------------------------------------------------------------------------------------------------------

把本地仓库 推送到远程
把远程项目 clone到本地

日常操作
git clone xxx

git add .
git commit -m xxx
git pull
git push

//解决冲突!!!,当不同人修改同一个文件,则会出现冲突问题,需要删除出现地冲突乱码

分支  分支的合并

把本地创建的dev分支 上传了远程仓库  在dev分支下面执行
git push --set-upstream origin dev

git diff //查看上次提交
git branch //查看分支
git status //查看状态,是否干净

63.如何封装axios,之后可以直接点用函数使用

1.在api文件夹里创建request.js文件和index.js文件
在request文件里写入
import axios from 'axios';
// 创建一个自定义的Axios对象
const Axios = axios.create({
    baseURL: 'http://127.0.0.1:1234',
    timeout: 3000,
    /*也可以不设置Content-Type,影响是在你发送请求时
    Vue会先发送OPTIONS包探测路由是否存在,需要后端也做设置响应OPTIONS
    方法,否则会报跨域错误;我这里用的Beego2,路由里不响应OPTIONS方法,
    所以我在这块设置Content-Type*/
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    /*这个配置很重要,允许axios携带用户Cookie到后端,不设置这个的话
    Set-Cookie是无效的,除此之外,Chrome默认开启了SameSite检查,如果
    后端不主动设置SameSite = none,Set-Cookie是无效的。详情请文章末尾
    参考阮老师的SameSite讲解*/
    withCredentials: true
});
Axios.interceptors.request.use(req => {
    // 请求拦截处理
    // console.log('这里是请求拦截器,我拦截了请求', req);
    return req;
}, err => {
    console.log('在发送请求时发生错误,错误为', err);
    //这里不能直接放回err,需要按照官方说明返回一个Promise
    return Promise.reject(err);
})
Axios.interceptors.response.use(res => {
        // 响应拦截处理
        // console.log('响应拦截 ', res);
        return res.data;
    }, error => {
        const err = error.toString();
        //按照实际的响应包进行解析,通过关键字匹配的方式
        switch (true) {
            case err.indexOf('Network') !== -1:
                console.log('后端服务器无响应或者URL错误', err);
                break;
            case err.indexOf('timeout') !== -1:
                console.log('请求后端服务器超时!', err);
                break;
        }
        return Promise.reject(error);
    })
    //暴露Axios实例化对象,允许所有文件调用Axios
export default Axios;

2.在index.js文件中写入
import axios from "./request";
export let reqGetData = (props) => axios.get('')
export let reqGetlist = (props) => axios.get('')
    //使用的时候解构赋值

3..vue组件中按需引入直接调用函数
import { reqGetData} from '../index.js'
mounted(){
   var data=  reqGetData(xx);
    
}

写入
import axios from ‘axios’;
// 创建一个自定义的Axios对象
const Axios = axios.create({
baseURL: ‘http://127.0.0.1:1234’,
timeout: 3000,
/也可以不设置Content-Type,影响是在你发送请求时
Vue会先发送OPTIONS包探测路由是否存在,需要后端也做设置响应OPTIONS
方法,否则会报跨域错误;我这里用的Beego2,路由里不响应OPTIONS方法,
所以我在这块设置Content-Type
/
headers: {
‘Content-Type’: ‘application/x-www-form-urlencoded’
},
/这个配置很重要,允许axios携带用户Cookie到后端,不设置这个的话
Set-Cookie是无效的,除此之外,Chrome默认开启了SameSite检查,如果
后端不主动设置SameSite = none,Set-Cookie是无效的。详情请文章末尾
参考阮老师的SameSite讲解
/
withCredentials: true
});
Axios.interceptors.request.use(req => {
// 请求拦截处理
// console.log(‘这里是请求拦截器,我拦截了请求’, req);
return req;
}, err => {
console.log(‘在发送请求时发生错误,错误为’, err);
//这里不能直接放回err,需要按照官方说明返回一个Promise
return Promise.reject(err);
})
Axios.interceptors.response.use(res => {
// 响应拦截处理
// console.log('响应拦截 ', res);
return res.data;
}, error => {
const err = error.toString();
//按照实际的响应包进行解析,通过关键字匹配的方式
switch (true) {
case err.indexOf(‘Network’) !== -1:
console.log(‘后端服务器无响应或者URL错误’, err);
break;
case err.indexOf(‘timeout’) !== -1:
console.log(‘请求后端服务器超时!’, err);
break;
}
return Promise.reject(error);
})
//暴露Axios实例化对象,允许所有文件调用Axios
export default Axios;

2.在index.js文件中写入
import axios from “./request”;
export let reqGetData = (props) => axios.get(‘’)
export let reqGetlist = (props) => axios.get(‘’)
//使用的时候解构赋值

3.在.vue组件中按需引入直接调用函数
import { reqGetData} from ‘…/index.js’
mounted(){
var data= reqGetData(xx);

}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值