zoukankan      html  css  js  c++  java
  • vue基础

    VUE是目前前端最火的两个框架之一
    是通过修改数据自动改变dom数据的框架,几乎完全的省去了dom的操作,目前vue的版本是2.x

    vue有两种使用方式,一种是直接引入js,一种是使用vue-cli,也就是脚手架

    不管是使用哪种,写法都是没变的,只是脚手架用在更加大型的项目,脚手架后面再说

    内容全部来自vue官网
    这是我第一次认真的看vue的开发文档,以前都是看视频学习的,这才发现vue还有这么多看都没看过的API

    需要学会的全部内容

    • 生命周期
    • 指令【太多了,不写了】
    • 选项/dom【ref】
    • 选项/数据【data,props,computed,methods,watch,$refs$nextTick
    • 全局API的【use,set,directive,component,filter】
    • 外部的【$router$store,axios】

    引入

    这里是一些基础的使用,所以就直接引入js做栗子

    <div id="app">
      {{ message }}
    </div>
    
    // 外部CDN
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
    <script type="text/javascript">
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue!'
      }
    })
    

    生命周期 和 ref
    生命周期在大型的插件封装里是非常常见的,是表示当前运行阶段
    vue的声明周期很多个,用到的有

    1. created:表示data数据已经加载,计算属性,watch,methods都执行好了,但是el还没挂载,第一次加载执行时用这个生命函数,我们去看vue的标签,写的时候可能是<vue></vue>但在页面上调试其实是个div,就是el被解析后挂载后的效果
    2. mounted:当前el已经挂载得差不多了,如果需要等el完全挂载,可以配合$nextTick使用,这个阶段是用来调用ajax
    3. updated:当数据发生变化,就会执行这个

    生命周期函数不能使用箭头函数

    <div id="app">
       <div ref="tt"> {{ message }} </div>
    </div>
    
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue!'
      },
      created(){
    	 // 此时没有el
             console.log(this.$refs)  //underfined
      },
      mounted(){
          this.$nextTick(function(){
    	  // 这里是执行ajax的  
              console.log(this.$refs)  //{tt:div}
          })
      },
      updated(){
          this.$nextTick(function(){
    	 // 数据变化执行这个
          })
      }
    })
    

    指令

    <div id="app">
    <!-- 数据显示的指令
         跟v-text一样但是用字符串模板{{}} 更好,还能执行方法
         v-html 是很少用的,一般用在后台返回富文本数据时使用  -->
        <div v-text="msg"></div>
        <div v-html="html">会识别html标签</div>
        <div>{{ msg + "aa" }} 可以写其他文字</div>
    
    <!-- 逻辑判断的指令
         v-if是直接看不到dom,v-show是display:none -->
        <div v-show="show">显示</div>
        <div v-show="!show">隐藏</div>
        <div v-if="str === 'A'">A</div>
        <div v-else-if="str === 'B'">B</div>
        <div v-else>Not A/B</div>
    
    <!-- 循环断的指令,可以循环数组,对象,字符串,数字 
         v-for要配合 :key 使用 
         v-for 不要跟 v-if 放在一起 -->
         <div v-for="value,key,index in obj" :key="key">{{key}}:{{value}}--{{index}}</div>
         <div v-for="value,index in arr" :key="value">{{value}}--{{index}}</div>
    
    <!-- 事件绑定的指令,简写为【@】,配合methods使用,
         不传参是不写括号的
         事件修饰符:stop 阻止冒泡,
                    prevent 阻止默认事件,
                    self 只能亲自执行不被冒泡执行,相当于event.target,
                    once 只执行一次
                    native 使用在自定义组件上,查看《vue的自定义》笔记 -->
         <input type="text" v-on:blur="myBlur($event)" />
         <button @click="myClick">点击</button>
    
    <!-- 变量绑定的指令,简写为【:】
         最常用的地方是 key,组件传参,src,href,type等-->
         <input v-bind:type="type" />
         <a :href="href"> 可以通过 data里改href 修改 a的href </a>
    
    <!-- 表单双向绑定的指令  -->
         <input type="text" v-model="text">	<span>{{text}}</span> <br>
         <input type="password" v-model="password">	<span>{{password}}</span> <br>
         <input type="radio" v-model="radio" value="radio1"><input type="radio" v-model="radio" value="radio2">  <span>{{radio}}</span> <br>
         <input type="checkbox" v-model="checkbox" value="checkbox1"><input type="checkbox" v-model="checkbox" value="checkbox2">  <span>{{checkbox}}</span> <br>
         <select v-model="select">
            <option value="select1">select1</option>
            <option value="select2">select2</option>
            <option value="select3">select3</option>
         </select> <br>
    </div>
    
    var app = new Vue({
      el: '#app',
      data: {
        msg: 'Hello Vue!',
        html:"<input type='text'>",
        show: true,
        str: 'A',
        obj:{
    	"name":"pdt",
    	age:18
        },
        arr:[10,20,30,40],
        type:"password",
        href: "http:www.baidu.com",
        text: "text",
        password:"pass",
        radio:"radio2",
        checkbox:["checkbox1","checkbox2"],
        select:"select2",
      },
      methods:{
        myBlur(e){ console.log(e.srcElement.value) },
        myClick(){ ... }
      },
    })
    

    特殊的key指令
    key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes,如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素,有相同父元素的子元素必须有独特的 key,重复的 key 会造成渲染错误

    还有一个问题就是vue格式的dom标签在生命周期没进行到mounted之前是显示的,会让页面非常的难看
    所以应该先隐藏,vue有个无用的指令叫v-cloak,把这个标签写在最高级dom上,给这个属性添加隐藏功能,等到vue把el挂载这个属性就会失效,页面也正好展示出来

    [v-cloak] {
      display: none;
    }
    
    <div id="app" v-cloak > ... </div>
    

    选项/dom
    就是给dom元素上加上ref="xxx"的值,相当于id,然后可以通过 this.$refs获得一个对象,这个对象里装着所有带有 ref 属性的dom元素,这个是很少使用,只有部分插件有要求使用这个属性

    选项/数据
    上面的指令是数据和dom的绑定和显示,这个是vue插件替我们完成的,我们就不用再去写xx.value=="xx",xx.innerHTML="xx"了,所以只需要自己修改数据就行

    我们一般使用的vue的数据写在4个地方

    1. data对象里
    2. 计算属性computed里
    3. prop对象里(由父组件的v-bind传过来的,这个后面单独讲)
    4. 还有vuex (这个后面单独讲)
    <div id="app">
        <div> {{ msg }} </div>
        <div> {{ msg2 }} </div>
        <div v-show="show">显示</div>
        <div v-show="!show">隐藏</div>
        <button @click="A">显示/隐藏</button>
        <button @click="B">点击修改msg的值</button>	
    </div>
    
    var app = new Vue({
      el: '#app',
      data: {
        msg: 0,
        show: true,
      },
      methods:{
        // 修改data的数据只能用this.【data里的key】 = 【新value】
        A(){ this.show = !show; // 取反 }
    
        // 修改data的数据只能用this.【data里的key】 = 【新value】
        B(){ this.msg = new Date().getTime(); }
      },
      computed:{
         // 在计算属性里的值不需要写在data里,重复会冲突
         // 一旦计算属性里的相关值发生变化,这个值就会重新计算
         // 计算属性是需要return才能给自己赋值
         msg2(){
    	return new Date(this.msg).getFullYear()+"-"+ (new Date(this.msg).getMonth()+1) + "-"+ new Date(this.msg).getDate() + " "+ new Date(this.msg).getHours() + ":"+ new Date(this.msg).getMinutes() + ":"+ new Date(this.msg).getSeconds()   
         } 
      } 
    })
    

    vue的watch监听
    这个是计算量很大的方法,vue建议能用computed尽量不用watch,但是我经常用它监听vuex的初始化数据,他是监听上面的四个数据对象的某个数据,需要四个数据对象里先有需要监听的值
    注意: watch和computed不要去操作相同的数据,不然相互计算会陷入死循环

    data:{
       name:"xxx"
    },
    watch:{
       name(){
          console.log("值发生了改变")
       }
    }
    

    watch的immediatedeep

    watch: {
      // 不能写成函数了
      firstName: {
        handler(newName, oldName) {
          this.fullName = newName + ' ' + this.lastName;
        },
        // 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
        immediate: true, //默认是false
    
        // 当watch监听的是对象,对象里的值改变是不被监听的,需要加上深度监听
        deep: true   //默认是false
      }
    }
    
    

    methods是存方法的地方,$refs在上面提到了

    还有最后一个this.$nextTick这个是配合vue的数据更新使用的,vue的数据更新后的dom更新并不是实时的,他不是你把a从1变成2他就去改一次的,他是用类似防抖的方式去控制数据变化的,他会把数据的变化攒着一口气再更新一次dom,而this.$nextTick回调的就是下一次dom更新完要执行的东西
    这个方法用得也不多,在使用轮播图插件的时候,一开始轮播图是空的,所以不会动,等图片数据从ajax请求下来后,数据更新上去但是轮播图还是不会动,就需要执行轮播图滚动的方法,如果同步执行,10次可能有5次不生效,因为你执行滚动方法的时候dom还没更新,所以解决方案有弄个定时器等大概1-2s后执行滚动方法,或者把滚动方法写在this.$nextTick的回调里

    数据添加的规定
    需要用到的数据有两种,一种是一开始就声明好了的,比如现在data里先声明了name属性,那这个属性在vue的creat阶段就被监听了,但是如果是后期添加的数据,是不被监听的

    <div id="app">
        <div v-for="value in opt.arr" :key="value">{{value}}</div>
        <div v-for="value,key in opt.obj" :key="value">{{key}}--{{value}}</div>
        <button @click="A">添加数组</button>
        <button @click="B">添加对象</button>	
    </div>
    
    var app = new Vue({
      el: '#app',
      data: {
         opt:{},
      },
      methods:{
        A(){ 
          this.opt.arr=[{name:"arr"}];
          console.log(this.opt.arr)
        },
        B(){ 
          this.opt.obj={name:"obj"};
          console.log(this.opt.obj)
        }
      } 
    })
    

    会发现虽然打印有数据,但是页面没数据,因为vue不知道有这个数据,js知道
    想要让vue知道,需要用vue规定的添加方式

      methods:{
        A(){
          // 在this是代表vue实例的地方这么写 
          this.$set(this.opt,"arr",[{name:"arr"}])
    
          // 在this不是vue的实例的地方,比如插件的上下文里
          // Vue.set(this.opt,"arr",[{name:"arr"}])  
          console.log(this.opt.arr)
        },
        B(){ 
          // 在this是代表vue实例的地方这么写 
          this.$set(this.opt,"obj",{name:"arr"})
    
          // 在this不是vue的实例的地方,比如插件的上下文里
          // Vue.set(this.opt,"obj",{name:"arr"})
          console.log(this.opt.obj)
        }
     } 
    

    数据更新的规定

    当更新一个普通的数据时,直接xx="xx",vue就能反应过来,但是如果是更新数组或者对象,就有些规定了,不然就会出现数据我改了,但是没效果的BUG,具体查看vue官网的文档

    vue规定修改数组用下面的方法
    push()
    pop()
    shift()
    unshift()
    splice()
    sort()
    reverse()
    如果是
    filter()、concat() 和 slice() 。它们不会改变原始数组,而总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:

    example1.items = example1.items.filter(function (item) {
      return item.message.match(/Foo/)
    })
    
    vm.items[1] = 'x' // 不是响应性的
    // 可以改用
    Vue.set(vm.items, indexOfItem, newValue)
    vm.items.splice(indexOfItem, 1, newValue)
    
    vm.items.length = 2 // 不是响应性的
    // 可以改用
    vm.items.splice(newLength)
    
    // 清空数组
    this.arr = []
    

    vue规定修改对象用下面的方法
    对象的数据需要改没有数组那么多的规定就直接赋值就行,新来的数据用set添加
    如果需要融合对象

    vm.userProfile = Object.assign({}, vm.userProfile, {
      age: 27,
      favoriteColor: 'Vue Green'
    })
    

    可以看出,封装是有封装的局限性的,他有很多的限制,这也是为什么学习原生比学习框架更好的原因

    剩下的知识点有
    全局API的【use,directive,component】
    外部的【$route$store,axios】

    剩下的这些都是在脚手架上用的多,用js引入的小项目小页面很少用

    use是用于引入插件的
    directive是自定义指令
    component是自定义组件
    filter是自定义过滤器
    $route是vue-router的路由数据
    $store是vuex的数据
    axios是新的请求方式,因为省去了操作dom,就不会再引入jq了,不用jq了,jq的ajax也就不用了
    除了$store其他的几个在引入型的vue使用中都可以用的,需要用到就自行百度,查看官方文档也有,下一篇《vue-cli》

  • 相关阅读:
    跨域 CORS 详解 (转)
    手机自动化(一)
    Appium Desktop-Permission to start activity denied.
    webview元素定位
    电商网站测试点 还需要整理
    性能测试第三天
    性能测试第二天
    DDD
    ATDD
    BDD
  • 原文地址:https://www.cnblogs.com/pengdt/p/12046385.html
Copyright © 2011-2022 走看看