vue基础第1-3天

vue基础

介绍

vue.js是一套构建用户界面(UI)渐进式框架。Vue的核心库 只关注视图层,采用自底向上增量开发,上手简单,便于与第三方库或既有项目整合。

  • 渐进式:一步一步来,不是说所有东西都要一次用上。
  • 自底向上 : 声明式渲染–>组件系统–>客户端路由–>大规模状态管理–>构建工具

使用

  • vue 使用基础步骤
<!-- 第1步: 引入vue库文件 -->
<script src="./js/vue.js"></script>
<body>
 <!-- 第2步:根容器,js对象转为真实的html后,在放在网页的什么位置中,挂载点挂载点可以写多个,但是在工作中一般只有一个 -->
    <div id="app">

 <!-- 第4步:使用 -->
    <!-- 模板语法 插值表达式 mustcache模板名称[小胡子语法] -->
    <!-- title它就是在vue实例化配置data属性中的数据 -->
    	<h3>{{ title }}</h3>
    <!-- vue模板不建议里面进行运算{{ 1+1 }} -->
    	<div> {{ 1+1 }}</div>
    <!-- 调用函数或方法 -->
    	<div>{{sum()}}</div>
    <!-- 调用js内置方法  不太推荐 -->
    	<div>{{ '电饭锅是'.substr(0,3) }}</div>
    <!-- 三目运算 -->
    	<div>{{ age<20?'未成年':'成年' }}</div>
    <!-- <input type="text" id="setTitle"> -->
    <!-- v-model,语法糖 -->
    <input type="text" v-model="title">

  </div>
<!-- 第3步:实例化vue -->
  <script>
    const vm = new Vue({
      // vue处理完成数据展示在页面中的挂载点dom
      el: '#app',
      // vue2中,唯一一个地方可以把data写成对象地方,就是在实例化vue类时
      // 声明vue要渲染的数据
      data: {
        title: 'hello vue'
      },
      methods:{
        // 调用函数  data中可以写函数,但是会被劫持,这完全没必要, vue为了提升性能可以新增一个methods:配置选项,用来定义函数并且不会被劫持
        sum() {
        	return 1 + 2
    	}
       }
    })
  </script>
</body>

vue2中优化方法

  1. vue的性能的瓶颈主要就是在数据的劫持,定义数据源尽可能的扁平化,可以减少递归带来的性能消耗
  2. vue中当你不想让一个数据变为响应性的,可以将它使用Object.freeze()冻结起来
  3. vue 中函数可以写在data中,但是data中的数据都会被劫持,而函数并没有被劫持的必要,为了提升性能,新增了一个配置选项methods,用于定义函数方法
  4. 对于静态的标签比如ul中的数据可以使用v-pre指令,这是一个固定的并不需要通过vue转化成为虚拟dom,可以直接写入html显示输出
  5. vue 中可以通过v-once 只绑定元素和组件一次,执行之后元素和组件会失去响应能力,相对于一直绑定在性能上确实有优化
  6. 条件判断的v-if 和v-show这两个指令在效果上几乎一样,但v-if在判断条件成立时会删除以创建的元素,这在页面初始化显示权限相关信息时性能更高一些,但是在频繁切换时如果使用v-if会造成频繁创建和删除元素的现象,相比之下v-show的性能会更好一些

Object.defineProperty和Proxy的区别

  1. Object.defineProperty 代理的是对象的某个属性,如果想获取嵌套格式的数据需要进行递归操作,Proxy代理的是整个对象
  2. Object.defineProperty 能监听数组中的每一项,但是监听不到数组中新增的元素和删减的元素,能够对数组已有的元素只能获取和修改,虽然通常情况下我们不希望监听整个数组,在数据量较大时会非常影响效率 ; Proxy可以代理整个对象,并可以监听到元素的增删改

diff比对

  • 同层级相比
  • 新的有 旧的没有,创建新的
  • 旧的有 新的没有, 旧的删除
  • 一样的就开始比对 有key按key比,没有就按照索引从两端向中间比

vue指令

  • 为了操作dom
    • 权限控制
    • 表单验证
    • 主题设置

v-html

  • 解析html字符串,可以解决花括号闪现问题,

v-text

  • 转义html字符串输出,为了解决早期没有使用工程化时,直接映入srcipt产生的花括号闪现问题 一般用不到,在单文件vue中不会有闪现问题,也用不着

v-cloak

  • 专门用来解决闪现问题的但是需要配合css样式,一般也不咋用。v-html或v-text能解决闪现,但是项目早期没用,如果后来全部修改的工程量太大,这时候可以用v-cloak

v-pre

  • 一个性能优化指令,使用可以提升性能,静态的元素可以用,因为是固定的所以不转成虚拟dom直接存储html显示输出,但是动态元素使用之后会直接变成静态的

v-once

  • 只绑定元素和组件一次,之后元素和组件会失去响应能力,也是个性能优化的方案,也不咋用

v-if

  • 显示或隐藏

  • 条件不满足,不会创建或删除已创建的元素;条件满足直接删除元素

v-show

  • 显示或隐藏

  • 条件满足会给元素添加css属性display:none

v-bind

  • 动态属性数据绑定
  • 标准语法: v-bind:属性=“动态数据”,数据不一定是data的methods之类的也可以
  • 简写语法: :属性=“动态数据”
<img v-bind:src="src" alt="">
<img :src="src" alt="">

data: {
        src: 'http://www.mobiletrain.org/images_index/right-fixed-face.png'
}

v-for

  • vue对v-for进行了增强,可以使用for in/of 都可以,而且两者都可以进行对象的迭代

  • 语法: v-for=“(元素,索引) in/of 数组”

    ​ v-for=“(元素,键名,索引) in/of 对象”

  • 注意 :vue2中小括号可以不写,但是vue3必须写

    ​ vue2中如果一个标签同时有v-if和v-for ,则v-for 的优先级会高于v-if,所以还是会循环完

    ​ vue3中v-if的优先级高于v-for

      	- **注意**:v-for 建议给循环的每一项添加一个key来作为标识,用来提升性能,key的值一定唯一不重复,不建议使用循环的索引当key值。一般和后端请求数据时,要求后端提供唯一的id号
    
  • 对象也能循环,但是一般都用枚举

<div id="app">
    <!-- <li v-for="(item,index) in user">{{index}} -- {{item}}</li> -->
    <!-- <li v-for="item,index in user">{{index}} -- {{item}}</li> -->
    <!-- <li v-for="item,index in user" :key="item.id">{{item.name}}</li> -->

    <!-- 循环对象 -->
    <div v-for="item,key,index in user" :key="key">{{index}} -- {{key}} -- {{item}}</div>

  </div>

  <!-- 第3步:实例化vue -->
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        // user: ['张三', '李四', '王五']
        user: [{ id: 2, name: '李四' }, { id: 1, name: '张三' }]
        // user: { id: 1, name: '张三' }
      }
    })

v-on

  • v-on:事件名=“实现的方法[此方法定义在vue配置的methods中]”

  • 简写 @事件名=“方法”

  • <button v-on:click="clickFn">点击事件</button>
    <button @click="clickFn">点击事件</button>
    
  • 绑定的方法可以写小括号也可以不写,但是会有区别

    • 如果绑定方法时没有写小括号,则vue在解析时,会自动给添加映射一个event给绑定方法

    • <button @click="clickFn">点击事件</button>
      
    • 如果绑定方法时,写了小括号,则需要手动把event对象传过去 e v e n t , event, eventevent可以传多个,但是通常建议只传一个,写在第一位或最后一位

    • <button uname="李四" data-uname="张三" @click="evt=>clickFn($event)">点击事件</button>
      
    • event可以用来完成dom数据的获取

    • 绑定的方法写在methods

  • 注意 : methods中定义的方法不使用箭头函数,因为箭头函数没有作用域,找父级会导致this指向混乱,但是方法体中还是建议使用箭头函数来保持this指向

事件修饰符

多个修饰符通过点(.)来连接,

<!-- 键盘按键绑定 -->
<input placeholder="请输入内容" type="text" @keyup.alt.112="onEnter" >
<!-- 阻止冒泡 -->
<button @click.stop="doThis"></button>
<!-- 阻止默认行为 -->
<a @click.prevent="doThis"></a>
<!-- 只执行一次 -->
<div @click.once="incr()">自增一下</div>
<!-- 绑定的元素本身触发时才触发回调 -->
<ul @click.self="incr()">
	<li>你好世界</li>
</ul>
<!--  串联修饰符 -->
<button @click.stop.prevent="doThis"></button>

动态样式

class样式的动态添加,对象和数组方式

  • 对象:{key就是他的样式名称:布尔值[true生效,false不生效]} -->一般用于开关的样式,不太适合添加新的样式属性
  • 动态的给对象添加成员属性:this.$set(给谁, “加什么”, 值是什么)
  • Object.assign() 对象合并,第一层是深复制,其他的是浅复制
  • let obj=Object.assign(第一个参数的地址和返回值地址相等)
  • 数组:[元素样式名称],一般用于新样式的追加

v-model

语法糖是value和事件的结合体,根据不同表单项选择不同的事件,实现了双向数据绑定

单个复选框
<div id="app">
    <div>
      <!-- 单个复选框,定义的数据类型为布尔类型 true选中,false未选中 -->
      <input type="checkbox" v-model="checked">
      <!-- click事件可以用,但它是的状态有太过提前,用onchange事件,改变后来获取 -->
      <!-- <input type="checkbox" @click="clickFn"> -->
      <!-- <input type="checkbox" @change="clickFn"> -->
    </div>
  </div>

  <!-- 第3步:实例化vue -->
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        // 单个复选框一定要用布尔类型
        checked: false
      },
      methods: {
        clickFn(evt) {
          console.log(evt.target.checked);
        }
      }
    })
  </script>
多个复选框
<div>
      <!-- 
        多个复选框,定义的数据类型为数组 
        指定它的value值
      -->
      <ul>
        <li>
          <input type="checkbox" value="html" v-model="lessons">html
        </li>
        <li>
          <input type="checkbox" value="css" v-model="lessons">css
        </li>
        <li>
          <input type="checkbox" value="js" v-model="lessons">js
        </li>
      </ul>
      <hr>
      <div>{{lessons}}</div>
    </div>
  </div>

  <!-- 第3步:实例化vue -->
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        lessons: ["js",'css','html']
      },
      methods: {
      }
    })
全选
<div id="app">
    <div>
      <!-- 
        多个复选框,定义的数据类型为数组 
        指定它的value值
      -->
      <input type="checkbox" v-model="checked" @change="onSelected">
      <hr>
      <ul>
        <li>
          <input type="checkbox" value="html" @change="selectlesson" v-model="lessons">html
        </li>
        <li>
          <input type="checkbox" value="css" @change="selectlesson" v-model="lessons">css
        </li>
        <li>
          <input type="checkbox" value="js" @change="selectlesson" v-model="lessons">js
        </li>
      </ul>
      <hr>
      <div>{{lessons}}</div>
    </div>
  </div>

  <!-- 第3步:实例化vue -->
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        lessons: [],
        checked: false
      },
      methods: {
        onSelected(evt) {
          // 选中了
          if (evt.target.checked) {
            this.lessons = ["js", 'html', 'css']
          } else {
            this.lessons = []
          }
        },
        selectlesson() {
          // 只要来操作数据源就可以改变视图
          this.checked = this.lessons.length == 3
        }
      }
    })
    </script>
单选框&下拉框
<div id="app">
    <div>
      <h3>{{sex}} -- {{city}}</h3>
      <!-- 定义的数据类型为字符串 -->
      <label>
        <input type="radio" value="先生" v-model="sex">建行
      </label>
      <label>
        <input type="radio" value="女神" v-model="sex">招行
      </label>
    </div>
    <hr>
    <div>
      <select v-model="city">
        <option value="0">==选择==</option>
        <option value="wh">芜湖</option>
        <option value="bj">北京</option>
      </select>
    </div>

  </div>

  <!-- 第3步:实例化vue -->
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        sex: '先生',
        city: '0'
      }
    })
  </script>
v-model修饰符

v-model.lazy 延时更新数据源,会在光标移开之后更新数据,每天一个性能提升小技巧有点类似防抖节流

<input v-model.lazy="title">

v-model.trim 两端去空格,中间的空格去不了但是可以用正则替换

<input v-model.trim="title">

v-model.number 转为数值

<input type="number" v-model.number="n1">

自定义指令

  • 自定义指令中不能直接通过this获取vue实例中的data数据或方法
  • 直接通过dom来完成数据的收集
  • 使用时要以’v-'开头,定义的时候不需要以’v-'开头
全局定义

定义之后所有组件或vue实例全都生效,可以使用

  • Vue.directive(‘指令名称 不需要写v-开头’,对象或函数)

  • 对象的写法提供了5个钩子函数

    • bind 第一次绑定到元素时调用 相当于初始化
    • inserted (加入
    • update (数据修改
    • componentupdated
    • unbind (数据删除
局部定义

–>只对于当前组件生效

directives: {} 这个有s全局那个没s

使用指令进行权限管理

计算属性

  • vue使用中,不推荐在模板中写过多的逻辑
  • 对于一个结果进行计算,可以使用vue提供的计算属性来完成,计算属性还具有缓存的功能
  • 如果依赖项没有发生改变,则它在下一次调用时会读取缓存中的数据
  • 提高运行效率,每天一个墨鱼小技巧,哎对性能优化
  • 不能异步
data: {
    n1: 1,
    n2: 2
},
computed: {
<!-- 简写写法 , 只是实现了get-->
	total(){
		console.log("------------");
		return this.n1+this.n2;
	}
<!-- 完整写法-->
	total: {
		get() {
            return this.n1 + this.n2
          },
		set(newVal) {
            if (newVal > 10) {
              this.msg = '值有点的大'
            }
          }
        }
      }
},
methods: {
        sum() {
          // console.log('sum --- methods', this.total);
          // 如果你定义的计算属性,为简写方式,则给计算属性赋值,会报错
          // 只有标准的写法时,它才可以对于计算属性进行赋值操作
          // 赋值只会触发标准方式中的set方法,然后你可以得到它,完成一些别的工作
          if (this.total > 6) {
            this.total = 101
          }
          return this.n1 + this.n2
        }
      }

监听器 - watch

  • 用来侦听 data 中数据变化,默认情况下初始化不触发
  • 监听器的依赖项只能有一个,可以看成一对一
  • 监听器中可以写异步
  • immediate:true 初始时执行一次,一般情况下不使用,只有标准写法下才有这个配置
const vm = new Vue({
	el: '#app',
	data: {
		username: 'aaa',
		errorUsername: '',
		user: { id: 100, name: 'aaa' }
	},
	watch: {
<!--标准写法-->
		username: {
			handler(newValue, oldValue) {//变化前后的值
				console.log(newValue, oldValue);
				if (newValue.length >= 3) this.errorUsername = '太大了';
				else this.errorUsername = ''
			},
             immediate: true
          },
<!--简写-->
		username(newValue, oldValue) {
    		if (newValue.length >= 3) this.errorUsername = '放不进去';
    		else this.errorUsername = ''
		}
<!--监听对象中指定属性数据的变化建议这种写法-->
		'user.id'(newValue,oldValue){
    		console.log(newValue,oldValue)
		}
	}
})
  • 监听对象只能用标准写法来写

  • 监听对象变化时newValue, oldValue两个值是一样的,没办法区分

  • 监听对象 ->深度监听

user: {
          // 深度监听
	deep: true,
	handler(newValue, oldValue) {
		console.log(newValue, oldValue);
	},
}

过滤器

  • 为了对于界面中显示的数据进行一个处理操作
  • 过滤器的定义方案:全局过滤器、局部过滤器
<!--Vue.filter('过滤器的名称,可以随便起',value=>{
	//回调函数,回调函数的参数最少一个,最后一位的参数永远指向要过滤的数据
})-->
<div id="app">
	<h3>{{phone}}</h3>
	<h3>{{phone|phoneCrypt}}</h3>
    <h3>{{phone|phoneCrypt('!!!!')}}</h3>
</div>
<script>
    /*全局过滤器*/
	Vue.filter('phoneCrypt',value=>{
            return value.slice(0,3)+'****'+value.slice(7)
	})
    //参数的个数可以多个
	Vue.filter('phoneCrypt', (value, salt = '****') => {
    	return value.slice(0, 3) + salt + value.slice(7)
	})
const vm=new Vue({
	el:'#app',
	data:{
		phone:'12345678987'
	},
    /*局部过滤器*/
    filters:{//注意了局部的这个filters是有s的全局的没有
    	phoneCrypt(value, salt = '****'){
        	return value.slice(0, 3) + salt + value.slice(7)
        }
	}    
})
</script>

混入 -Mixins

  • 用于公共代码复用
  • 方式 :全局、局部
  • 混入的配置,可以把几乎所有new Vue配置中的所有配置都能混入,但el配置不可
  • data配置,在混入方式中,只能写函数的方式,且函数一定要返回一个对象,混入可以被多次调佣,如果直接是对象的话就会产生污染
  • data混入的优先级 组件(实例) > 局部 > 全局 =>只调用一个
  • 生命周期方法的执行顺序 全局 > 局部 > 组件 依次执行
<body>

  <div id="app">
    <h3>{{name}}</h3>
    <hr>
    <h3>{{showName}}</h3>
    <hr>
    <div>{{run()}}</div>
  </div>

  <script>
    Vue.mixin({
      data() {
        return {
          name: '张三 -- 全局'
        }
      },
      computed: {
        showName() {
          return 'abc -- 全局'
        }
      },
      methods: {
        run() {
          return 'run -- 全局'
        }
      },
      created() {
        console.log('created -- 全局');
      }
    })

    // 局部混入
    const mix = {
      data() {
        return {
          name: '张三 -- 局部'
        }
      },
      computed: {
        showName() {
          return 'abc -- 局部'
        }
      },
      methods: {
        run() {
          return 'run -- 局部'
        }
      },
      created() {
        console.log('created -- 局部');
      }
    }

    const vm = new Vue({
      el: '#app',
      data: {
        // name: '张三 -- 实例'
      },
      mixins: [mix],
      methods: {
        run() {
          return 'run -- 实例'
        }
      },
      created() {
        console.log('created -- 实例');
      }
    })
  </script>

</body>

插件

vue中提供了插件机制,可以通过它的要求来完成插件的封装,运用到项目中

Vue.use(函数 | 类 | 对象 ,[可选参数])
  • 函数
<!--  function plugin(Vue类,options可选参数){}  -->
<body>
    <div id="app">
        <h3 v-red>{{title}}</h3>
    </div>
    <script>
        function plugin(Vue,options){//optionsshi 可选参数
            console.log('options+',options);
            Vue.directive('red',el=>{
                console.log('el+',el)
                el.style.cssText='color:red'
            })
            Vue.mixin({
                data(){
                    return{
                        title:'这就是个标题'
                    }
                },
                created(){
                    this.title=options.title
                    console.log('this.title',this.title)
                }
            })
            //静态属性
            // Vue.run=()=>console.log('run')
            //添加成员属性,除了prototype还有混入可以添加
            Vue.prototype.run=()=>console.log('run')
        }
        Vue.use(plugin,{title:'abc'})
        const vm=new Vue({
            el:'#app',
            data:{

            },
            created(){
                // 调用静态属性
                // Vue.run()
                this.run()
            }
        })
    </script>
</body>
  • 类,必须有个静态方法
<!--
	必须静态方法,名称必须为install
	class Plugin{
		static install(Vue类,options可选参数){}
	}
-->


<body>
    <div id="app">
        <h3 v-red>{{title}}</h3>
    </div>
    <script>
        class Plugin {
            static install(Vue, options) {
                console.log(options);
                Vue.directive('red', el => {
                    el.style.cssText = 'color:red'
                })
                Vue.mixin({
                    data() {
                        return {
                            title: `() => console.log('run');`//这似乎没啥用
                        }
                    },
                    created() {
                        this.title = options.title
                        console.log('混入了');
                    }
                })
                // 添加成员属性
                Vue.prototype.run = () => console.log('run');
            }
        }
        Vue.use(Plugin, { title: 'asd' })
        const vm = new Vue({
            el: '#app',
            data: {},
            created() {
                this.run()
            }
        })
    </script>
</body>

对象

<body>
    <div id="app">
        <h3 v-red>{{title}}</h3>
    </div>
    <script>
        const Plugin = {
            install(Vue, options) {
                console.log(options);
                Vue.directive('red', el => {
                    el.style.cssText = 'color:red'
                })
                Vue.mixin({
                    data() {
                        return {
                            title: `() => console.log('run');`
                        }
                    },
                    created() {
                        this.title = options.title
                        console.log('混入了');
                    }
                })
                // 添加成员属性
                Vue.prototype.run = () => console.log('run');
            }
        }

        // 插入插件
        Vue.use(Plugin, { title: 'abc' })

        const vm = new Vue({
            el: '#app',
            data: {
            },
            created() {
                // Vue.run()
                this.run()
            }
        })
    </script>
</body>

生命周期

  • 也可以被叫做页面钩子函数 (一共11个vue3还要再加2个)

  • 初始化阶段一次 有4个

  • 更新阶段 生命周期会执行N次 有2个

  • 销毁阶段 只执行一次 有2个

  • 剩那3个属于特定场景触发暂时不考虑

 <script>
    const vm = new Vue({
      el: '#app',
      data: {
        username: ''
      },
      // 初始化阶段生命周期  -- 它只都只执行1次
      beforeCreate() {
        console.log('beforeCreate');
      },
      created() {
        console.log('created');
      },
      beforeMount() {
        console.log('beforeMount');
      },
      mounted() {
        console.log('mounted');
        setTimeout(() => {
          // 销毁
          this.$destroy()
        }, 2000);
        this.timer = setInterval(() => {
          console.log(111);
        }, 1000);
      },
      // 更新阶段生命周期,它们会执行N次
      beforeUpdate() {
        console.log('beforeUpdate');
      },
      updated() {
        console.log('updated');
      },
      // 销毁阶段  只执行1次
      beforeDestroy() {
        clearInterval(this.timer)
        console.log('beforeDestroy');
      },
      destroyed() {
        console.log('destroyed');
      }
    })
  </script>

网络请求

status是XMLHttpRequest对象的一个属性,表示响应的http状态码
在http1.1协议下,http状态码总共可分为5大类

1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求
 
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本

使用catch()会捕获之前所有.then的异常,()=>只捕获前面一个.then的异常

 axios.get('/api/users', {
          headers: {
            token: 'abc'
          }
        }).then(ret => {
          console.log(ret.data);
        }).catch(() => console.log('有异常')) 

组件

  • 全局组件 一旦声明完成,就可以在所有的组件中直接使用,不需要引入和注册
  • 定义的组件,它的元素必须要有一个顶层元素进行包裹,否则报错
<body>
    <div id="app">
        <!-- 自定义的标签,在vue项目中,称为组件 -->
        <mytitle></mytitle>
        <mytitle></mytitle>
        <mytitle></mytitle>
        <mytitle></mytitle>
    </div>
    <script>
        Vue.component('mytitle', {
            data() {
                return {
                    title: '我是一个标题'
                }
            },
            // 生成直接生成 虚拟dom方法  
            // 在工程化中,render中可以直接写jsx,在引入一个babel可以写jsx语法(js的增强版本)
            // render(h) {
            //   // console.log(h);
            //   // let vnode = h('h3', null, '我是一个标签')
            //   let vnode = h('h3', { attrs: { name: 'abc', style: 'color:red' } }, '我是一个标签')
            //   return vnode
            // }
            template: `<div>
        <h3 name='abc' @click="setTitle">{{title}}</h3><div>aaaa</div>
        <hr />
        <subtitle></subtitle>
        </div>`,
            methods: {
                setTitle() {
                    this.title = Date.now()
                }
            }
        })

        Vue.component('subtitle', {
            template: `<div>
          <h3>我是一个子标题</h3>
        </div>`
        })
        const vm = new Vue({
            el: '#app',
            data: {
            }
        })
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值