vue3基础入门
中文文档: https://staging-cn.vuejs.org/guide/introduction.html
1、简介
1.1、vue是什么?
Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。
Vue 只关注视图层, 采用自底向上增量开发的设计。
Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
说白了,VUE就是一套 JS框架,与AngularJS、ReactJS、Vue.js、jQuery具有一样目的的框架。
1.2、VUE能干什么?
前端框架,能快速开发前端项目。
VUE是MVVM架构。
1.3、vue2和vue3区别
文章:https://www.jianshu.com/p/d3f973433274
- vue2和vue3双向数据绑定原理发生了改变。
- 定义数据变量和方法的改变。
- 生命周期钩子函数的不同。
- vue3中新加入了TypeScript和PWA的支持。
ue3.0比起vue2.0有以下优势:
- 打包大小减少41%
- 初次渲染块55%,更新渲染块133%
- 内存占比少54%
2、初识Vue指令
通过引用 JS文件来学习VUE的常用指令,由于CDN不稳定,建议下载到本地。
类似引用Jquery。
Staticfile CDN(国内): https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js
- 指令是带有 v- 前缀的特殊属性。
- 直接作用在DOM元素上。
- 例如:
- v-html
- v-bind
- v-on
- ...
2.1、Hello Vue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="hello-vue" class="demo">
<p>{{ message }}</p>
<input v-model="message" />
</div>
<script>
const HelloVueApp = {
data() {
return {
message: 'Hello Vue!!'
}
}
}
Vue.createApp(HelloVueApp).mount('#hello-vue')
</script>
</body>
</html>
- {{message}}:这里使用的是数据绑定。
- 当input框改变时,页面显示的值也会随着变。
- 可以在
{{}}
写JavaScript 表达式,例如:{{5+5}}
,true ? 'YES' : 'NO'
如果想值不跟着发生变化,添加 v-once
。
<p v-once>这个将不会改变: {{ message }}</p>
2.2、v-html
- v-html 指令用于输出 html 代码。
<div id="demo" class="demo">
<p>普通数据绑定: {{ rawHtml }}</p>
<p>转换HTML: <span v-html="rawHtml"></span></p>
</div>
<script>
const DemoApp = {
data() {
return {
rawHtml: '<span style="color: red">HTML代码</span>'
}
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
2.3、v-bind
- v-bind 指令用于绑定属性中的值,例如:
class动态绑定
,style样式动态绑定
,等等
。 - 简写成:
@
<style>
.class1{
background: #444;
color: #eee;
}
</style>
<div id="demo" class="demo">
动态绑定值:<input type="text" v-bind:value="demoValue"><br/>
<div v-bind:id="demoId">动态id</div>
动态禁用:<button v-bind:disabled="isButtonDisabled">按钮</button>
<p><a :href="url">百度一下</a></p>
<div :class="{'class1':isClass}">
动态class
</div>
</div>
<script>
const DemoApp = {
data() {
return {
demoValue: '123',
demoId: 'myDiv',
isButtonDisabled: true,
url: 'https://www.baidu.com/'
isClass: true
}
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
2.4、v-on
-
v-bind 指令用于监听 DOM 事件,例如:
点击事件
,键盘监听
,等等
。 -
简写成:
@
<div id="demo" class="demo">
<button @click="counter += 1">增加 1</button>
<!-- 监听回车键 -->
<input @keyup.enter="counter +=2" />
<p>这个按钮被点击了 {{ counter }} 次。</p>
</div>
<script>
const DemoApp = {
data() {
return {
counter: 0
}
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
2.5、v-if,v-show...
- v-if 用于条件性地渲染一块内容,为false时 DOM 不存在该元素
- v-else 与 v-if 组成一个“else 区块”。
- v-else-if 相应于 v-if 的“else if 区块”
- v-show 用于是否显示元素,为false时 DOM 存在该元素,只是添加了
display:none
属性。
<!-- 为false,则消失,页面也不存在DOM元素 -->
<h1 v-if="true">v-if</h1>
<!-- v-if 为false,sele才生效 -->
<h1 v-else>v-else</h1>
<!-- v-else-if -->
<div v-if="type === 'A'"> A </div>
<div v-else-if="type === 'B'"> B </div>
<div v-else-if="type === 'C'"> C </div>
<div v-else> Not A/B/C </div>
对比页面DOM
<div id="hello-vue" class="demo">
<p v-if="flag">v-if</p>
<p v-show="flag">v-show</p>
</div>
页面结果:
2.6、v-for
- v-for 指令基于一个数组来渲染一个列表
普通用法: v-for="item in items"
,每一个item
都是一个对象。
带索引用法:v-for="(item, index) in items"
,index是索引,从0开始。
v-for 与 v-if
同时使用
v-if
和v-for
是不推荐的,因为这样二者的优先级不明显。当
v-if
和v-for
同时存在于一个元素上的时候,v-if
会首先被执行。
<div id="demo" class="demo">
<li v-for="item in items">
姓名:{{item.name}},
年龄:{{item.age}}
</li>
</div>
<script>
const DemoApp = {
data() {
return {
items: [{ name: '小明', age:22 },
{ name: '大白', age:23 },
{ name: '张三', age:24 }]
}
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
2.7、v-model
- v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="demo" class="demo">
<h1>用户注册</h1>
名称:<input v-model="demoForm.name" placeholder="名称" /> <br/>
性别:<input type="radio" v-model="demoForm.sex" value="男" /> 男
<input type="radio" v-model="demoForm.sex" value="女" /> 女 <br/>
兴趣: <input type="checkbox" v-model="demoForm.hobby" value="吃饭" /> 吃饭
<input type="checkbox" v-model="demoForm.hobby" value="睡觉" /> 睡觉
<input type="checkbox" v-model="demoForm.hobby" value="打豆豆" /> 打豆豆 <br/>
区域:<select v-model="demoForm.region">
<option>中国</option>
<option>外国</option>
<option>其它</option>
</select> <br/>
备注: <textarea v-model="demoForm.remark" placeholder="备注"></textarea>
<div>
表单内容:{{demoForm}}
</div>
</div>
<script>
const DemoApp = {
data() {
return {
checkedNames:[],
demoForm:{
name:'',
sex: '',
hobby:[],
region: '',
remark: ''
}
}
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
</body>
</html>
修饰符
.lazy
:每次 change
事件后更新数据
.number
:自动转换为数字
.trim
:去除内容中两端的空格
名称:<input v-model.trim="name" placeholder="名称" /> <br/>
年龄:<input v-model.trim="number" placeholder="年龄" />
3、生命周期
一个模板新创建时,都会执行一些初始化函数,开发者可以在对应的周期内,去做好数据的初始化或者数据侦听等操作。
例如:在页面渲染好后,执行方法:
export default {
mounted() {
console.log(`页面加载完成。`)
}
}
图示:
现在不理解没有关系,以后做参考也是可以的。
4、ref
- ref 获取底层 DOM 元素。
- 作用:input自动获取焦点。表单提交前校验.....
- 也可以被用在一个子组件上(后面会讲到)。
页面加载成功后对焦。
<div id="demo" class="demo">
<input ref="input" />
</div>
<script>
const DemoApp = {
data() {
return {
}
},
mounted() {
this.$refs.input.focus()
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
5、计算属性
当值发生变化时,会跟着变化。
例如,根据不同的密码强度来显示强弱。
<div id="demo" class="demo">
<input v-model="pwd"><br/>
{{message}}
</div>
<script>
const DemoApp = {
data() {
return {
pwd:'',
message: ''
}
},
watch: {
pwd(newPwd, oldPwd) {
this.message = '新值:'+newPwd+',旧值'+oldPwd;
}
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
6、监听属性
如果监听当值发生变化时,会触发函数。
<div id="demo" class="demo">
<input v-model="pwd">
</div>
<script>
const DemoApp = {
data() {
return {
pwd:''
}
},
watch: {
pwd(newPwd, oldPwd) {
console.log('新值:'+newPwd+',旧值'+oldPwd)
}
}
}
Vue.createApp(DemoApp).mount('#demo')
</script>
7、组件概念
7.1、什么是组件?
有点像ctrt+C
和ctrt+V
例如,我这里有一段HTML代码,可以提取起来当模板使用。这个就是组件。
7.2、组件使用
一般会将 Vue 组件定义在一个单独的 .vue
文件中。这种叫做单文件组件 (简称 SFC)。
1、定义子组件
<!-- ButtonCounter.vue -->
<script>
export default {
data() {
return {
count: 0
}
}
}
</script>
<template>
<button @click="count++">你点击的次数 {{ count }}.</button>
</template>
2、引用子组件
<script>
import ButtonCounter from './ButtonCounter.vue'
export default {
components: {
ButtonCounter
}
}
</script>
<template>
<h1>下面是子组件信息!</h1>
<!-- 组件可以引用多次 -->
<ButtonCounter />
</template>
7.3、组件之间传值
组件相关于模板,那不同的模板,应该是根据不同的值来显示不同的内容。
案例1:现在点击父组件的数据,子组件根据传过来的ID显示不同的值。
1、定义接收值的子组件。
<!-- IdShow.vue -->
<script>
export default {
/* id:接收的属性名 */
props: ['id']
}
</script>
<template>
<h4>{{ id }}</h4>
</template>
2、定义传值的父组件。
<script>
import IdShow from './IdShow.vue'
export default {
components: {
IdShow
},
data() {
return {
id: 6
}
}
}
</script>
<template>
<h1>下面是子组件信息!</h1>
<!-- 自定义attributes -->
<IdShow :id="id" />
</template>
案例2:子组件向父组件传值
1、定义发送值的子组件。
<script>
export default {
methods:{
toMsg(){
//msg是自定义事件名
this.$emit('showMsg',"给父组件的值");
}
}
}
</script>
2、接收值的父组件。
<script>
import MsgShow from './MsgShow.vue'
export default {
components: {
MsgShow
},
data(){
return {
msg:''
}
},
methods: {
showMsgText(msg) {
this.msg = msg
}
}
}
</script>
<template>
<h1>接收值的父组件信息!</h1>
<p>{{msg}}</p>
<MsgShow @showMsg="showMsgText" />
</template>
7.4、组件占位符
- html标签是有双标签的,
- 某些场景,需要向子组件,让子组件渲染这些字段。
案例:封装一个提示窗,父组件传值。
1、父组件
<子组件>
<!-- 占位符内容 -->
这是内容。
</子组件>
2、子组件
<div class="message">
<!-- 占位符显示 -->
<slot></slot>
</div>