Vue3.x学习笔记
初识
计数器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<!--引入vue库-->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
//创建Vue实例
Vue.createApp({
//data()是一个方法
data() {
return {
//返回一个对象
counter: 1
}
},
//生命周期的构造函数
mounted() {
setInterval(() => {
//常用,简写
this.counter += 1
//正式写法
// this.$data.counter+=2
}, 1000)
},
template: '<div>{{counter}}</div>'
}).mount("#app")
</script>
</html>
声明/绑定方法 状态切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
//声明对象
//第一步
Vue.createApp({
//第二步
data() {
//第三步
return {
content: "",
setMeal: "1 2 3 ",
isShowMeal: false
}
},
//声明方法
methods: {
welcomeBtnClick() {
this.content = "贵宾一位"
},
byebyeBtnClick() {
this.content = "下次再来"
},
showOrHideBtnClick() {
//显示状态切换
this.isShowMeal = !this.isShowMeal
}
},
//声明实例
template: `
<div>
<div>{{ content }}</div>
//v-on:click绑定函数
<button v-on:click="welcomeBtnClick">有顾客来</button>
 
<button v-on:click="byebyeBtnClick">顾客离开</button>
<div>
//v-if根据状态调整是否显示
<div v-if="isShowMeal">{{ setMeal }}</div>
<button v-on:click="showOrHideBtnClick">显示/隐藏套餐</button>
</div>
</div>`
}).mount("#app")//挂载到<div id="app"></div>下
</script>
</html>
循环和双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>List</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
data(){
return{
list:["宋佳","刘亦菲","戚薇"],
//声明的输入变量
inputValue:""
}
},
methods:{
addItem(){
this.list.push(this.inputValue)
this.inputValue=""
}
},
template:`
<div>
<!-- //数据双向绑定-->
<input v-model="inputValue"/>
<button v-on:click="addItem">增加</button>
<ul>
<li v-for="(item,index) of list">[{{index}}]{{ item }}</li>
</ul>
</div>`
}).mount("#app")
</script>
</html>
组件/父子参数绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>List</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
list: ["宋佳", "刘亦菲", "戚薇"],
//声明的输入变量
inputValue: ""
}
},
methods: {
addItem() {
this.list.push(this.inputValue)
this.inputValue = ""
}
},
template: `
<div>
<my-title/>
<!-- //数据双向绑定-->
<input v-model="inputValue"/>
<button v-on:click="addItem">增加</button>
<ul>
<!-- <li v-for="(item,index) of list">[{{index}}]{{ item }}</li>-->
<!--// 绑定父子参数
v-bind:item="item"
v-bind:index="index"-->
<my-girl
v-for="(item,index) of list"
v-bind:item="item"
v-bind:index="index"
/>
</ul>
</div>`
})
app.component('my-title', {
template: `
<h1 style="text-align: center">上海</h1>
`
})
app.component('my-girl', {
//接收来自父组件的参数,数组类型
props: ['index', 'item'],
template: `
<li>[{{ index }}]{{ item }}</li>
`
})
app.mount("#app")
</script>
</html>
基础
createApp()和mount()
<script>
//createApp({}),({})的{}表示了一个对象形式的参数
const app = Vue.createApp({
data() {
return {
message: 'jspang.com' //1.在这里定义了数据,也就是`model`数据
}
},
template: "<h2>{{message}}</h2>" //2.在这里定义了模板,也就是`view`,
//定义后的自动关联,就叫做`vm`,viewModel数据视图连接层。
})
const vm=app.mount("#app")
//mvvm m model v view vm viewModel
</script>
- 当我们获取了vm根节点后,其实就可以操作里边的数据了。比如在控制台中输入下面的代码:
<!-- $是选择器 -->
vm.$data.message ='技术胖'
生命周期函数
beforeCreate( ) :在实例生成之前会自动执行的函数
created( ) : 在实例生成之后会自动执行的函数
beforeMount( ) : 在模板渲染完成之前执行的函数
mounted( ) : 在模板渲染完成之后执行的函数
beforeUpdate( ) :当data中的数据变化时, 会立即自动执行的函数
updated( ):当data中的数据发生变化,页面重新渲染完后,会自动执行的函数
//控制台中输入app.unmount()查看
beforeUnmount( ) :当Vue应用失效时,会自动执行的函数
unmounted() : 当Vue应用失效时,且DOM完全销毁之后,会自动执行
v-once/v-html/v-on
data() {
return {
message: '<i>jspang.com</i>'
}
},
//v-html:输出html内容
//v-once:只渲染一次
//v-on:绑定方法
template: "<h2 " +
"v-on:click='handleIteClick' " +
"v-html='message'" +
"v-once>{{message}}</h2>",
v-bind
//该位置有小窗
template: `
<h2 v-bind:title="message">{{message}}</h2>`,
简写
v-bind:title="message"
:title="message"
v-on:click=
@click=
动态参数
data() {
return {
message: 'jspang.com',
name:'title',
event:'click'
}
},
template: `
<h2 :[name]="message"
@[event]="handleItemClick">{{ message }}</h2>`,
阻止默认事件
//方法一
<button type="submit" @click.prevent="">跳转</button>
//方法二
<button type="submit" @click.prevent="handleBtn">跳转</button>
methods: {
handleBtn(e) {
e.preventDefault(e)
}
}
条件判断
<style>
.one {
color: red;
}
.two {
color: green;
}
.three {
color: yellow;
}
</style>
template: `
<h2 :class="message=='jspang.com'?'one':'two'"
@click="handleItemClick">
{{message}}
</h2>`,
methods: {
handleItemClick() {
this.message = this.message == "jspang.com" ? `技术胖` : "jspang.com"
},
const app = Vue.createApp({
data() {
return {
message: 'hello'
}
}, template: `
<h2 @click="handleItemClick" v-if="message=='jspang.com'" class="one">{{ message }} </h2>
<h2 @click="handleItemClick" v-if="message=='技术胖'" class="two">{{ message }} </h2>
<h2 @click="handleItemClick" v-if="message=='hello'" class="three">{{ message }} </h2>
`,
methods: {
handleItemClick() {
this.message = this.message == "jspang.com" ? `技术胖` : "jspang.com"
},
}
})
const app = Vue.createApp({
data() {
return {
message: 'jspang.co'
}
}, template: `
<h2 @click="handleItemClick" v-if="message=='jspang.com'" class="one">{{ message }} </h2>
<h2 @click="handleItemClick" v-else class="three">{{ message }} </h2>
`,
methods: {
handleItemClick() {
this.message = this.message == "jspang.com" ? `技术胖` : "jspang.com"
},
}
})
计算属性
data(){
return{
message:'jspang.com' ,
price:10,
count:2
}
},
computed:{
total(){
return this.price*this.count;
}
},
方法methods:只要页面重新渲染,就会重新执行方法
计算属性computed: 当计算属性依赖的内容发生变更时,才会重新执行计算
监听器
watch:{
//默认第一个参数为当前值,第二个参数为变化前的值,名称同变量名相同
count(current,prev){
console.log(current)
console.log(prev)
}
},
method、watch和computed三者使用优先级
computed 和 method都能实现的功能,建议使用computed,因为有缓存,不用渲染页面就刷新。
computed 和 watch 都能实现的功能,建议使用 computed,因为更加简洁。
样式绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>List</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<!-- -->
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
/*使用 <sonCom :class="classArr"/>*/
classString: 'green',
classObject: {red: false, background: true},
classArr: ['green', 'background', {red: true}],
/*使用<h2 :style="styleObject">jspang.com</h2>*/
styleObject: {
color: "pink",
background: "yellow"
}
}
},
template: `<h2 :style="styleObject">jspang.com</h2>
<sonCom :class="classArr"/>
`,
})
app.component('sonCom', {
//如有多个<div/>则在外层套上一个<div>
template: `
<div>
<div>sonCom1</div>
<div>sonCom2</div>
<div>sonCom3</div>
</div>
`
})
app.mount("#app")
</script>
<style>
.red {
color: red !important;
}
.green {
color: green;
}
.background {
background-color: orange;
}
</style>
</html>
v-show和v-if的差别
const app = Vue.createApp({
data() {
return {
show:false
}
},
//v-show=不会重新渲染dom元素,仅控制样式
//v-if=会重新渲染dom元素,可以处理复杂逻辑
template: `
<h2 v-show="show">jspang.com</h2>
<h2 v-if="show">jspang.com</h2>
`,
})
v-for使用
data(){
return{
listArray:['刘亦菲','宋佳','汤唯'],
listObject:{
Girl1:"julia",
Girl2:"新垣绫濑",
Girl3:"古力娜扎",
}
}
},
遍历数组
<li v-for="(item,index) in listArray"
:key="index+item">
[{{ index + 1 }}]{{ item }}
</li>
遍历对象
<li v-for="(value,key,index) in listObject"
:key="key">
[{{index}}]{{key}}:{{value}}
</li>
筛选对象
- <template>标签用来处理业务逻辑
<ul>
<template v-for="(item,index) in listArray"
:key="index+item">
<li
v-if="item!='汤唯'"
>[{{ index + 1 }}]{{ item }}
</li>
</template>
</ul>
- 浏览器展示
<ul>
<!--v-if-->
<li>...</li>
<li>...</li>
</ul>
方法和参数
//同时触发两个事件
<button @click="handleBtnClick1(),handleBtnClick2()">增加一位佳丽</button>
-
如果想在模板中一次触发两个事件方法,需要 用,逗号,把事件隔开,然后每个事件后边必须加上( )才能起作用。
-
有参数的情况下使用event
methods:{
addCountClick(num,event){
this.count+=num;
console.log(event.target)
},
},
template:`
<div>目前已点佳丽数量{{count}}.</div>
<button @click="addCountClick(2,$event)">增加一位佳丽</button> `
})
事件修饰符
stop修饰符
- 停止冒泡
<button @click.stop=" addCountClick()">增加一位佳丽</button> //修改了此处
self修饰符
- 只有点击自己的时候才会被执行
- 加的位置要在外层DOM元素的事件上
template:`
<div @click.self="handleBtnClick1"> //修改了此处
我是最外层的DIV文字
<div>目前已点佳丽数量{{count}}.</div>
<button @click=" addCountClick()">增加一位佳丽</button>
</div> `
prevent修饰符
- 阻止form表单的默认提交行为
<form
action="https://jspang.com"
@click.prevent="hanldeButton"> //修改了此处
<button type="submit">默认提交</button>
</form>
capture修饰符
- 捕获模式,默认的模式都是冒泡模式
template:`
<div @click.capture="handleBtnClick1"> //修改了此处
我是最外层的DIV文字
<div>目前已点佳丽数量{{count}}.</div>
<button @click=" addCountClick()">增加一位佳丽</button>
</div>
`
once修饰符
- 事件只执行一次
template:`
<div @click.self="handleBtnClick1">
我是最外层的DIV文字
<div>目前已点佳丽数量{{count}}.</div>
<button @click.once=" addCountClick()">增加一位佳丽</button>
</div>
`
passive修饰符
- 解决滚动时性能的修饰符
按键的修饰符
enter 、tab、delete、esc、up 、down、left、right
template:`
<div">
<input @keydown.enter="handleKeyDown"/>
</div>
`
})
鼠标修饰符
left、right、middle
<div @click.right="handleClick">JSPang.com</div>
表单数据的双绑定
input的数据双向绑定
<script>
const app=Vue.createApp({
data(){
return{
name:''
}
},
template:`
<div>
<div>{{name}}</div>
<input v-model="name" />
</div>
`
})
const vm=app.mount("#app")
</script>
textarea的数据双向绑定
template:`
<div>
<div>{{name}}</div>
<div><input v-model="name" /></div>
<div><textarea v-model="name" /></div>
</div>
`
checkbox数据双向绑定
data(){
return{
name:'',
checked:false
}
},
<div>{{checked}}<input type="checkbox" v-model="checked" /></div>
Radio的双向数据绑定
data(){
return{
name:'',
checked:false,
girls:[],
girl:'',
}
},
<div>
{{girl}}
大脚<input type="radio" v-model="girl" value="大脚" />
刘英<input type="radio" v-model="girl" value="刘英" />
晓红<input type="radio" v-model="girl" value="晓红" />
</div>
true-value和false-value
data(){
return{
checked:true,
name:'未选中',
message:''
}
},
<div>
{{name}}
<input
type="checkbox"
v-model="name"
true-value="刘亦菲"
false-value="宋 佳"
>
</div>
lazy修饰符
- 可以实现当输入完成后,失去焦点再进行改变。
<div>
{{message}}<input v-model.lazy="message" />
</div>
number修饰符
- 输入的内容无论是数字还是字母,最终都会变为字符串
- 加上number修饰符后,你输入的值只要是数字,就变成了number类型
<div>
{{typeof message}}<input v-model.number="message" />
</div>
trim修饰
- 用来消除input框输入内容前后的空格的
<div>
{{message1}}<input v-model.trim="message" />
</div>