VUE知识整理-----一起学习(一)

194 阅读2分钟

VUE官方网址

cn.vuejs.org/

vue的属性和方法

vue的属性和方法

  • var data={a:1}
  • var vm=new Vue({el:'#app',data:data}) 属性:
  • vm.data.a//data.a // data就是vm中data存储的变量,同vm.a 方法:
  • vm.$watch('a',function(newValue,oldValue){ // 观察变量a发生改变时会触发函数,参数1为变化后的值,oldValue为变化前的值}

生命周期钩子

生命周期钩子(因箭头函数没有this,固生命周期钩子不能用箭头函数定义)

  • beforeCreate:function(){},// 实例创建之前
  • created:function(){}, // 实例创建之后,通常获取ajax
  • beforeMount:function(){}, // 数据挂载到模版之前
  • mounted:function(){}, // 数据挂载到模版之后,通常写window事件
  • beforeUpdate:function(){}, // 数据变化之前
  • updated:function(){}, // 数据、结构已经更新完成
  • beforeDesdroy(){}, // 实例销毁之前
  • destroyed(){} // 实例销毁之后

内置指令

指令 v-xxx

指令即带有v-前缀的特性,当指令的表达式(值)发生改变时,将产生的连带影响响应式地作用于DOM

    1. v-once 只渲染一次,变量发生改变不会进行改变
<span v-once> {{msg}} </span>
    1. v-html 渲染html代码
<p v-html="rawHtml"></p>
    1. v-bind 给原html属性绑定变量
// 所有的v-bind:都可简写为 :
<div v-bind:class="color">test...</div> // 简写 <div :class="color"></div>
// 此时的color为vue的变量 color:'red'而非类名
    1. 条件渲染 v-if、v-else-if、v-else 是否渲染标签
// 一般不频繁更换状态时使用v-if
<p v-if="seen"></p> // seen为true时渲染p标签,false时不渲染
<div v-if="type=='A'"></div> // type为 'A'时
<div v-else-if="type=='B'"></div> // type为 'B'时
<div v-else-if="type=='C'"></div> // type为 'C'时
<div v-else"></div> // type不为A、B、C时
    1. 条件渲染 v-show 标签是否显示
// 一般频繁更换状态时使用v-show
<h1 v-show="ok"></h1> // ok为true时h1标签的displaynone
    1. 类名渲染v-bind:class
// 表达式结果的类型可以是字符串、对象、数组
字符串表达式:
	<div class="test" :class="activeClass"></div>
	// activeClass:'active green'
对象表达式:
	<div class="test" :class="{active:isActive,green:true}"></div>
    // isActive为true时存在active类名 且与原class可以同时存在
数组表达式:
	<div :class="[ 'active','green',{'active2': true}]"></div>
    1. 行内样式渲染 v-bind:style
<div :style="{color:color,fontSize:size,background: isRed ? '#f00' : ''}"></div>
// color:'#f00',size:'50px',isRed:true
// 注意不能写font-size,要改成fontSize
    1. 列表渲染 v-for
数组渲染:
	<li v-for="(item,index) in items" :key="item.id">
      // items:[{id:1,message:'a'},{id:2,message:'b'}]
      // key的作用是数据的唯一标识,item没有id时key采用index
      {{ item.message }}  // 此时的item.message为'a','b'
      {{ index }}   // 此时的index为下标0,1
    </li>
对象渲染:
	<li v-for="value,key,index in object" :key="key">
      // object:{title:'a',author:'b','publishedAt:'c'}
      {{ value }}  // 此时的value为 a,b,c
      {{ key }}  // 此时的key为 title,author,publishedAt
      {{ index }}  // 此时的index为下标0,1
    </li>
    1. 事件绑定v-on
<button v-on:click="counter+=1"></button>
// data:{counter:0}
<button v-on:click="f1"></button>
// methods:{ f1:function(event){} } // 不传参时参数默认会传event参数
<button v-on:click="f1('abc')"></button>
// methods:{ f1:function(str){ console.log(str); } }
<button v-on:click="f1($event)"></button>
// 传参时$event变量为事件变量
    1. v-model 表单双向数据绑定
原理:
	<yxdt-rate v-model="rate"></yxdt-rate>
	// v-model="rate" 是 :value="rate" @input="rate = $event.target.value" 的缩写。
	// 自定义双向绑定 :val="rate" @input="setRate"  setRate(rate){ this.rate=rate; }
输入表单:
	<input v-model="message">
    // 当input框的值发生改变时 p标签里的内容也会发生改变
    <p>{{message}}</p>
复选框:
	<input type="checkbox" value="a" v-model="checkedNames">
    <input type="checkbox" value="b" v-model="checkedNames">
    <input type="checkbox" value="c" v-model="checkedNames">
    <p>{{checkedNames}}</p> // 全选中的渲染结果为 ["a","b","c"]
    // data:{ checkedNames:[] } 
    // 可设默认值 data:{ checkedNames:['a','b'] }
单选框:
	<input type="radio" value="a" v-model="picked" name="test">
    <input type="radio" value="b" v-model="picked" name="test">
    <p>{{picked}}</p> // 选中a时 picked为a
下拉框:
	<select>
 		<option v-for="c in citys" :value="c.code" v-model="sh">{{c.name}}</option>
	</select>	// data:{ citys:[{value:'bj',name:'beijing'},{value:'sh',name:'shanghai'},..

指令的修饰符

让指令以特殊的方式绑定

  • 1.stop 阻止冒泡
<div @click="click1">
	<div @click.stop="click2">click me</div>
	// 此时只执行click2函数不执行click1函数
</div>
  • 2.prevent 阻止默认事件
<form v-on:submit.prevent="onSubmit"></form>
// 修饰符可串联
<a v-on:click.stop.prevent="doThat"></a>
// 只有修饰符也可以
<form v-on:submit.prevent></form>
  • 3.capture 事件捕获
<div v-on:click.capture="dothis"></div>
  • 4.self 只有当自身触发时才执行函数
<div v-on:click.self="dothat"></div>
  • 5.once 点击的事件只会触发一次
<div v-on:click.once="dothat"></div>
  • 6.passive
修饰符会执行默认方法
  • 7.按键修饰符 v-on:keyup.按键名 // @keyup.enter="fn"

定义事件 methods

定义事件

var vm=new Vue({
	...,
    methods:{
    	click1:function(){},
        click2:function(){},
    }
});

注册全局组件 Vue.component

定义:

Vue.component('button-counter',{
	// 组件必须在new Vue之前定义 且在挂载标签内调用
    data:function(){ // 该组件的数据,必须为函数
    	return { count:0 }
    },
    template:'<button v-on:click="count++"> Click Me {{count}} times</button>'
});
var vm=new Vue({...})

调用(组件可复用):

<button-counter></button-counter>
Vue-cli中注册自定义组件:
const myComponent=require('./components/base/base-myComponent.vue');
自动循环添加:
const requireComponent = require.context(
  './components/base',
  false,
  /base-[a-z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
  const componentConfig = requireComponent(fileName)
  // 转化大驼峰命名(./base-autofold.vue -> BaseAutofold)
  const componentName = upperFirst(
    camelCase(
      fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
    )
  )
  Vue.component(
    componentName,
    componentConfig.default || componentConfig
  )
})

组件间通信 父子组件传参

父传子,有三种props向子组件传递数据的方式:

  • 父组件:
<my-component :id="id" :name="name" :getEmp="getEmp"></my-component>
  • 子组件:
const MyComponent={
	template:'<div></div>',
    props:['id','name','getEmp'] // 方式1,指定传递属性名
    props:{   // 方式2,指定传递属性名和数据类型(Number,String,Array,Object,Function,Promise,Boolean)
    	id:Number,
        name:String,
        getEmp:Function
    }
    props:{ // 方式3,指定属性名、数据类型、必要性、默认值
    	name:{
        	type:String, // 数据类型
            required:true, // 必要性
            default:'mxg' // 默认值
        } // 当default为数组时:default(){ return [] }
    }
}

子传父,$emit子组件向父组件发送消息(等同于父元素通过props传递函数给子组件)

  • 父组件:
<my-component @get_emp="getEmp"></my-component> // 等同 :getEmp="getEmp"
// get_emp为自定义事件名,事件名不能大写,@可以替换为v-on:,getEmp为父组件函数
  • 子组件:
const MyComponent={
	template:'<div><a @click="myGet">click</a></div>',
    methods:{
    	myGet(){
        	this.$emit('get_emp','param');// 通过$emit调用执行父组件参数get_emp的函数,第二个参数开始为参数
        }// 等同 props:['getEmp'],this.getEmp('param')
    }
}

slot插槽,父组件向子组件传递标签、数据

slot插槽,父组件向子组件传递标签、数据(传递的插槽数据需定义在父组件中)
  • 单个插槽
父组件:
	<button-counter> <h2>h2</h2> </button-counter>
子组件:
	Vue.component('button-counter',{
    	...
        template:'<div><h1>h1</h1><slot></slot></div>
    });
  • 多个插槽
父组件通过slot属性指定替换子组件中的插槽:
	<component-a>
          <div slot="aaa">aaa</div>
          <div slot="bbb">bbb</div>
	</component-a>
子组件中定义插槽:
	<div>
          <slot name="aaa"></slot>
          <slot name="bbb"></slot>
	</div>
        

具名插槽v-slot

父组件通过slot属性指定替换子组件中的插槽
<component-a>
  <template v-slot:header><div>Header content</div></template>
  // 等同于 <h1 slot="header">Header content</h1>
  <template v-slot:default><div>Default content</div></template>
  // 等同于 <h1>Default content</h1>
  <template v-slot:footer><div>Footer content</div></template>
  // 等同于 <h1 slot="footer">Footer content</h1>
</component-a>
子组件中定义插槽:
  <div>
    <slot name="header"></slot>
    <slot></slot>
    <slot name="footer"></slot>
  </div>

作用域插槽slot-scope

旧写法(2.6.0-):
  <template slot="header" slot-scope="slotProps">
    // 新写法可简写为<template #header="slotProps">
    <div>Header content{{slotProps.user.firstName}}</div>
  <template>
新写法(2.6.0+):
  父组件通过slot属性指定替换子组件中的插槽:
    <component-a>
      <template v-slot:[zz]="slotProps">
        // zz表示动态插槽名,slotProps为子组件中的数据参数对象
        <div>Header content{{slotProps.user.firstName}}</div>
      </template>
      <template v-slot:default><div>Default content</div></template>
      <template v-slot:footer><div>Footer content</div></template>
    </component-a>
    data:{ zz:'header' }
  子组件中定义插槽:
    <div>
      <slot name="header" :user="user"></slot> // 通过自定义属性给父组件的插槽上传参
      <slot><h1>无插槽时默认结构</h1></slot>
      <slot name="footer"></slot>
    </div>
    data:{
      user:{ firstName:'zheng',lastName:'xiaodong' }
    }