Vue2 简单入门级学习

215 阅读5分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

Vue2 基础语法

文章都是我从自己的笔记中复制过来的,所以整篇文章风格更加偏向笔记风,没有像文章那样的解释之类的

let vm = new Vue({
	// 挂载点
  el: '.app',
  // 存放响应式数据
  data: {
    msg: '你好',
    msg2: '数据'
  },
  // 计算属性
  computed: {
    'msgGetters':function(){
      return this.msg2 + '测试'
    }
  },
  // 存放方法
  methods: {
    clickDiv(){
      console.log('点击了 div')
    }
  }
})

v-xxx 基础指令

  • v-text

渲染 vue 数据,但不能渲染数据中的 HTML 标签

  • v-html

渲染 vue 数据:v-html = 'msg'

能够渲染数据中的 HTML 标签

  • v-cloak

解决刷新页面时,数据闪烁问题。

  • v-bind

单向绑定数据:v-bind:属性名 = 'msg'

简写::属性名 = 'msg'

修饰符:

    • .prop:将数据绑定到元素的 property 上。
    • .sync:语法糖,用来修改父组件数据。
  • v-on

事件绑定:v-on:click = 'add()'

简写为: @click = 'add()'

修饰符:

  • .stop:阻止事件冒泡
  • .prevent:阻止 DOM 默认行为
  • .capture:实现捕获触发事件的机制
  • .self:规定冒泡与捕获无法触发本事件
  • .once:规定只能触发一次本事件
  • .left:规定只有鼠标左键才能触发此事件
  • .right:规定只有鼠标右键才能触发此事件
  • .midde:规定只有鼠标中键能够触发本事件
  • @keyup.按键码:将事件绑定到键盘,当按下对应事件码时触发事件。
  • v-model

双向数据绑定,修饰符:

  • .lazy:取代 input 监听 onchange事件
  • .number:将输入的字符串转为有效数字
  • .trim:清除输入数据的首尾空格
  • v-for

循环渲染数组、对象、数字、字符串

  • v-if

创建删除元素

  • v-else

配合 v-if 使用

  • v-else-if

配合 v-if 和 v-else 使用

  • v-show

显示隐藏元素

  • v-slot

插槽指令

  • v-pre

声明跳过此元素的编译过程,显示原始标签。

  • v-once

表明此 DOM 或组件只渲染一次,之后这个 DOM、组件及其所有的子节点都将被视为静态内容而不会被更新渲染。可以用于优化更新性能。

filter 过滤器

私有过滤器比全局过滤器优先级要高。(Vue3 已删除过滤器语法)。

// 全局过滤器
// 第一个参数永远代表数据本身,第二个则是自定义的参数
Vue.filter('filterVal', function(msg, data){
	return data + 1
})

// 私有过滤器
let vm = new Vue({
	// 挂载点
  el: '.app',
  filters:{
  	filterVal: function(msg, data){
    	return data + 1
    }
  }
})

// 过滤器使用时:响应式数据 | 过滤器(参数)
<p>{{ data | filterVal('1') }}</p>

watch 侦听器

watch 会对目标进行侦听,当侦听的目标发生变化时就会触发侦听器的事件。

let vm = new Vue({
	// 挂载点
  el: '.app',
  data: {
  	msg: '你好'
  },
  // 监听数据
  watch: {
    // 侦听数据
    // 侦听器的第一个参数为最新的值,第二个值为上一次的值。
    msg(newMsg, oldMsg){
      this.msg = this.msg + '+我好'
    },
    // 侦听路由
    '$route.path': function(newMsg, oldMsg){
    	// 处理事件
    }
    // immediate 属性,设置为 true 后,将会在加载页面时就对数据进行一次事件处理
    // 而非等待数据发生变化再去触发事件处理
    immediate: true
    // deep 深度监听
    deep: true,
    // 开启深度监听后可以监听对象中的数值
    'Obj.a'(newMsg, oldMsg){
			// 处理事件
		}
  }
})

computed 计算属性

计算属性内部的所有 data,只要其中一个发生了变化,那么就会立刻调用这个计算属性函数,并将结果缓存下来,方便下次使用。

let vm = new Vue({
	// 挂载点
  el: '.app',
  data:{
  	msg: 1,
    msg1: 2
  },
  // 计算数据
  computed: {
  	'fullMsg': function(){
    	return msg + msg1
    },
    // getter 和 setter 属性
    // setter 可以在数据被修改时执行一些操作
    'modifyMsg':{
  		// getter
      get: function () {
          // 处理事件
      },
      // setter
      set: function (newValue) {
          // 处理事件
      }
  	}
  }
})

// 使用,使用时不必要当做函数调用而加上(),
// 只需要将其当做普通数据使用就可。
// 可以将其理解为一个进行加工后的数据。
<p>{{ fullMsg }}</p>

keyup 按键修饰符

常见按键修饰符:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统按键修饰符

  • .ctrl
  • .alt
  • .shift
  • .meta

鼠标按揭修饰符

  • .left
  • .right
  • .middle
// 输入框按下回车键时触发
<input @keyup.enter="add()">123</input>

// ctrl 加单击时触发
<o @click.ctrl="sum()">123</p>

<!-- alt 和回车同时按下才会触发 -->
<input @keyup.alt.enter="clear" />

.exact 修饰符

对按键修饰符进行精确控制。

<!-- 按住 ctrl 的同时安装其他键盘也可以触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 只有在按下 ctrl 时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有按下任何键盘时才会触发 -->
<button @click.exact="onClick">A</button>

directive 自定指令

八个常用自定指令:

www.cnblogs.com/lzq035/p/14…

定义的指令在调用时需要加上 v- 前缀。

// 定义全局指令
Vue.directive('clickColor', {
	// 执行事件
})

let vm = new Vue({
	// 挂载点
  el: '.app',
  // 局部自定指令
  directives:{
    // 指令定义时可以使用大写,
    // 但在调用时必须改为小写:v-click-color
  	clickColor:{
    	// 执行事件
    }
  }
})

// 给指令传参数时需加上 '' 号
<p v-click-color="'blue'">指令测试</p>

钩子函数生命周期

mounted

  • 模板挂载时调用。

bind

  • 只调用一次,在指令绑定到元素上时调用。(CSS 样式最早在这使用)。

inserted

  • 只调用一次,在被绑定元素插入父节点时调用。(js 行为最早在这使用)。

update

  • 绑定元素 Vnode 更新时调用。

componentUp的、ate

  • 帮顶元素 Vnode 及子 Vnode 都更新时调用。

unbind

  • 只调用一次,指令解绑时调用。
// 定义全局指令
Vue.directive('clickColor', {
  mounted(){},
	bind(){},
  inserted(){},
  update(){},
  componentUpdate(){},
  unbind(){}
})

钩子函数参数

el

  • 指令绑定的元素本身,用来操作 DOM。

binding

  • 返回一个对象,对象中包含。

name

  • 指令的名称,不包含 v-。

value

  • 通过指令传入的所有值。

oldvalue

  • 指令绑定的前一个值,只能在 update 和 ComponentUpdate 中使用。

expression

  • 字符串形式的指令表达式。

arg

  • 传给指令的参数。

modifiers

  • 包含修饰符的对象。
  • Tips:arg 与 modifiers 的区别在于一个是使用 : 冒号一个是使用 . 点号。

vnode

  • Vue 编译成的虚拟节点。

oldvnode

  • Vue 编译成的上一个虚拟节点,只能在 update 和 ComponentUpdate 中使用。
// 定义全局指令
Vue.directive('clickColor', {
	bind(el, binding, vnode){
  	// ...
  },
  inserted(el, binding, vnode){
  	// ... 
  },
  // oldVnode 只能在 update 和 componentUpdate 中使用
  update(el, binding, vnode, oldVnode){
  	// binding 中的 oldvalue 属性
    // 只能在 update 和 componentUpdate 中使用
  	console.log(binding.oldvalue)
  },
  componentUpdate(el, binding, vnode, oldVnode){
    // ...
  },
  unbind(el, binding, vnode){
  	// ...
  }
})

component 组件

组件简单学习

// 定义一个名为 button-counter 的组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: `<button v-on:click="count++">
  						组件定义:{{ count }}</button>`
})

// 另一种定义方法
Vue.component('button-counter2', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '#myTemp'
})
<template id="myTemp">
	<p v-on:click="count++">第二种组件定义方法:{{ count }}</p>
</template>

// 私有组件定义
let vm = new Vue({
	// 挂载点
  el: '.app',
  // 局部组件
  components:{
  	temp:{
      // 组件名
    	template: '#add-count',
      data: function(){
      	return{
        	count: 1
        }
      },
      methods:{
      	add(){
        	this.count ++
        }
      }
    },
    temp1:{
      // 组件名
    	template: '#content'
    }
  }
})

// 组件1
<template id="add-count">
	<p @click="add()">{{ count }}</p>  
</template>
// 组件2
<template id="content">
	<p>组件内容</p>  
</template>

组件切换

使用 component 的 is 属性来切换组件的使用。

// 通过切换不同的组件名来实现,组件的切换效果
<component :is="组件名"></component>

// 使用 transition 给组件添加切换时的动画效果
// out-in 定义组件动画为先出去再进来
<transition mode="out-in" 
		// 退出动画定义
    leave-active-class="类名"
		// 进入动画定义
    enter-active-class="类名"
		// 设置组件的进入退出时间
    :duration="{enter:1000,leave:400}">
    // 切换组件
    <component :is="组件名"></component>
</transition>

// 组件缓存
<keep-alive 
	include="匹配那些组件可以被缓存" 
	exclude="定义那些组件不可以被缓存" 
	max="定义最多可以缓存多少组件,默认为 5 个">
<component :is="组件名">缓存</component>      
</keep-alive>

ref

ref 是 Vue 内部提供的一个用来获取 DOM 的语法糖。因为也可以获取到子组件 DOM,所以常用来做父子组件通信。

<p ref="p">123</p>
<子组件 res="component"></子组件>

// 输出:123
console.log(this.$ref.p.innerText)

// 使用子组件数据
console.log(this.$refs.component.msg)
// 调用子组件方法
this.$refs.component.function()

Vue2 生命周期

创建前

  • beforeCreate(){}

创建后

  • created(){}

模板挂载前

  • beforeMount(){}

模板怪哉后

  • mounted(){}

更新前

  • beforeupdate(){}

更新后

  • update(){}

销毁前

  • beforDestroy(){}

销毁后

  • destroy(){}

slot 插槽

插槽使用场景:如果子组件需要显示的内容并非来自本身,而是父组件传递进来的,是不会显示的。需要在原本子组件内容里添加个 slot 标签才会显示。

例如下面这个:

<div id="app">
  <me-component>
    // 此时 h1 标签是不会显示的
    <h1>我是header</h1>
  </me-component>
</div>
<script>
  Vue.component('me-component', {
    template:
    `<div>
      <p>你好</p>
    </div>`
  })
  var vm = new Vue({
    el:"#app"
  })
</script>

修改后:

<div id="app">
  <me-component>
    // 能够显示了
    <h1>我是header</h1>
  </me-component>
</div>
<script>
  Vue.component('me-component', {
    template:
      `<div>
        <p>你好</p>
				// 加上 slot 插槽标签
        <slot></slot>
      </div>`
  })
  var vm = new Vue({
    el:"#app"
  })
</script>

具名插槽(v-slot:name)

如果需要显示多个内容时,可以使用具名插槽。

<div id="app">
  <me-component>
    <h1 v-slot:header>我是 header</h1>
    <h2 v-slot:footer>我是 footerr</h2>
  </me-component>
</div>
<script>
  Vue.component('me-component', {
    template:
    `<div>
      <p>你好</p>
      <slot name="header"></slot>
      <slot name="footer"></slot>
    </div>`
  })
  var vm = new Vue({
    el:"#app"
  })
</script>

插槽默认内容

另外,插槽还支持默认内容显示:

<div id="app">
  <me-component>
    <h1 slot="header">我是header</h1>
    <!-- <h1 slot="footer">我是footerr</h1> -->
  </me-component>
</div>
<script>
  Vue.component('me-component', {
    template:
    `<div>
      <p>你好</p>
      <slot name="header">我是默认内容1</slot>
      <slot name="footer">我是默认内容2</slot>
    </div>`
  })
  var vm = new Vue({
    el:"#app"
  })
</script>

作用域插槽(scope)

插槽的内容最后是在子组件模板上渲染的,但是假设这时我们需要使用子组件中的数据,这种时候就需要作用域插槽解决问题了。

       作用域插槽是一种特殊类型的插槽,用作一个(能被传递数据的)可重用模板,来代替已经渲染好的元素。利用 slot 标签将子组件的数据传递到分发的内容上,类似于父子组件传值的 prop 传递数据。

<div id="app">
  <me-component v-slot:userName="scope">
    <p v-for="(key, value) in scope" v-key="key">{{ value }}</p>
  </me-component>
</div>
<script>
  Vue.component('me-component', {
    template:
    `<div>
      <p>你好</p>
      <slot name="name" :userName="user"></slot>
    </div>`
  })
  var vm = new Vue({
    el:"#app",
    data: {
      user: {
        firstName: '张三',
        lastName: '李四'
      }
    }
  })
</script>

keep-alive 组件缓存

keep-alive 是 vue 的内置组件,用作缓存组件。

<template>
  <div id="app">
  	<keep-alive>
      <router-view/>
    </keep-alive>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

1. 参数

  • include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
  • exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
  • max - 数字。最多可以缓存多少组件实例。
<template>
  <div id="app">
  	// 1. 将缓存 name 为 test 的组件
  	<keep-alive include='test'>
      <router-view/>
    </keep-alive>
	
	// 2. 将缓存 name 为 a 或者 b 的组件,结合动态组件使用
	<keep-alive include='a,b'>
  	  <router-view/>
	</keep-alive>
	
	// 3. 使用正则表达式,需使用 v-bind
	<keep-alive :include='/a|b/'>
  	  <router-view/>
	</keep-alive>	
	
	// 5.动态判断
	<keep-alive :include='includedComponents'>
  	  <router-view/>
	</keep-alive>
	
	// 5. 将不缓存 name 为 test 的组件
	<keep-alive exclude='test'>
  	  <router-view/>
	</keep-alive>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

2. 独有生命周期:activated、deactivated

注意一点:activated, deactivated 这两个生命周期函数一定是要在使用了keep-alive 组件后才会有的,否则则不存在。

当引入 keep-alive 的时候,页面第一次进入,钩子的触发顺序为:created-> mounted-> activated,退出时触发 deactivated。当再次进入组件(前进或者后退)时,只触发 activated。

一般事件挂载的方法,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中, activated 中的不管是否需要缓存多会执行。