Vue学习(二)

Vue,js 高博文
文章标签: vue.js

Vue学习(二)

Vue.js基础知识

①模板语法

代码如下:

     <div id="app">
        <h3>普通文字</h3>
        <p>{{mustache}}</p>
        <p v-text="mustache"></p>
        <h3>插入原始html</h3>
        <p v-html="htmls"></p>
        <h3>html属性上插值</h3>
        <ul>
            <li v-for="i in 10" v-bind:id="'list'+i">{{i}}</li>
        </ul>
        <h3>对于属性值是false时在html上不显示</h3>
        <button type="button" v-bind:disabled="no">点击</button>
        <h3>js表达式</h3>
        <p>表达式是由变量、常量、运算符、函数,并返回一个值</p>
        <p>{{num*num}}、{{true?"yes":"no"}}</p>
        <h3>沙盒模式</h3>
        <p>{{Date()}}</p>
        <p>{{school}}</p>
    </div>
    <div id="app1">
            <h3>在v-开头的都是指令,指令通常需要一个js表达式</h3>
            <p v-if="send">看的到的</p>
            <p v-else>看不到的</p>
            <h3>指令参数</h3>
            <button type="button" v-on:click="show">点击</button>
            <h3>缩写</h3>
            <p>v-bind缩写   :属性名</p>
            <ul>
                    <li v-for="i in 10" :id="'list'+i">{{i}}</li>
                </ul>
            <p>v-on缩写    @属性名</p>
            <button type="button" @click="show1">点击</button>
       </div>
</body>
<script>
        var school="智学无忧";//报错全局变量不是沙盒中的
        var  vm=new Vue({
            el:"#app",
            data:{
                 mustache:"文本插入",
                 htmls:"<strong>原始html</strong>",
                 no:false,
                 num:10,
                 school,//不加报错
            }    
        })
        var app=new Vue({
        el:"#app1",
        data:{
             send:true,
        },
        methods:{
            show(){
                 alert("click也是指令参数");
            },
            show1(){
                alert("v-on缩写")
            }
        }
    })
</script>

②计算属性和侦听器

计算属性:带有一点逻辑的属性,在使用是可以当做data属性一样使用,定义在computed上。

侦听器:使用watch监听到某个属性的变化,watch属性要和data属性名称一样,watch属性传递两个参数newValue和oldValue。

    <div id="app">
        <p>原始内容{{mag}}</p>
        <p>计算后内容:{{reversemag}}</p>
        <p>方法计算:{{reversemags1()}}</p>
       <p> <input type="text" v-model="fristname"/>+<input v-model="lastname"/>={{fullName}}</p>
        <input type="text" v-model="fullName"/>
        <!-- 侦听 -->
        <h3>侦听器</h3>
        <input type="text" v-model="msg"/>
    </div>
    <div id="watch-example">
            <p>
              Ask a yes/no question:
              <input v-model="question">
            </p>
            <p>{{ answer }}</p>
          </div>
    <script>
         var app=new Vue({
             el:"#app",
             data:{
                 mag:"hello vue",
                 fristname:"",
                 lastname:"",
                 msg:"",
                 arr:[
                     {1:"a"},
                     {2:"b"},
                     {3:"c"},
                     {4:"d"}
                 ]
             },
             computed:{
                 //计算属性的getter
                 reversemag:function(){
                     //this指向app实例
                     return this.mag.split("").reverse().join("");
                 },
                 fullName:{
                    get(){
                      return this.fristname+" "+this.lastname;
                    },
                    set(newv){
                         var names=newv.split(" ");
                         this.fristname=names[0];
                         this.lastname=names[names.length-1];
                         return this.fristname+" "+this.lastname
                    }
                 }
             },
             methods:{
//计算属性有缓冲作用,依赖的变量没有变化不在重新计算
//方法没有缓冲作用,每次调用都会执行
                 reversemags1(){
                      return this.mag.split("").reverse().join("");
                 }
             },
             watch:{
//侦听属性msg的变化
                 msg:function(newv,oldv){
                      console.log(newv,oldv);
                 }
             }
         })
    </script>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // 如果 `question` 发生改变,这个函数就会运行
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
    // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
    // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
    // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
    // 请参考:https://lodash.com/docs#debounce
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },
  methods: {
    getAnswer: function () {
      if (this.question.indexOf('?') === -1) {
        this.answer = 'Questions usually contain a question mark. ;-)'
        return
      }
      this.answer = 'Thinking...'
      var vm = this
      axios.get('https://yesno.wtf/api')
        .then(function (response) {
          vm.answer = _.capitalize(response.data.answer)
        })
        .catch(function (error) {
          vm.answer = 'Error! Could not reach the API. ' + error
        })
    }
  }
})
</script>

③条件渲染

与js中的if结构和if-else结构类似的。

在<template>元素上使用v-if条件,template标签不会渲染 只是一个将包裹的元素作为一个整体。

v-show:只是控制css的display值,添加内样式。 v-show的元素始终会被渲染并保留在dom中,只是简单的的切换css的display。 v-show不支持template元素,也不支持v-else。

v-show和v-if的比较:v-if是“真正”的条件渲染。v-show元素总是会被渲染,并且只是简单的css切换。v-if有更高的切换开销,而v-show有更高的初始渲染开销。

使用场景:需要非常频繁地切换使用v-show比较好,如果在运行时条件很少改变,则使用v-if较好。

    <div id="app">
        <h3>v-if</h3>
          <template v-if="show">
                   <h3>template标签不会渲染 只是一个将包裹的元素作为一个整体</h3>
                   <span>v-if判断</span>
          </template>
          <template v-else-if="show1">
              <span>v-else-if</span>
              <p>v-else-if判断</p>
          </template>
          <template v-else>
                     <span>v-else判断</span>
          </template>
          <div v-show="show">
              <span>v-show显示
            <!-- 只是控制css的display值,添加内样式
             v-show的元素始终会被渲染并保留在dom中,只是简单的的切换css的display
              v-show不支持template元素,也不支持v-else -->
          </div>
          <!-- v-if vs v-show
          v-if是“真正”的条件渲染。v-show元素总是会被渲染,并且只是简单的css切换
          v-if有更高的切换开销,而v-show有更高的初始渲染开销
          使用场景:需要非常频繁地切换使用v-show比较好,如果在运行时条件很少改变,则使用v-if较好 -->
          <div>
              <template v-if="dis">
               <label>手机号:</label><input type="text" placeholder="输入手机号" key="da"/>
              </template>
              <template v-else>
                    <label>email:</label><input type="text" placeholder="输入email" key="em"/>
              </template>
          </div>
          <button type="button" @click="dis=dis==false?true:false">切换</button>
    </div>
    <script>
          var vm=new Vue({
              el:"#app",
              data:{
                show:true,
                show1:false,
                dis:false,
              }
          })
    </script>

④列表渲染

与js中的for循环类似。在与v-if处于同一节点时,v-for的优先级比v-if高,可以理解为for循环嵌套if结构。

    <div id="app">
           <!-- 数组的遍历 -->
           <ul>
               <li v-for="(itme,index) in arr">{{itme.name}}, 下标:{{index}}</li>
           </ul>
           <!-- 对象遍历 -->
           <ul>
               <li v-for="(value,keys,index) in school":key="keys">下标:{{index}} 属性名:{{keys}}  属性值:{{value}}</li>
           </ul>
    </div>
</body>
<script>
    var vm=new Vue({
        el:"#app",
        data:{
           arr:[{name:"张三",age:10},{name:"jack",age:20},{name:"rose",age:18}] ,
           school:{
               name:"张三",
               age:20,
               sex:"男"
           }
        }
    })
</script>

⑤数据变化的检测与跟踪

    <div id="app">
           <table border="1" cellpading="0" cellspacing="0" width="50%">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>姓名</th>
                        <th>年龄</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody style="text-align: center">
                    <tr v-for="(itme,index) in (isf?schoolfil:school)">
                        <td>{{index}}</td>
                        <td>{{itme.name}}</td>
                        <td>{{itme.age}}</td>
                        <td><button type="button" @click="schoolRemove(index)">删除</button></td>
                    </tr>
                </tbody>
           </table>
           <label>姓名:</label><input type="text" v-model="names"/>
           <label>年龄:</label><input type="text" v-model="ages"/>
           <button type="button" @click="schoolPush">在末尾追加</button>
           <button type="button" @click="schoolUnshift">在第一个添加</button>
           <button type="button" @click="schoolPop">删除末尾</button>
           <button type="button" @click="schoolReverse">反转</button></br>
           <button type="button" @click="schoolSortS">升序</button>
           <button type="button" @click="schoolSortJ">降序</button>
           <label>搜索</label><input type="text" v-model="studentName"/>
           <div>
               <h3>弥补数组缺陷</h3>
               <!-- 缺陷
               1.利用索引直接设置一个项时vm.itmes[indexOfItem]=newValue
               2.修改数组的长度时vm.items.length=newlength
                -->
               <ul>
                   <li v-for="items in arr">{{items}}</li>
               </ul>
               <h3>弥补对象的缺陷</h3>
               <p>name:{{obj.name}} age:{{obj.age}} sex:{{obj.sex}}</p>
               <p>地址:{{obj.arrt}} 班级:{{obj.sce}}</p>
           </div>
    </div>
</body>
<script>
    var vm=new Vue({
        el:"#app",
        data:{
             school:[{ name:"小莉",age:20,},{name:"张三",age:30},{name:"rose",age:22},{name:"jack",age:18}],
             names:"",
             ages:18,
             studentName:"",
             schoolfil:[],
             isf:false,
             arr:[1,2,3,4,5],
             obj:{
                 name:"xiao",
                 age:10,
             }
        },
        watch:{
              studentName(m,n){
                      if (m.trim()==""||m.trim()==null) {
                          this.isf=false;
                      }else{
                          this.find();
                          this.isf=true;
                      }
                }
        },
        methods:{
            //删除
            schoolRemove(index){
                this.school.splice(index,1);
            },
            //在末尾追加
            schoolPush(){
              this.school.push({"name":this.names,"age":this.ages});
            },
            //在第一个添加
            schoolUnshift(){
                this.school.unshift({"name":this.names,"age":this.ages});
            },
            //删除末尾
            schoolPop(){
                this.school.pop();
            },
            //反转
            schoolReverse(){
                this.school.reverse();
            },
            //升序
            schoolSortS(){
                this.school.sort(function(a,b){
                    //返回值>0 a插入到b后面
                    //返回值=0 a和b位置不变
                    //返回值<0  b插入到a后面
                    return a.age-b.age;
                })
            },
            //降序
            schoolSortJ(){
                this.school.sort(function(a,b){
                    //返回值>0 a插入到b后面
                    //返回值=0 a和b位置不变
                    //返回值<0  b插入到a后面
                    return -(a.age-b.age);
                })
            },
            find(){
                //数组过滤器
                this.schoolfil=this.school.filter(function(a,b,c){
                    return a.name.indexOf(vm.studentName)!=-1;
                })
            }
        }
    })
    //vm.$forceUpdate()重新渲染数据
    //数组缺陷的弥补   对象也一样
    //1.使用vue提供的方法 
    Vue.set(vm.arr,0,10)
    //2.vm.$set是全局方法Vue.set的别名
     vm.$set(vm.arr,1,100)
    //3.使用原生的方法 
    vm.arr.splice(4,1,9)
    //vm.items.splice(nrelength)

    //对象
    //修改
     Vue.set(vm.obj,"name","dasdas")
    //添加
     vm.$set(vm.obj,"sex","女")
     //Vue.set(vm.obj,"sex","男")
    //一次添加多个属性
    vm.obj=Object.assign({},vm.obj,{"sex":"男","arrt":"深圳市","sce":10})
</script>

⑥事件处理

v-on指令:监听DOM事件,并在触发时运行一些js代码。事件处理方法,方法定义在methods属性上。

    <div id="app">
        <h3>v-on指令:监听DOM事件,并在触发时运行一些js代码</h3>
        <button type="button" @click="show1($event)"/>v-on</bUtton>
        <div>
             <div @click="show1">
                <h3>.stop阻止事件冒泡</h3>
                <!-- <button type="button" @click="show2">点击</button> -->
                <button type="button" @click.stop="show2">点击</button>
             </div>
        </div>
        <h3>按键修饰符</h3>
        <label>enter键</label><input type="text" @keyup.enter="enter1" placeholder="按enter键提交"/>
        <label>tab键</label><input type="text" @keyup.tab="tab1" placeholder="按tab键触发"/>
        <label>delete键</label><input type="text" @keyup.delete="delete1" placeholder="按delete键触发"/>
        <label>esc键</label><input type="text" @keyup.esc="esc1" placeholder="按esc键触发"/>
        <div>
            <h3>组合按键修饰符</h3>
            <label>同时按alt键和C键触发</label><input type="text" @keyup.alt.67="alt_C" placeholder="同时按alt键和C键触发"/>
        </div>
        <div>
            <h3>鼠标按钮修饰符</h3>
            <button type="button" @click.left="left1" @click.right="right1($event)" @click.middle="middle1">鼠标按钮</button>
        </div>
    </div>
</body>
<script>
     var vm=new Vue({
         el:"#app",
         data:{
               
         },
         methods:{
             //$event传递原始的DOM事件
               show1(ev){
                   console.log(ev)
                   alert("v-on指令"); 
               },
               show2(){
                   alert(".stop阻止冒泡事件");
               },
               enter1(){
                   alert("按enter键触发事件")
               },
               tab1(){
                   alert("按tab键触发")
               },
               delete1(){
                   alert("按delete键触发")
               },
               esc1(){
                   alert("按esc键触发")
               },
               //space键的触发是  .space
               //up键的触发是     .up
               //down键的触发是    .down
               //left键的触发是     .left
               //right键的触发是     .right
               alt_C(){
                   alert("组合按键")
               },
               left1(){
                   alert("鼠标左键")
               },
               right1(ev){
                ev.preventDefault();
                   alert("鼠标右键");
               },
               middle1(){
                   alert("鼠标中键")
               }
               

         }
     })
</script>

⑦表单输入绑定

v-model指令:双向绑定数据,作用在input、textarea、select标签上,默认值来自data的初始化数据。

  <div id="app">
        <h3>复选</h3>
          <input type="checkbox" v-model="chk" value="复选1"/>复选1
          <input type="checkbox" v-model="chk" value="复选2"/>复选2
          <input type="checkbox" v-model="chk" value="复选3"/>复选3
          <input type="checkbox" v-model="chk" value="复选4"/>复选4</br>
          <label>你的选择是:</label>{{chk}}
          <h3>单选</h3>
          <input type="radio" v-model="rad" value="男"/>男
          <input type="radio" v-model="rad" value="女"/>女
          {{rad}}
          <h3>选择框</h3>
          <select v-model="sel">
              <option value="选择1">选择1</option>
              <option value="选择2">选择2</option>
              <option value="选择3">选择3</option>
              <option value="选择4">选择4</option>
          </select>
          {{sel}}
          <h3>修饰符</h3>
          <h4>.lazy    input事件改成change事件</h4>
          <input v-model.lazy="laz"/>{{laz}}
          <h4>number输入值转为数值类型</h4>
          <input type="number" v-model.number="age"/>{{age}}
          <h4>.trim去首尾空格</h4>
          <input v-model.trim="tri"/>{{tri}}
         </br>{{tri.length}}
    </div>
</body>
<script>
    var vm=new Vue({
        el:"#app",
        data:{
          chk:["复选1"],
          rad:"男",
          sel:"选择1",
          laz:"",//懒加载
          age:0,
          tri:"",
        },
    })
</script>

⑧Class与Style绑定

   <div id="app">
           <h3>绑定class</h3>
           <h4>对象</h4>
           <p :class="{red:isRad,'font-size':isSiza}">对象的绑定</p>
           <p :class="objclass">对象定义在data上</p>
           <h3>绑定数组</h3>
           <h4>单个原始数组</h4>
           <p :class="[arrred,arrsize]">单个原始数组</p>
           <h4>对象数组</h4>
           <p :class="[{red:isRad},{'font-size':isSiza}]">对象数组</p>

           <h3>绑定内联样式</h3>
           <h4>对象</h4>
           <P :style="{color:objco,fontSize:objsz+'px'}">对象语法</P>
           <h4>数组</h4>
           <p :style="[arr1,arr2]">数组语法</p>
    </div>
    <script>
        var vm=new Vue({
            el:"#app",
            data:{
            isRad:true,
            isSiza:true,
            objclass:{
                //这里isRad都是调用的初始化值false
                red:this.isRad,'font-size':this.isSiza
            },
            //也可以定义在计算属性,方法上 只要返回值是对象的都可以
            //绑定数组
            arrred:"red",
            arrsize:"font-size",
            objco:"red",
            objsz:30,
            arr1:{
                color:"red"
            },
            arr2:{
                fontSize:30+'px'
            }
            }
        })
    </script>

还能输出{{restrictNumber}}个字符  
  • {{reply.author}}

    {{CommonUtil.formateDate(reply.ac_CommentDate).shortTime}}
  • 回复了{{Comments.author}} :