vue 2
快速试验
导包
-
官网下载
- 开发版
- 生产版
-
下载开发工具
- vue-devtools
- 浏览器扩展工具
- Vue.config.productionTip = false// 阻止vue在启动时生成生产提示
- vue-devtools
试验
<!--插值表达式-->
<div id="app">
{{message}}
</div>
<!--插值语法-->
<a :href="url" >点击</a>
new Vue({
el:'#app',
data:{
message:"hello vue",
url:"http://xxx/xxx"
}
})
el
- 挂载点
- 作用范围
- 元素内部所有范围
- 选择器
- id
- 建议使用
- class
- name
- id
- 可以使用双标签,不要使用html和body标签
- 作用范围
const v = new Vue({
// data 另一种写法
data(){
return {
name:'xxx'
}
}
})
// 另一种挂载方式
v.$mount('#app')
data
- 数据对象
- 基本类型
- 对象
- 数组
基础
MVVM
- MVVM
- M:model
- 对应vue data中的数据
- V:view
- 模板
- VM:viewModel
- vue实例
- M:model
Object.deineProperty
// 双向绑定示例
let number = 18
let person = {
name:'xx',
sex:'男'
}
Object.defineProperty(person,'age',{
// enumerable:true// 是否可枚举
// writable:true // 是否可修改
// configurable:true // 是否可删除
// 当读取person.name时调用aget方法
get(){
return number
},
// 当修改person.age时调用set
set(value){
number = value
}
})
// person.age与number双向绑定了
数据代理
// 通过obj2代理操作obj
let obj = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj.x
},
set(value){
obj.x = value
}
})
obj2.x = 200
console.log(obj.x)
let data = {
name:'xxx'
}
const vm = new Vue({
el:'#app',
data
})
// 传入的data存在与vm._data中
console.log(vm._data === data)
// 代理 修改name,会调用name的set方法,修改掉data.name的内容
// vm获取到data属性后,给自己添加data属性,并使用Object.defineProperty双向绑定
vm.name = 'aaaa'
console.log(vm._data.name)
console.log(data.name)
数据绑定
v-bind
- v-bind:属性名=表达式
- ‘:’: 简写
<div id='app'>
<img v-bind:src="imgSrc">
<img v-bind:title="imgTitle+'!!!'">
<img v-bind:class="isActive?'active':''">
<img v-bind:class="{active:isActive}">
</div>
<div id='app'>
<img :src="imgSrc">
<img :title="imgTitle+'!!!'">
<img :class="isActive?'active':''">
<img :class="{active:isActive}">
</div>
var app=new Vue({
el:"#app",
data:{
imgSrc:"xxx",
imgTitle:"xxxx",
isActive:false
}
})
v-model
- 表单元素双向绑定
<div id="app">
<input type="text" v-model="message"/>
</div>
var app = new Vue({
el:"#app",
data:{
message:"xxx"
}
})
事件
- v-on
- @:简写
<button @click="clickButton">点击(不传参)<button>
<button @click="clickButton2(22,$event)">点击(传参)<button>
new Vue({
el:'#app',
data:{
},
methods:{
clickButton(event){
cosnole.log(event)
},
// 传递参数
clickButton2(number,event){
cosnole.log(number)
cosnole.log(event)
},
}
})
示例
<div id="app">
<input type="button" value="xxx" v-on:click="doit">
<input type="button" value="xxx" @click="doit">
<input type="button" value="xxx" v-on:mouseenter="xx">
<input type="button" value="xxx" v-on:dbclick="xx">
<!--只有回车可以触发-->
<input type="button" value="xxx" @keyup.enter="doit">
<!--传参-->
<input type="button" value="xxx" @keyup.enter="doit(x,y)">
<input type="button" value="xxx" @keyup.enter="x">
</div>
var app=new Vue({
el:"#app",
methods:{
doit:function(){
alert("xxx")
},
x:function(event){
console.log(event.target.value)
}
}
})
- 数据修改
<div id="app">
{{ message }}
<input type="button" value="点击" @click="myclick">
</div>
var app = new Vue({
el:'#app',
data:{
message:"hello vue"
},
methods:{
myclick:function(){
console.log(this.message)
this.message += '!'
}
}
})
事件修饰符
- @click.prevent
- 阻止事件默认行为
- @click.stop
- 阻止事件冒泡
- @click.once
- 事件只能触发一次
- @click.capture
- 捕获模式
- @click.self
- 只有event.target是当前操作元素才触发
- @click.passive
- 事件的默认行为立即执行,无需等待事件回调执行完成
<!--阻止事件默认行为 调用clickA,不再跳转href-->
<a href='http://xxx' @click.prevent="showInfo">点击<a>
<!--阻止事件冒泡-->
<div class="demo1" @click="showInfo">
<button @click.stop="showInfo">点我</button>
</div>
<!--事件只触发一次-->
<button @click.once="showInfo">点我</button>
<!--默认先捕获在冒泡,在冒泡阶段才开始处理事件-->
<!--捕获阶段,由外往内,冒泡阶段,由内往外-->
<!--捕获模式下,捕获阶段就开始处理事件-->
<div @click.capture="showMsg(1)">
div1
<div @click="showMsg(2)">
div2
</div>
</div>
<!--只有event.target是当前操作元素才触发,-->
<div class="demo1" @click.self="showInfo">
<button @click="showInfo">点我</button>
</div>
<!--事件的默认行为立即执行,无需等待事件回调执行完成-->
<!--@scroll:滚动条滚动事件-->
<!--@wheel:鼠标滚动事件-->
<ul @wheel="demo">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
ul{
width:200px;
height:200px;
background-color:orange;
overflow:auto;
}
li{
height:100px;
}
new Vue({
el:'#app',
data:{
},
methods:{
showInfo(event){
cosnole.log(event)
},
showMsg(num){
console.log(num)
},
demo(){
// 如果方法内部操作需要花费大量事件,会导致滚轮滑动延迟
// passive可无需等待
console.log(scroll)
}
}
})
键盘事件
- 事件
- keyup
- keydown
- 别名
- enter
- keyCode = 13
- keyup.enter
- delete
- 删除或者退格
- esc
- space
- tab
- 必须配合keydown使用
- keydown.tab
- up
- down
- left
- right
- enter
- 系统修饰键
- ctrl
- alt
- shift
- meta
- 与keyup配合
- 需要与其他键配合,释放其他键后才触发
- 与keydown配合
- 正常触发
<input type='text' placeholder="请按回车键输入" @keyup="showInfo"/>
showInfo(e){
// 输出编码
console.log(e.keyCode)
// 输出别名
console.log(e.key)
}
计算属性
<div id='app'>
姓:<input type='text' v-model='firstName'><br/>
名:<input type='text' v-model='lastName'><br/>
姓名:<span>{{fullName}}</sapn>
</div>
new Vue({
el:'#app',
data:{
firstName:'xx',
lastName:'xx'
},
computed:{
/*
fullName:{
// 当有人读取fullName,就会调用fullName
// 初次读取fullName时会调用,并放入内存
// 所依赖的值发生改变时调用,修改内存中fullName的值
get(){
return this.firstName+'-'+this.lastName
},
// 一般情况不需要修改,不用set方法
set(value){
const arr = va;ue.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
*/
// 简写
fullName(){
return this.firstName+'-'+this.lastName
}
},
})
监视属性
- watch
const vm = new Vue({
el:'#app',
data:{
isHot:true,
},
watch:{
/*
isHot:{
immediate:true,// 初始化isHot时也会调用handler
// 当isHot发生改变时调用
handler(newValue,oldValue){
console.log("isHot被修改了",newValue,oldValue)
}
}
*/
// 简写
isHot(newValue,oldValue){
console.log("isHot被修改了",newValue,oldValue)
}
}
})
// 另一种写法
vm.$watch('isHot',{
})
深度监视
new Vue({
el:'#app',
data:{
numbers:{
a:1,
b:1
}
},
watch:{
// 多级结构监视
'numbers.a':{
handler(newValue,oldValue){
console.log("a被修改了",newValue,oldValue)
}
},
numbers:{
deep:true,// 监视多级结构改变
handler(){
}
}
}
})
class&style
class
<div :class='arr'></div>
new Vue({
el:'#app',
data:{
// 可动态修改class
arr:['a','b']
}
})
style
<div :style='styleObj'></div>
new Vue({
el:'#app',
data:{
// 可动态修改style
styleObj:{
fontSize:'40px',
color:'red'
}
}
})
条件渲染
v-show
<div id='app'>
<img src="地址" v-show="true">
<!--是否显示-->
<img src="地址" v-show="isShow">
<img src="xx" v-show="age>=18">
</div>
var app = new Vue({
el:"#app",
data:{
isShow=false,
age:18
}
})
v-if
- v-if
- v-else-if
- v-else
- v-else不需要条件
<div id='app'>
<!--是否显示-->
<!--操作dom-->
<p v-if="true">p标签</p>
<p v-if="isShow">p标签</p>
</div>
var app = new Vue({
el:"#app",
data:{
isShow=false,
age:18
}
})
列表渲染
v-for
<div id='app'>
<ul>
<!--遍历数组-->
<li v-for="(item,index) in objArr" :key="item.id">
{{ item.name }}
</li>
</ul>
<ul>
<!--遍历对象-->
<li v-for="(value,key) in person" :key='key'>
{{ key }}{{ value }}
</li>
</ul>
<ul>
<!--遍历字符串-->
<li v-for="(char,index) in str" :key='index'>
{{ char }}{{ index }}
</li>
</ul>
<ul>
<!--遍历指定次数-->
<li v-for="(number,index) of 5" :key='index'>
{{ number }}{{ index }}
</li>
</ul>
</div>
new Vue({
el:"#app",
data:{
objArr:[
{id:1,name:'xx1'},
{id:2,name:'xx2'}
],
person:{
name:'xx',
age:10
},
str:'xsasdasda'
}
})
数据监测原理
let data = {
name:'xxx'
}
// 创建一个监视实例对象,监视data中属性变化
const obs = new Observer(data)
function Observer(obj){
const keys = Object.keys(obj)
keys.forEach((k)=>{
Object.defineProperty(this,k,{
get(){
return obj[k]
},
set(val){
obj[k] = val
}
})
})
}
### 数组检测
- 监测方法
- push
- pop
- shift
- unshift
- splice
- sort
- reverse
// 指标一个vm对象
let vm = {}
// data = obs 数据劫持
vm._data = data = obs
Vue.set
const vm = new Vue({
el:'#app',
data:{
name:xx,
student:{
name:'xx'
}
}
})
// student追加属性
// vm.$set()
Vue.set(vm.student,'sex','男')
表单数据
- v-model.lazy
- v-model.trim
- v-model.number
<div>
<form @submit.prevent='demo'>
年龄 <input type='number' v-model.number='userInfo.age'><br/>
性别:
男<input type='radio' name='sex' v-model='userInfo.sex' value='male'>
女<input type='radio' name='sex' v-model='userInfo.sex' value='female'><br/>
爱好:
学习<input type='checkbox' v-model='userInfo.hobby' value='study'>
打游戏<input type='checkbox' v-model='userInfo.hobby' value='game'>
吃饭<input type='checkbox' v-model='userInfo.hobby' value='eat'><br/>
所属校区:
<select v-model='userInfo.city'>
<option value='bj'>北京</option>
<option value='nj'>南京</option>
<option value='sh'>上海</option>
</select><br/>
<button>提交</button>
</form>
</div>
new Vue({
el:'#app',
data:{
userInf:{
age:10,
sex:'male',
hobby:[],
city:'bj'
}
},
methods:{
demo(){
console.log(this.userInfo)
}
}
})
过滤器
// timeFormater 获取tiem并返回
<div>{{time | timeFormater}}</div>
<div>{{time | timeFormater('YYYY-MM-DD') | mySlice }}</div>
new Vue({
el:'#app',
data:{
time:// 时间戳
}
// 局部过滤器
filters:{
timeFormater(value,str="YYYY-MM-DD HH:mm:ss"){
// 需要导包dayjs
return dayjs(value).format(str)
},
mySliec(value){
return value.slice(0,4)
}
}
})
// 全局过滤器
// Vue.filter('xx',function(value){})
内置指令
v-text
<div id="app">
<h2 v-text="message"></h2>
</div>
//v-text会替换h2内所有值,部分替换采用插值法
var app=new Vue({
el:"#app",
data:{
message:"xxx"
}
})
v-html
<div id="app">
<h2 v-html="content"></h2>
<h2 v-text="content"></h2>
</div>
//v-text只显示文本
//v-html如果有标签就会解析标签
var app=new Vue({
el:"#app",
data:{
//content:"xxx"
content:"<a href='xxx'>xxx</a>"
}
})
v-cloak
- 与css配合,防止页面加载资源延迟出现不该出现的内容
[v-cloak]{
display:none;
}
// 在vue加载前会隐藏,加载后v-cloak会自动删除
<div v-cloak>xxx</div>
v-once
<!--v-once初次动态渲染后不再改变-->
<div v-once>{{n}}</div>
<div >{{n}}</div>
v-pre
- v-pre
- vue不解析节点的插值
<div v-pre>{{n}}</div>
<div >{{n}}</div>
自定义指令
<div v-big="n"><div>
<input v-fbind:value="n"/>
new Vue({
el:'#app',
data:{
n:1
},
directives:{
// 此处this指向window
// 自定义v-big
big(element,binding){
// 放大10被
element.innerText = binding.value*10
},
fbind:{
// 赋值并获取焦点
// 对象式
bind(element,binding){
// 指令与元素成功绑定时
console.log('bind')
element.value = binding.value
},
inserted(element,binding){
// 指令所在元素插入页面时
console.log('inserted')
element.focus()
},
update(element,binding){
// 指令所在元素重新解析时
console.log('update')
element.value = binding.value
}
}
}
})
// 全局
// Vue.directive()