vue2笔记1基本用法整理
准备开发环境
下载vue开发版本
引入
<script src="/js/vue.js"></script>
F12可见提示,引入成功
关闭开发模式提示
Vue.config.productionTip = false;
创建容器和Vue实例
<div id="root"></div>
<script>
new Vue({
el: '#root'
});
</script>
或
<div id="root"></div>
<script>
new Vue({}).$mount('#root');
</script>
插值语法
用于解析标签体内容
{{JS表达式}}
<div id="root">
<h1>{{message}}</h1>
</div>
<script>
new Vue({
el: '#root',
data() {
return {
message: 'Hello world'
}
}
});
</script>
指令语法
用于解析标签(属性,标签体内容,绑定事件…)
v-bind:attribute=“JS表达式”
<div id="root">
<a v-bind:href="url">baidu</a>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
new Vue({
el: '#root',
data() {
return {
url: 'https://www.baidu.com'
}
}
});
</script>
MVVM
- M model data数据
- V view 模板
- VM viewModel Vue实例对象(m中的属性会在vm中代理,v可以使用vm中的所有属性,通过Object.defineProperty实现数据代理)
数据绑定
双向绑定v-model只能用于表单类元素(有value属性的元素)上
单向:<input type="text" v-bind:value="message" />
双向:<input type="text" v-model:value="message" />
简写
单向:<input type="text" :value="message" />
双向:<input type="text" v-model="message" />
事件处理
<button v-on:click="onBtnClick($event,message)">click</button>
简写
<button @click="onBtnClick($event,message)">click</button>
new Vue({
data() {
message: 'hello world'
},
methods: {
onBtnClick(event, message) {
alert(message + ' clicked');
}
}
})
事件修饰符
<a @click.prevent.stop="onClick">click</a>
- prevent 阻止默认事件默认行为(例如标签阻止跳转)
- stop 阻止事件冒泡
- once 事件只触发一次
- capture 使用捕获模式(默认在冒泡阶段执行回调(由内向外),此修饰符可在捕获阶段执行回调(由外向内))
- self 只有event.target是当前元素才触发
- passive 立即执行事件默认行为,无需等待事件回调结束(例如滚动条滚动事件,防止因回调导致滚动条卡顿)
- 键盘事件按键绑定
<input @keydown.Enter="onKey"></input>
<input @keydown.caps-lock="onKey"></input>
<input @keydown.tab="onKey"></input>
<input @keydown.ctrl.x="onKey"></input>
- tab必须配合keydown,否则焦点离开无法触发
- 系统修饰键 ctrl,alt,shift,meta(win键)
配合keyup时,按下修时间同时,再按下其他键,随后释放其他键触发
配合keydown时,正常触发
计算属性
<input v-model:value="fn"/>
<input v-model:value="ln"/>
<input v-model:value="fullname"/>
new Vue({
data() {
firstname: 'san',
lastname: 'zhang'
},
computed: {
fullname: {
// 1. 初次读取时调用,模板中多次使用,只调用一次(如果使用method定义计算,则会多次调用)
// 2. 所依赖的数据发生变化时调用
get(){
return this.firstname + '-' +this.lastname
},
// 可选,fullname变化时调用
set(value){
const arr = value.split('-');
this.firstname=arr[0];
this.lastname=arr[1];
}
}
}
})
- 简写
只可读取不可修改
使用计算属性时用fullname而不是fullname()
computed:{
fullname: function{
return this.firstname + '-' +this.lastname
}
}
侦听属性
通过配置
watch: {
fullname: {
immediate: true, // 初始化时调用handler
handler(newv, oldv) {
console.log('change', newv, oldv);
}
}
}
通过api
let vm = new Vue({...});
vm.$watch('fullname',{
immediate: true,
handler(newv, oldv) {
console.log('change', newv, oldv);
}
});
简写
不需要其他配置时(immediate,deep)可使用简写
watch:{
fullname(newValue,oldValue){}
}
深度侦听
data() {
return {
name:{
fn: 'fn',
ln: 'ln'
}
}
},
watch: {
// 监视结构中属性
'name.fn':{},
// 监视结构中所有属性变化
name:{
deep:true,
handler(){};
}
}
watch vs computed
当需要异步处理计算逻辑时得使用watch
watch:{
name:{
deep:true,
handler(){
setTimeout(()=>{
// 注意此处使用箭头函数,this=vue实例
// 如果使用function ,this=window
this.fullname = name.fn + name.ln;
},1000)
}
}
}
绑定样式
绑定字符串:名字不确定
绑定数组:样式个数和名字都不确定
绑定对象:个数和名字确定,但不确定用不用
<div class='basic' :class='vClass'></div>
<div class='basic' :class='vClasses'></div>
<div class='basic' :class='vClassObj'></div>
data:{
vClass: 'class1',
vClasses:['class1','class2','class3'],
vClassObj:{
class1: true,
class2: false
}
}
style
表达式绑定值
绑定对象
绑定数组
<div :style="{fontSize: styleObj.fontSize}">123</div>
<div :style="styleObj">123</div>
<div :style="styleObjs">123</div>
data() {
return {
styleObj: {
fontSize: '40px'
},
styleObjs:[{},{}]
}
}
条件渲染
v-show dom结构在,样式为不显示
v-if dom结构不创建,使用if,else指令的元素必须相邻
v-if可以配合template使用,包裹同时控制多个结构
<div v-show="!hidden"></div>
<div v-if="n==1"></div>
<div v-else-if="n==2"></div>
<div v-else></div>
列表渲染
可遍历:数组,对象属性,字符串,指定次数
注:尽量使用key,可以提高性能(更新根据KEY复用/替换已经创建的dom,否则将自动根据index作为Key)
<ul>
<li v-for="person in psersons" :key="id">{{person.name}}</li>
</ul>
<ul>
<li v-for="(person,index) in psersons" :key="id">{{index}}-{{person.name}}</li>
</ul>
<ul>
<li v-for="(attr,key) of car" :key="key">{{key}}:{{attr}}</li>
</ul>
<ul>
<li v-for=(number,index) of 5></li>
</ul>
data(){
persons:[{id:1,name:'a'},{id:2,name:'b'}],
car:{
name: 'name',
prices: 100,
model: 'model'
}
}
过滤排序
data(){
minAge: 10,
sort:0,
persons:[{id:1,name:'a',age:10},{id:2,name:'b',age:22}]
},
computed:{
filteredPersons(){
let arr = this.person.filter((p)=>{return p.age>this.minAge})
if(this.sort){
arr.sort((p1,p2)=>{return this.sort === 1 ? p1.age-p2.age : p2.age-p1.age})
}
}
},
watch:{
minAge:{
immediate: true, // 注意不写此配置,初始渲染会有问题
handler:function(value){
this.filteredPersons2 = this.person.filter((p)=>{return p.age>this.minAge});
}
}
}
数据更新的问题
- 直接在对象中增加属性,没有响应式特性,需使用以下API(不能直接给data添加属性)
let vm = new Vue({
data() {
myObj:{}
}
});
Vue.set(vm._data.myObj,'newProp1','value')
// 或
vm.$set(vm.myObj,'newProp2','value')
- 直接替换数组中某个元素(根据索引值修改),会导致列表无法更新,需使用已下数组方法
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
替换数组元素
vm.$set(vm.myArr,index,'value')