1.基本使用步骤
a.导入vue.js的script脚本文件(自动为window对象挂载vue构造函数)
b.在页面中声明一个将要被vue控制的Dom区域
c.创建vue实例对象
<body>
<div id="app">
{{msg}}
</div>
</body>
</html>
<script src="./vue3.js"></script>
<script>
let app = Vue.createApp({
data(){
return{
msg:'123'
}
}
})
app.mount('#app')
</script>
data指向的对象是Model数据源
div是View视图区域
vue实例对象就是ViewModel
2.MVVM项目的架构模式
M:model,模型:
主要完成业务功能,在数据库相关的项目中,数据库的增删改查属于模型(重点)。(nodeJS中的db文件夹),没有页面,是纯粹的逻辑
V:view,视图:
主要负责数据的显示(HTML+CSS,动态网页(jsp,含有html的php文件))页面的展示和用户的交互。
VM:ViewModel
主要完成M和V的数据通信,并且是双向绑定。而 View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作 DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
3.vue调试工具
a.chrome浏览器右上角三个点图标,点击设置,
b.点击扩展程序,在应用商店搜索扩展程序vue.js devtools,添加至chroma,
c.详情:允许此扩展程序读取和更改您在所访问的网站上留存的所有数据,在所有网站上,打开允许访问文件网址
d.重启浏览器
e.点击调试面板最右侧vue
4.vue指令
指令是vue为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构
a.内容渲染指令v-text, v-html, {{}}
b.属性绑定指令v-bind
c.事件绑定指令v-on
d.双向绑定指令v-model
e.条件渲染指令v-if,v-else-if,v-else,v-show
f.列表渲染指令v-for
<body>
<div id="app">
<!--1. v-text和插值表达式只能渲染纯文本内容。v-html会把包含html标签的字符串渲染为页面的html元素 -->
<p>{{msg}}</p>
<p v-text="msg"></p>
<p v-html="msg"></p>
<p>{{str}}</p>
<p v-text="str"></p>
<p v-html="str"></p>
<!-- 2.为元素的属性绑定属性值,v-bind可省略 -->
<input type="text" v-bind:placeholder="placeholder">
<img v-bind:src="src" alt="">
<!-- 3.事件绑定v-on:click,v-on:input,v-on:keyup,简写@click ,当事件处理函数中的代码简单,可简写到行内-->
<button v-on:click="fn1">按钮1</button>
<button v-on:click="msg+='123'">按钮1</button>
<button v-on:click="fn2('123',$event)">按钮2</button>
<!-- 事件修饰符.prevent阻止默认行为,.stop阻止事件冒泡,.capture以捕获方式处理当前事件,.once只触发一次,.self当前元素自身触发 -->
<a href="http://www.baidu.com" @click.prevent="onLinkClick">百度</a>
<div class="outer" @click="outerClick">
<div class="inner" @click.stop="innerClick"></div>
</div>
<!-- 事件默认以冒泡形式执行,加capture以捕获形式执行,从外到里 -->
<div class="outer" @click.capture="outerClick">
<div class="inner" @click="innerClick"></div>
</div>
<div class="inner" @click.once="innerClick"></div>
<!-- 里中外冒泡执行,不执行以冒泡形式触发的事件加上self -->
<div class="box" @click="boxClick" >
<div class="outer" @click.self="outerClick">
<div class="inner" @click="innerClick"></div>
</div>
</div>
<!-- 按键修饰符 -->
<input type="text" @keyup.enter="submit" @keyup.esc="clear">
</div>
</body>
</html>
<script src="./vue3.js"></script>
<script>
let app = Vue.createApp({
data(){
return{
msg:'123',
str:'<b>b</b>',
placeholder:'hello',
src:"./001.png"
}
},
methods:{
fn1(e){
console.log('按钮1');
// 接受事件对象event
const nowBgColor=e.target.style.backgroundColor;
e.target.style.backgroundColor=nowBgColor==='red'?'':'red'
},
fn2(str,e){
this.msg+=str;
const nowBgColor=e.target.style.backgroundColor;
e.target.style.backgroundColor=nowBgColor==='red'?'':'red'
},
onLinkClick(){
alert('ok')
},
outerClick(){
alert('outerClick')
},
innerClick(){
alert('innerClick')
},
boxClick(){
alert('boxClick')
},
submit(e){
alert(`按键${e.target.value}`)
},
clear(e){
e.target.value=''
}
}
})
app.mount('#app')
</script>
<body>
<div id="app">
<!-- 4.双向绑定 -->
<!-- 输入框 -->
<p><input type="text" v-model="value">{{value}}</p>
<!-- 下拉选择框 -->
<select v-model="num" name="" id="">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
{{num}}
<!-- 单选框 -->
<input type="radio" v-model="istrue" value="yes" id="yes"><label for="yes">yes</label>
<input type="radio" v-model="istrue" value="no" id="no"><label for="no">no</label>
<!-- 单个复选框 -->
<p><input type="checkbox" v-model="isCheckd">xxxx</p>
<!-- 复选框 -->
<input type="checkbox" v-model="arr" value="aaaa">aaaa
<input type="checkbox" v-model="arr" value="bbbb">bbbb
<input type="checkbox" v-model="arr" value="cccc">cccc
{{arr}}
<!-- v-model指令修饰符.number,.trim,.lazy -->
<p><input type="text" v-model.number="value">{{value}}</p>
<p><input type="text" v-model.trim="value">{{value}}</p>
<p><input type="text" v-model.lazy="value">{{value}}</p>
<!-- 使用了lazy后,在失去焦点时更新value,而不是在输入时更新 -->
<!--5.条件渲染 -->
<button v-if="flag" @click="clickFn">按钮1</button>
<button v-show="flag"@click="clickFn">按钮2</button>
<p v-if="type==='A'">优秀</p>
<p v-else-if="type==='B'">良好</p>
<p v-else-if="type==='C'">一般</p>
<p v-else>差</p>
<!-- 6.列表渲染v-for -->
<div v-for="(item,index) in arr1" :key="item">{{index}}{{item}}</div>
<div v-for="(value,key) in obj">{{key}}{{value}}</div>
<div v-for="(item,index) in str">{{index}}{{item}}</div>
<!-- 嵌套循环 -->
<div v-for="(item,index) in objArr">
<p v-for="(v,k) in item">{{k}}{{v}}</p>
</div>
<div v-for="(item,index) in objArr" :key="item">
<input type="checkbox">
{{index}}{{item.a}}
</div>
<button @click="addFn">key</button>
</div>
</body>
<script src="./vue3.js"></script>
<script>
let app = Vue.createApp({
data(){
return{
value:'',
num:'',
istrue:'no',
isCheckd:true,
arr:[],
flag:true,
type:'D',
arr1:['1a','2b','3c','4d'],
objArr:[{
a:"1aaaaaaaa",
b:"1bbbbbbbbbbbbb",
c:"1cccccccccccc",
d:"1dddddddddd"
},{
a:"2aaaaaaaa",
b:"2bbbbbbbbbbbbb",
c:"2cccccccccccc",
d:"2dddddddddd"
}],
obj:{
a:"1aaaaaaaa",
b:"1bbbbbbbbbbbbb",
c:"1cccccccccccc",
d:"1dddddddddd"
}
}
},
methods:{
clickFn(){
this.flag=!this.flag
},
addFn(){
this.objArr.unshift({
a:`${Math.random()*10}aaaaaaaa`,
b:`${Math.random()*10}bbbbbbbbbbbbb`,
c:`${Math.random()*10}cccccccccccc`,
d:`${Math.random()*10}dddddddddd`
})
}
}
})
app.mount('#app')
</script>
v-if和v-show的区别
实现原理不同
v-if指令会动态的创建或移出dom元素,
v-show会动态添加或移出style="display:none;"样式
性能消耗
v-if有更高的切换开销,v-show有更高的初始渲染开销。
频繁切换使用v-show。如果运行时条件很少改变,使用v-if
v-for中的key
当列表的数据发生表示变化时,vue会尽可能地复用已存在的dom元素,从而提升渲染的性能。但这种默认的性能优化策略,会导致有状态的列表无法被正确更新。需要为每项提供一个唯一的key属性。
key的值只能是字符串或数字类型,必须具有唯一性,建议把数据项id属性作为key,使用index的值作为key值没有任何意义。
5.简单案例
<body>
<div id="app">
<div class="top">
<h4>添加品牌</h4>
<p>
<input class="goodVal" type="text" v-model.trim="goodVal">
<button @click="addFn">添加品牌</button>
</p>
</div>
<div class="bottom">
<table>
<tr>
<td class="goodId">#</td>
<td class="goodName">名称</td>
<td class="goodState">状态</td>
<td class="goodTime">时间</td>
<td class="goodAction">操作</td>
</tr>
<tr v-for="(item,index) in goods" :key="item.id">
<td class="goodId">{{index+1}}</td>
<td class="goodName">{{item.name}}</td>
<td class="goodState">
<input type="checkbox" v-model="item.state" :id="item.id">
<label :for="item.id">{{item.state===true?"上架":"下架"}}</label>
</td>
<td class="goodTime">{{item.time}}</td>
<td class="goodAction"><u @click="clearFn(item.id)">删除</u></td>
</tr>
</table>
</div>
</div>
</body>
</html>
<script src="./vue3.js"></script>
<script>
let app = Vue.createApp({
data(){
return{
msg:'hello',
goodVal:"",
goods:[{
id:'1',
name:'苹果',
state:true,
time:'2020-11-03 11:00:00'
},
{
id:'2',
name:'梨',
state:true,
time:'2020-11-03 11:00:00'
},
{
id:'3',
name:'香蕉',
state:true,
time:'2020-11-03 11:00:00'
}]
}
},
methods:{
clearFn(id){
this.goods = this.goods.filter((item)=>{
return item.id !== id;
})
},
addFn(){
if(this.goodVal==''){
alert('请输入添加内容');
return;
}
let obj={
id: Math.random()*10,
name:this.goodVal,
state:true,
time: this.formatTime()
}
this.goods.push(obj);
this.goodVal='';
},
formatTime(){
let dt=new Date()
let y=dt.getFullYear();
let m=this.padZero(dt.getMonth()+1);
let d=this.padZero(dt.getDate());
let hh=this.padZero(dt.getHours());
let mm=this.padZero(dt.getMinutes());
let ss=this.padZero(dt.getSeconds());
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
},
padZero(n){
console.log(n);
return n>9 ? n:'0'+ n
}
}
})
app.mount('#app')
</script>