vue学习二:vue指令

v-cloak:

使用 v-cloak 能够解决 插值表达式闪烁的问题,不使用v-cloak的话,在用户网速不理想的时候,页面加载时会先直接显示{{message}},然后再显示数据

<div>
  {{ message }}
</div>

因为这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如[v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。即在实例结束编译前,元素会按照下面的样式进行元素的显示,结束编译后这个样式就不会起作用了。

[v-cloak] {
    display: none;
}
<div v-cloak>
  {{ message }}
</div>

v-text:

默认 v-text 是没有闪烁问题的。

<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>

v-cloak和v-text之间的区别:

v-text会覆盖元素中原本的内容,但是 插值表达式 只会替换自己的这个占位符,不会把 整个元素的内容清空

<p v-cloak>++++++++ {{ msg }} ----------</p>
<h4 v-text="msg">==================</h4>

v-html和v-text的区别:

    <div v-text="msg2">1212112</div>
    <div v-html="msg2">1212112</div>

v-bind:

是 Vue中,提供的用于绑定属性的指令
<input type="button" value="按钮" v-bind:title="mytitle + '123'">
注意: v-bind: 指令可以被简写为 :要绑定的属性
v-bind 中,可以写合法的JS表达式

v-on:

事件绑定机制
<input type="button" value="按钮" :title="mytitle + '123'" v-on:click="show">

注意: v-on: 指令可以被简写为 @要绑定的事件,在Vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了

事件修饰符:

.stop       阻止冒泡
.prevent    阻止默认事件
.capture    添加事件侦听器时使用事件捕获模式
.self       只当事件在该元素本身(比如不是子元素)触发时触发回调,通过捕获冒泡触发的都不执行事件回调
.once       事件只触发一次

<!-- 点击链接后不会跳转到百度的页面 -->
<a href="http://www.baidu.com" @click.prevent.once="linkClick">有问题,先去百度</a>

.stop 和 .self 的区别:

    <div class="outer" @click="div2Handler">
      <div class="inner" @click="div1Handler">
        <input type="button" value="戳他" @click.stop="btnHandler">
      </div>
    </div>

    <!-- .self 只会阻止自己身上冒泡行为的触发,并不会真正阻止 冒泡的行为 -->
    <div class="outer" @click="div2Handler">
      <div class="inner" @click.self="div1Handler">
        <input type="button" value="戳他" @click="btnHandler">
      </div>
    </div>

v-model和双向数据绑定:

v-model是唯一可以实现双向数据绑定的指令。双向数据绑定:M层数据改变后V层对应的数据会修改,V层数据改变后M层对应的数据也会修改。

v-model和v-bind的区别:

v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V, 无法实现数据的双向绑定:

<h4>{{ msg }}</h4>
<!-- v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V, 无法实现数据的双向绑定  -->
<input type="text" v-bind:value="msg" style="width:100%;">

v-model和v-bind的区别

使用  v-model 指令,可以实现 表单元素和 Model 中数据的双向数据绑定
注意: v-model 只能运用在 表单元素中

<h4>{{ msg }}</h4>
<input type="text" style="width:100%;" v-model="msg">

 

v-model和v-bind的区别

class与style的绑定:

使用class样式:

数组
<h1 :class="['red', 'thin']">这是一个邪恶的H1</h1>
数组中使用三元表达式
<h1 :class="['red', 'thin', isactive?'active':'']">这是一个邪恶的H1</h1>
 数组中嵌套对象
<h1 :class="['red', 'thin', {'active': isactive}]">这是一个邪恶的H1</h1>
 直接使用对象
<h1 :class="{red:true, italic:true, active:true, thin:true}">这是一个邪恶的H1</h1>

.red {
  color: red;
}

.thin {
  font-weight: 200;
}

.italic {
  font-style: italic;
}

.active {
  letter-spacing: 0.5em;
}
<div id="app">
  <h1 class="red thin">这是一个很大很大的H1,大到你无法想象!!!</h1>

  <!-- 第一种使用方式,直接传递一个数组,注意: 这里的 class 需要使用  v-bind 做数据绑定 -->
  <h1 :class="['thin', 'italic']">这是一个很大很大的H1,大到你无法想象!!!</h1>

  <!-- 在数组中使用三元表达式 -->
  <h1 :class="['thin', 'italic', flag?'active':'']">这是一个很大很大的H1,大到你无法想象!!!</h1>

  <!-- 在数组中使用 对象来代替三元表达式,提高代码的可读性 -->
  <h1 :class="['thin', 'italic', {'active':flag} ]">这是一个很大很大的H1,大到你无法想象!!!</h1>

  <!-- 在为 class 使用 v-bind 绑定 对象的时候,对象的属性是类名,由于 对象的属性可带引号,也可不带引号,所以 这里我没写引号;  属性的值 是一个标识符 -->
  <h1 :class="classObj">这是一个很大很大的H1,大到你无法想象!!!</h1>
</div>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
  el: '#app',
  data: {
    flag: true,
    classObj: { red: true, thin: true, italic: false, active: false }
  },
  methods: {}
});

使用内联样式:

直接在元素上通过 `:style` 的形式,书写样式对象
<h1 :style="{color: 'red', 'font-size': '40px'}">这是一个善良的H1</h1>
将样式对象,定义到 `data` 中,并直接引用到 `:style` 中
在data上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="h1StyleObj">这是一个善良的H1</h1>
在 `:style` 中通过数组,引用多个 `data` 上的样式对象
在data上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
        h1StyleObj2: { fontStyle: 'italic' }
}
在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="[h1StyleObj, h1StyleObj2]">这是一个善良的H1</h1>

v-for:

v-for循环普通数组:
 

<div id="app">
    <p v-for="(item, i) in list">索引值:{{i}} --- 每一项:{{item}}</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    list: [1, 2, 3, 4, 5, 6]
  },
  methods: {}
});

v-for循环对象数组:

<div id="app">
  <p v-for="(user, i) in list">Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{i}}</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    list: [
      { id: 1, name: 'zs1' },
      { id: 2, name: 'zs2' },
      { id: 3, name: 'zs3' },
      { id: 4, name: 'zs4' }
    ]
  },
  methods: {}
});

v-for循环对象:

<div id="app">
  <!-- 注意:在遍历对象身上的键值对的时候, 除了 有  val  key  ,在第三个位置还有 一个 索引  -->
  <p v-for="(val, key, i) in user">值是: {{ val }} --- 键是: {{key}} -- 索引: {{i}}</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    user: {
      id: 1,
      name: 'aha',
      gender: '女'
    }
  },
  methods: {}
});


迭代数字
 

<div id="app">
  <!-- in 后面我们放过  普通数组,对象数组,对象, 还可以放数字 -->
  <!-- 注意:如果使用 v-for 迭代数字的话,前面的 count 值从 1 开始 -->
  <p v-for="count in 10">这是第 {{ count }} 次循环</p>
</div>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
  el: '#app',
  data: {},
  methods: {}
});

key:

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index" 

在一些特殊情况中,不使用key时会出现的问题

<div id="app">

  <div>
    <label>Id:
      <input type="text" v-model="id">
    </label>

    <label>Name:
      <input type="text" v-model="name">
    </label>

    <input type="button" value="添加" @click="add">
  </div>
  <p v-for="item in list" >
    <input type="checkbox">{{item.id}} --- {{item.name}}
  </p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    id: '',
    name: '',
    list: [
      { id: 1, name: '李斯' },
      { id: 2, name: '嬴政' },
      { id: 3, name: '赵高' },
      { id: 4, name: '韩非' },
      { id: 5, name: '荀子' }
    ]
  },
  methods: {
    add() { // 添加方法
      this.list.unshift({ id: this.id, name: this.name })
    }
  }
});

no key

出现的问题,本来是第四项被check,但是在头部添加一项以后,被check的变为了第三项

使用key以后:

2.2.0+ 的版本里,**当在组件中使用** v-for 时,key 现在是必须的。

    <!-- 注意: v-for 循环的时候,key 属性只能使用 number或者string -->
    <!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 -->
    <!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值 -->
    <p v-for="item in list" :key="item.id">
      <input type="checkbox">{{item.id}} --- {{item.name}}
    </p>

have key

添加一项元素以后,依然是第四项被check

v-if和v-show:

v-if 的特点:每次都会重新删除或创建元素
v-show 的特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式
v-if 有较高的切换性能消耗
v-show 有较高的初始渲染消耗(因为即使元素不被显示,也会被创建,只是加了个display:none样式) -->
如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show
如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if

<div id="app">
    <input type="button" value="toggle" @click="flag=!flag">
    <h3 v-if="flag">这是用v-if控制的元素</h3>
    <h3 v-show="flag">这是用v-show控制的元素</h3>
</div>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
  el: '#app',
  data: {
    flag: false
  },
  methods: {
    toggle() {
      this.flag = !this.flag
    } 
  }
});

v-if  v-show

过滤器:

Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;过滤器可以串联,会将filterA 的结果传递到 filterB 中

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

全局过滤器(所有VM实例都能共享这个过滤器):

    <p>{{ msg | msgFormat('疯狂+1', '123') | test }}</p>
    // 定义一个 Vue 全局的过滤器,名字叫做  msgFormat
    Vue.filter('msgFormat', function (msg, arg, arg2) {
      // 字符串的  replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则
      return msg.replace(/单纯/g, arg + arg2)
    })

    Vue.filter('test', function (msg) {
      return msg + '========'
    })

私有过滤器:

<td>{{ item.ctime | dateFormat() }}</td>
filters: { // 定义私有过滤器    过滤器有两个 条件  【过滤器名称 和 处理函数】
        // 过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致了,这时候 优先调用私有过滤器
        dateFormat: function (dateStr, pattern = '') {
          // 根据给定的时间字符串,得到特定的时间
          var dt = new Date(dateStr)

          //   yyyy-mm-dd
          var y = dt.getFullYear()
          var m = (dt.getMonth() + 1).toString().padStart(2, '0')
          var d = dt.getDate().toString().padStart(2, '0')

          if (pattern.toLowerCase() === 'yyyy-mm-dd') {
            return `${y}-${m}-${d}`
          } else {
            // padStart填充字符串
            var hh = dt.getHours().toString().padStart(2, '0')
            var mm = dt.getMinutes().toString().padStart(2, '0')
            var ss = dt.getSeconds().toString().padStart(2, '0')

            return `${y}-${m}-${d} ${hh}:${mm}:${ss} ~~~~~~~`
          }
        }
      }

自定义全局按键修饰符:

<input type="text" class="form-control" v-model="name" @keyup.f2="add">
Vue.config.keyCodes.f2 = 113

相当于:

<input type="text" class="form-control" v-model="name" @keyup.113="add">

自定义指令:

定义全局的指令:

    // 使用  Vue.directive() 定义全局的指令  v-focus
    // 其中:参数1 : 指令的名称,注意,在定义的时候,指令的名称前面,不需要加 v- 前缀, 
    // 但是: 在调用的时候,必须 在指令名称前 加上 v- 前缀来进行调用
    //  参数2: 是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作
    Vue.directive('focus', {
      bind: function (el) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
        // 注意: 在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
        // 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
        //  因为,一个元素,只有插入DOM之后,才能获取焦点
        // el.focus()
      },
      inserted: function (el) {  // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
        el.focus()
        // 和JS行为有关的操作,最好在 inserted 中去执行,放置 JS行为不生效
      },
      updated: function (el) {  // 当VNode更新的时候,会执行 updated, 可能会触发多次

      }
    })

    // 自定义一个 设置字体颜色的 指令
    Vue.directive('color', {
      // 样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
      // 将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
      bind: function (el, binding) {
        // el.style.color = 'red'
        // console.log(binding.name)
        // 和样式相关的操作,一般都可以在 bind 执行

        // console.log(binding.value)
        // console.log(binding.expression)

        el.style.color = binding.value
      }
    })

自定义私有指令:

directives: { // 自定义私有指令
        'fontweight': { // 设置字体粗细的
          bind: function (el, binding) {
            el.style.fontWeight = binding.value
          }
        },
        'fontsize': function (el, binding) { // 注意:这个 function 等同于 把 代码写到了 bind 和 update 中去
          el.style.fontSize = parseInt(binding.value) + 'px'
        }
      }

 

 

v-for 的列表过渡

1. 定义过渡样式:

<style>

.list-enter,

.list-leave-to {

opacity: 0;

transform: translateY(10px);

}

.list-enter-active,

.list-leave-active {

transition: all 0.3s ease;

}

</style>

2. 定义DOM结构,其中,需要使用 transition-group 组件把v-for循环的列表包裹起来:
 

<div id="app">

<input type="text" v-model="txt" @keyup.enter="add">

<transition-group tag="ul" name="list">

<li v-for="(item, i) in list" :key="i">{{item}}</li>

</transition-group>

</div>

3. 定义 VM中的结构:

// 创建 Vue 实例,得到 ViewModel

var vm = new Vue({

el: '#app',

data: {

txt: '',

list: [1, 2, 3, 4]

},

methods: {

add() {

this.list.push(this.txt);

this.txt = '';

}

}

});

列表的排序过渡

`<transition-group>` 组件还有一个特殊之处。不仅可以进入和离开动画,**还可以改变定位**。要使用这个新功能只需了解新增的 `v-move` 特性,**它会在元素的改变定位的过程中应用**。

`v-move` 和 `v-leave-active` 结合使用,能够让列表的过渡更加平缓柔和:

.v-move{

transition: all 0.8s ease;

}

.v-leave-active{

position: absolute;

}

定义Vue组件:

什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;

组件化和模块化的不同:

模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;

组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;

创建组件的方式:

 

    // 1.1 使用 Vue.extend 来创建全局的Vue组件
    // var com1 = Vue.extend({
    //   template: '<h3>这是使用 Vue.extend 创建的组件</h3>' // 通过 template 属性,指定了组件要展示的HTML结构
    // })
    // 1.2 使用 Vue.component('组件的名称', 创建出来的组件模板对象)
    // Vue.component('myCom1', com1)
    // 如果使用 Vue.component 定义全局组件的时候,组件名称使用了 驼峰命名,则在引用组件的时候,需要把 大写的驼峰改为小写的字母,同时,两个单词之前,使用 - 链接;
    // 如果不使用驼峰,则直接拿名称来使用即可;
    // Vue.component('mycom1', com1)

    // Vue.component 第一个参数:组件的名称,将来在引用组件的时候,就是一个 标签形式 来引入 它的
    // 第二个参数: Vue.extend 创建的组件  ,其中 template 就是组件将来要展示的HTML内容
    Vue.component('mycom1', Vue.extend({
      template: '<h3>这是使用 Vue.extend 创建的组件</h3>'
    }))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值