前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue2你该知道的一切(上)

vue2你该知道的一切(上)

作者头像
kai666666
发布2024-07-11 18:53:36
190
发布2024-07-11 18:53:36
举报
文章被收录于专栏:橙光笔记橙光笔记

Vue知识点众多,这两章记录一下Vue2.x版本的常规使用方法。如果你是一名使用Vue框架开发的前端工程师,那么这两章的内容会让你对Vue的知识点记得更牢固。

如何引入

HTML只要引入Vue就可以直接使用了,这里可以使用CDN地址https://unpkg.com/vue来引入Vue:

代码语言:javascript
复制
<div id="app"></div>

<script src="https://unpkg.com/vue"></script>
<script>
  new Vue({
    el: '#app',
    created() {
      // This code will run on startup
    }
  });
</script>

除了HTML直接引入Vue以外,也可以使用vue-loader与webpack配合,来使用.vue文件来编写代码,webpack中配置vue-loader如下(只截取vue-loader配置部分):

代码语言:javascript
复制
module: {
  rules: [
    {
      test: /\.vue$/,
      loader: 'vue-loader',
    },
    // ...其他loader
  ]
}

当然最简单的还是使用vue-cli来初始化一个项目:

代码语言:javascript
复制
npm install -g vue-cli
vue init webpack

基本使用

data中的数据可以使用双花括号引入,也可以用在v-开头的指令中,如下:

代码语言:javascript
复制
<div id="app">
  <p v-if="path === '/'">你在主页</p>
  <p v-else>你当前的地址是:{{ path }}</p>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      path: location.pathname
    }
  });
</script>

v-if与v-show的使用

代码语言:javascript
复制
<div v-if="true">v-if true</div>
<div v-if="false">v-if false</div>
<div v-show="true">v-show true</div>
<div v-show="false">v-show false</div>

最终输出的是HTML如下:

代码语言:javascript
复制
<div>v-if true</div>
<!---->
<div>v-show true</div>
<div style="display: none;">v-show false</div>

可见,v-show是使用display来控制是否显示的,而v-if则直接控制是有有该元素。

v-if多条件判断:

代码语言:javascript
复制
<div v-if="state === 'loading'">加载中..。</div>
<div v-else-if="state === 'error'">出错了</div>
<div v-else>其他内容</div>

v-for的使用

v-for是循环指令,可以用在数组,对象和数字上。

数组循环:

代码语言:javascript
复制
<div id="app">
  <ul>
    <li v-for="(item, index) in dogs" :key="index">{{ 1 + index + ':' + item }}</li>
  </ul>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      dogs: ['Rex', 'Rover', 'Henrietta', 'Alan']
    }
  });
</script>

对象循环:

代码语言:javascript
复制
<div id="app">
  <ul>
    <li v-for="(value, key) in obj" :key="key">{{ key + ':' + value }}</li>
  </ul>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      obj: {
        a: 1,
        b: 2,
        c: 3,
      }
    }
  });
</script>

数字循环,这里打印1~10,注意v-for用在数字上,索引会从1开始而不是0

代码语言:javascript
复制
<div id="app">
  <ul>
    <li v-for="num in 10" :key="num">{{ num }}</li>
  </ul>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
    }
  });
</script>

属性绑定

属性绑定使用v-bind:,或者简写形式:冒号

代码语言:javascript
复制
<div id="app">
  <button v-bind:type="buttonType">Test button</button>
  <button :type="buttonType">Test button</button>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      buttonType: 'submit'
    }
  });
</script>

由于Vue是使用Object.defineProperty来做的响应式的,所以对于给对象添加新的属性、使用数组下标修改数组值、修改数组长度来删除数组元素这三种操作是无法做到响应式,所以Vue提供了set和delete方法:

代码语言:javascript
复制
Vue.set(data, 'key', value);
// 组件内可以
this.$set(data, 'key', value);

Vue.delete( data, index);
// 组件内可以
this.$delete( data, index);

v-html

如果需要把一段字符串当做HTML元素来使用的时候可以使用v-html,否则HTML标签会被转移。需要注意的是v-html的内容一点要保证是安全的,否则容易受到XSS攻击。

代码语言:javascript
复制
<div v-html="yourHtml"></div>

v-modal双向绑定

代码语言:javascript
复制
<div id="app">
  <input type="text" v-model="inputText">
  <p>inputText: {{ inputText }}</p>
</div>

方法

代码语言:javascript
复制
<div id="app">
  <ul>
    <li v-for="number in filterPositive(numbers)">{{ number }}</li>
  </ul>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      numbers: [-5, 0, 2, -1, 1, 0.5]
    },
    methods: {
      filterPositive(numbers) {
        return numbers.filter((number) => number >= 0);
      }
    }
  });
</script>

计算属性

代码语言:javascript
复制
<div id="app">
  <p>Sum of numbers: {{ numberTotal }}</p>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      numbers: [5, 8, 3]
    },
    computed: {
      numberTotal() {
        return numbers.reduce((sum, val) => sum + val);
      }
    }
  });
</script>

计算属性与方法的区别:计算属性会被缓存,如果在模板中多次调用一个方法,方法中的代码在每一次调用时都会执行一遍,但是如果计算属性被多次调用,其中的代码会执行一次,之后每次调用都会使用被缓存的值。只有当计算属性的依赖发生变化时,代码才会被再次执行。此外方法可以携带参数,但是计算属性可以设置值,如下:

代码语言:javascript
复制
<div id="app">
  <p>Sum of numbers: {{ numberTotal }}</p>
</div>
<script>
  new Vue({
    el: '#app",
    data: {
      numbers: [5, 8, 3]
    },
    computed: {
      numberTotal: {
        get() {
          return numbers.reduce((sum, val) => sum + val);
        },
        set(newValue) {
          const oldValue = this.numberTotal;
          const difference = newValue - oldValue;
          this.numbers.push(difference)
        }
      }
    }
  });
</script>

watch的使用

代码语言:javascript
复制
new Vue({
  el: '#app',
  data: {
    count: 0
  },
  watchers: {
    count(newValue, oldValue) {
      // this.count has been changed!
      console.log('新的值:' + newValue)
      console.log('旧的值:' + oldValue)
    }
  }
});

注意:在watch中一定不要去修改当前监听的值,否则容易造成死循环。如上面count方法中不要写this.count = XXX

watch也可以监听对象的某个属性:

代码语言:javascript
复制
new Vue({
  data: {
    formData: {
      username: ''
    }
  },
  watch: {
    'formData.username'(newValue, oldValue) {
      // this.formData.username has changed
    }
  }
});

当然也可以使用函数来监听:

代码语言:javascript
复制
this.$watch('formData.username', function (newValue, oldValue) {

})

对于watch监听对象的情况如果对象的引用不变,则不会调用监听的方法,如上面formData.username改变如果只监听formData则不会调用,如果这种情况需要调用的时候,可以传递deep参数:

代码语言:javascript
复制
new Vue({
  data: {
    formData: {
      username: ''
    }
  },
  watch: {
    formData: {
      handler(newValue, oldValue) {
        // formData.username改变也会调用
      },
      deep: true
    }
  }
});

filter的使用

代码语言:javascript
复制
<div id="app">
  <p>Product one cost: {{ productOneCost | formatCost('$') }}</p>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      productOneCost: 998,
    },
    filters: {
      formatCost(value, symbol = '¥') {
        return symbol + (value / 100).toFixed(2);
      }
    }
  });
</script>

上述最后渲染出的是Product one cost: $9.98,filter也可以不传参数,如下

代码语言:javascript
复制
<p>Product one cost: {{ productOneCost | formatCost }}</p>

上述渲染出的是Product one cost: ¥9.98

除此之外还可以定义全局的过滤器:

代码语言:javascript
复制
Vue.filter('formatCost', function (value, symbol = '¥') {
  return symbol + (value / 100).toFixed(2);
})

使用ref访问元素或者组件

代码语言:javascript
复制
<canvas ref="myCanvas"/>

<!-- JS中使用如下访问 -->
<!-- this.$refs.myCanvas -->

事件

最简单的使用:

代码语言:javascript
复制
<button v-on:click="counter++">Click to increase counter</button>
<p>You've clicked the button {{ counter }}</P> times.

使用方法:

代码语言:javascript
复制
<div id="app">
  <button v-on:click="increase">Click to increase counter</button>
  <p>You've clicked the button {{ counter }}</p> times.
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      counter: 0
    },
    methods: {
      increase(e) {
        this.counter++;
      }
    }
  });
</script>

v-on:可以使用@来代替简写:

代码语言:javascript
复制
<button @click="increase">Click to increase counter</button>

修饰符:

代码语言:javascript
复制
<button @click.stop.prevent="increase">Click to increase counter</button>
<input @keyup.enter="submit">

Vue的修饰符有很多,不同修饰符间可以连用,修饰符的顺序不同左右可能也会不同。这里简单的列举一下常用的修饰符:

常用修饰符

说明

.stop

阻止事件冒泡

.prevent

阻止默认行为

.capture

捕获模式

.self

只监听元素自身而不监听子元素

.once

只调用一次方法

.passive

提前告知不阻止默认行为(可以提高移动端性能),不可与.prevent一起使用,如果同时存在则忽略.prevent

.exact

准确地触发,如@click.ctrl.exact则只有当ctrl按下并且点击的时候才触发;再如@click.exact则只有点击切不能按任何其他键才触发

.ctrl

ctrl按下时

.alt

alt按下时

.shift

shift按下时

.meta

Command或者Windows键被按下时

鼠标按钮修饰符:

修饰符

说明

.left

鼠标左键,如@mousedown.left表示鼠标左键被按下

.right

鼠标右键

.middle

鼠标滚轮

对于keyup等按键事件来说,提供了专门的按键修饰符,如:.enter.tab.delete(捕获“删除”和“退格”键)、.esc.space.up.down.left.right.数字(数字对应的是keyCode)

也可以自定义键名,如v-on:keyup.f1

代码语言:javascript
复制
Vue.config.keyCodes.f1 = 112

生命周期钩子函数

代码语言:javascript
复制
new Vue({
  beforeCreate() { // 实例初始化前被触发
  },
  created() {// 初始化后被添加到DOM之前触发
  },
  beforeMount() {// 已经准备好添加DOM前触发
  },
  mounted() {// 元素创建后触发(不一定添加到DOM中了,需要使用nextTick来保证添加进去了)
  },
  beforeUpdate() {// 数据更新后将对dom做一些更改时触发
  },
  updated() {// DOM更新后触发
  },
  deforeDestroy() {// 即将销毁时触发
  },
  destroyed() {// 销毁后触发
  }
})

自定义指令

代码语言:javascript
复制
<p v-blink>This content will blink</p>

<script>
Vue.directive('blink', {
  bind(el, binding, vnode, oldVno) {
    let isVisible = true;
    el.dataset.blinkTimer = setInterval(() => {
      isVisible = !isVisible;
      el.style.visibility = isVisible ? 'visible' : 'hidden';
    }, binding.value || 1000);
  },
  unbind(el) {
    if(el.dataset.blinkTimer) {
      clearInterval(el.dataset.blinkTimer);
      delete el.dataset.blinkTimer
    }
  }
});
</script>

指令有5个钩子函数:bind、inserted、update、componentUpdated、unbind。 update指的是当前组件被更新时调用,此时可能子组件还没有更新。componentUpdated是所有子组件都更新后调用。

定义指令还有一种简写的形式:

代码语言:javascript
复制
Vue.directive('my-directive', (el) => {
  // 这里的回调将会在bind和update的时候调用
});

钩子函数的参数有el、binding、vnode 和 oldVnod。其中binding又是一个对象,它的属性有:name、value、oldValue(仅在 update 和 componentUpdated钩子中可用)、expression、arg、modifiers。

transition动画

代码语言:javascript
复制
<transition name="fade">
  <div v-if="divVisible">This content is sometimes hidden</div>
</transition>

<style>
.fade-enter-active, .fade-leave-active {
    transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
    opacity: 0;
}
</style>

过渡类名:{name}-enter、{name}-enter-active、{name}-enter-to、{name}-leave、{name}-leave-active、{name}-leave-to。

过渡也可以使用JS的钩子函数来做:

代码语言:javascript
复制
<transition
    v-on:before-enter="handleBeforeEnter"
    v-on:enter="handleEnterp"
    v-on:leave="handleLeave">
  <div v-if="divVisible">...</div>
</transition>

<script>
new Vue({
  el: '#app',
  data: {
    divVisible: false
  },
  methods: {
    handleBeforeEnter(el) {
      el.style.opacity = 0;
    },
    handleEnter(el, done) {
      TweenLite.to(el, 0.6, { opacity: 1, onComplete: done });
    },
    handleLeave(el, done) {
      TweenLite.to(el, 0.6, { opacity: 0, onComplete: done });
    }
  }
});
</script>

绑定Class

静态使用class:

代码语言:javascript
复制
<div class="foo bar">
  <!-- ... -->
</div>

可以使用数组:

代码语言:javascript
复制
<div :class="['foo', 'bar']">
  <!-- ... -->
</div>

也可以使用对象,如果值为true的时候则使用该类:

代码语言:javascript
复制
<div :class="{foo: false, bar: true}">
  <!-- ... -->
</div>

还可以混着使用数组和对象:

代码语言:javascript
复制
<div :class="['class1', {foo: false, bar: true}]">
  <!-- ... -->
</div>

还可以写一个静态的和一个动态的class,最终的结果是两者的合并:

代码语言:javascript
复制
<div class="class1" :class="{foo: false, bar: true}">
  <!-- ... -->
</div>

绑定style

style的绑定和class有些类似,需要注意的是对于font-weight这种带有连字符的属性需要使用驼峰形式,如fontWeight

对象形式:

代码语言:javascript
复制
<div :style="{ fontWeight: 'bold', color: 'red' }"></div>

数组形式,可以串联多个对象:

代码语言:javascript
复制
<div :style="[{fontWeight: 'bold'}, {color: 'red'}]">...</div>

一般情况下,Vue会自动加上浏览器的前缀的,当然也可以自己设置多重置:

代码语言:javascript
复制
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">...</div>

vue-loader的Scoped CSS

在.vue文件中样式默认是全局的,如果在style标签中加入scoped则只会应用在本组件内:

代码语言:javascript
复制
<template>
  <p>The number is <span class="number">123</span></p>
</template>

<script>
  export default {
  };
</script>

<style scoped>
  .number {
    font-weight: bold;
  }
</style>

为什么会只改变本组件呢?实际上当写有scoped后,打包出来的组件元素都将会有一个data-v-{hash}的属性,而样式也会加上该属性,如下(hash可能是其他的值):

代码语言:javascript
复制
<p data-v-e0e8ddca>The number is <span data-v-e0e8ddca class="number">123</span></p>

<style>
.number[data-v-e0e8ddca] {
  font-weight: bold;
}
</style>

vue-loader的CSS Modules

style标签中使用module属性,表示使用了CSS Modules,如下:

代码语言:javascript
复制
<template>
  <p>The number is <span :class="$style.number">{{ number }}</span></p>
</template>

<style module>
  .number {
    font-weight: bold;
  }
</style>

使用SCSS

首先需要安装SCSS,使用命令:

代码语言:javascript
复制
npm install --save-dev sass-loader node-sass

然后在style上使用lang="scss"属性就可以了:

代码语言:javascript
复制
<style lang="scss" scoped>
  $color: red;

  .number {
    font-weight: bold;
    color: $color;
  }
</style>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何引入
  • 基本使用
  • v-if与v-show的使用
  • v-for的使用
  • 属性绑定
  • v-html
  • v-modal双向绑定
  • 方法
  • 计算属性
  • watch的使用
  • filter的使用
  • 使用ref访问元素或者组件
  • 事件
  • 生命周期钩子函数
  • 自定义指令
  • transition动画
  • 绑定Class
  • 绑定style
  • vue-loader的Scoped CSS
  • vue-loader的CSS Modules
  • 使用SCSS
相关产品与服务
内容分发网络 CDN
内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档