Vue2
简介
Vue官网:Vue2、Vue3
官方教程:Vue.js 教程 (dcloud.io)
Vue 是一套前端框架,免除原生 JavaScript 中的 DOM 操作,简化书写。Vue 基于 MVVM(Model-View-View-Model) 思想,实现数据的双向绑定,将编程的关注点放在数据上。
图中的 Model
就是数据,View
是视图,用户可以通过浏览器看到的内容;Model
和 View
是通过 ViewModel
对象进行双向绑定的,而 ViewModel
对象是 Vue
提供的。
快速入门
1、引入 vue.js
代码语言:javascript复制<script src="js/vue.js"></script>
//or
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
2、创建 Vue 核心对象,进行数据绑定
代码语言:javascript复制<script>
new Vue({
el: "#app",
data() {
return {
username: ""
}
},
methods:{
show(){
alert("我被点了...");
}
}
});
</script>
el
: 用来指定哪些标签受 Vue 管理。data
:用来定义数据模型methods
:用来定义函数。这个我们在后面就会用到
3、编写视图
代码语言:javascript复制<div id="app">
<input name="username" v-model="username" >
{{username}} <!--插值表达式-->
<input type="button" value="一个按钮" v-on:click="show()"><br>
</div>
{{}}
是 Vue 中定义的插值表达式
,模型的数据值展示在这个位置。v-model
创建双向数据绑定
Vue 指令
指令:HTML 标签上带有 v- 前缀
的特殊属性,不同指令具有不同含义。例如:v-if,v-for…
指令 | 作用 |
---|---|
v-bind | 为HTML标签绑定属性值,如设置 href , css样式等 |
v-model | 在表单元素上创建双向数据绑定 |
v-on | 为HTML标签绑定事件 |
v-if | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-else | |
v-else-if | |
v-show | 根据条件展示某元素,区别在于切换的是display属性的值 |
v-for | 列表渲染,遍历容器的元素或者对象的属性 |
v-bind
该指令可以给标签原有属性绑定模型数据。
代码语言:javascript复制<a v-bind:href="url">百度一下</a>
<a :href="url">百度一下</a> <!--v-bind 可以省略-->
v-model
该指令可以给表单项标签绑定模型数据。这样就能实现双向绑定效果。
代码语言:javascript复制<input name="username" v-model="username">
测试
代码语言:javascript复制<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<a v-bind:href="url">点击一下</a>
<a :href="url">点击一下</a>
<input v-model="url">
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data(){
return {
username:"",
url:"https://www.baidu.com"
}
}
});
</script>
</body>
</html>
v-on
绑定单击事件
代码语言:javascript复制<input type="button" value="一个按钮" v-on:click="show()">
<input type="button" value="一个按钮" @click="show()"><!--v-on:可替换成@-->
测试
代码语言:javascript复制<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="button" value="一个按钮" v-on:click="show()"><br>
<input type="button" value="一个按钮" @click="show()">
</div>
<script src="js/vue.js"></script>
<script>
//1. 创建Vue核心对象
new Vue({
el:"#app",
methods:{
show(){
alert("我被点了...");
}
}
});
</script>
</body>
</html>
v-if
- 当
count
模型的数据是3时,在页面上展示div1
内容; - 当
count
模型的数据是4时,在页面上展示div2
内容; count
模型数据是其他值时,在页面上展示div3
。- 这里为了动态改变模型数据
count
的值,再定义一个输入框绑定count
模型数据。
<div id="app">
<div v-if="count == 3">div1</div>
<div v-else-if="count == 4">div2</div>
<div v-else>div3</div>
<hr>
<input v-model="count">
</div>
<script>
new Vue({
el:"#app",
data(){
return {
count:3
}
}
});
</script>
测试
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div v-if="count == 3">div1</div>
<div v-else-if="count == 4">div2</div>
<div v-else>div3</div>
<hr>
<input v-model="count">
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data(){
return {
count:3
}
}
});
</script>
</body>
</html>
v-show
v-show
和 v-if
效果类似,区别在于渲染方式不同
v-show
不展示的原理是给对应的标签添加 display
属性,并将该属性值设置为 none
,这样就达到了隐藏的效果。而 v-if
指令是条件不满足时根本就不会渲染。
<div id="app">
<div v-show="count == 3">div1</div>
<div v-show="count == 4">div2</div>
<hr>
<input v-model="count">
</div>
测试
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div v-show="count == 3">div1</div>
<div v-show="count == 4">div2</div>
<hr>
<input v-model="count">
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data(){
return {
count:3
}
}
});
</script>
</body>
</html>
v-for
遍历
代码语言:javascript复制<标签 v-for="变量名 in 集合模型数据">
{{变量名}}
</标签>
如果在页面需要使用到集合模型数据的索引,就需要使用如下格式:
代码语言:javascript复制<标签 v-for="(变量名,索引变量) in 集合模型数据">
<!--索引变量是从0开始,所以要表示序号的话,需要手动的加1-->
{{索引变量 1}} {{变量名}}
</标签>
测试
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div v-for="addr in addrs">
{{addr}} <br>
</div>
<hr>
<div v-for="(addr,i) in addrs">
{{i 1}}--{{addr}} <br>
</div>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data(){
return {
addrs:["北京","上海","西安"]
}
}
});
</script>
</body>
</html>
生命周期
官网生命周期API:API — Vue.js (vuejs.org)
Vue 生命周期有八个阶段,每触发一个生命周期事件,会自动执行一个生命周期方法,这些生命周期方法也被称为钩子方法。
状态 | 阶段 | 描述 |
---|---|---|
beforeCreate | 创建前 | 在实例初始化之后,进行数据侦听和事件/侦听器的配置之前同步调用 |
created | 创建后 | 在实例创建完成后被立即同步调用 |
beforeMount | 载入前 | 在挂载开始之前被调用 |
mounted | 挂载完成 | 实例被挂载后调用 |
beforeUpdate | 更新前 | 在数据发生改变后,DOM 被更新之前被调用 |
updated | 更新后 | 在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用 |
beforeDestroy | 销毁前 | 实例销毁之前调用 |
destroyed | 销毁后 | 实例销毁后调用 |
vue-cli
vue-cli 官方提供的一个脚手架,用于快速生成一个 vue 的项目模板。预先定义好的目录结构及基础代码,就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速。
安装
代码语言:javascript复制npm install -g @vue/cli
#查看是否安装成功
vue -V
使用
代码语言:javascript复制#创建一个名为myvue的vue项目
vue create myvue
#运行
cd myvue
npm run serve
以图形化界面创建和管理项目
代码语言:javascript复制vue ui
vue 项目的运行流程
在工程化的项目中, vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。
① App.vue 用来编写待渲染的模板结构 ② index.html 中需要预留一个 el 区域 ③ main.js 把 App.vue 渲染到了 index.html 所预留的区域中
src 目录的构成
assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源 components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下 main.js 是项目的入口文件。整个项目的运行,要先执行 main.js App.vue 是项目的根组件。
代码语言:javascript复制├── README.md
├── babel.config.js
├── jsconfig.json
├── node_modules
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico # favicon图标
│ └── index.html # html模板
├── src
│ ├── App.vue # 入口页面,放每个页面都有的内容
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── main.js # 入口文件 加载组件 初始化等
│ ├── router # 路由
│ └── views # 单个页面内容
└── vue.config.js # vue-cli 配置
Vue3
script setup
它是 Vue3 的一个新语法糖,在 setup
函数中。所有 ES 模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。相对于之前的写法,使用后,语法也变得更简单。
使用方式极其简单,仅需要在 script
标签加上 setup
关键字即可。示例:
<script setup></script>
属性和方法无需返回
这可能是带来的较大便利之一,在以往的写法中,定义数据和方法,都需要在结尾 return 出去,才能在模板中使用。在 script setup 中,定义的属性和方法无需返回,可以直接使用!
代码语言:javascript复制<!--不使用script setup-->
<template>
<div>
<p>My name is {{name}}</p>
<p>sex is {{sex}}</p>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
name:'组件名'
setup(){
const name = ref('Tom')
const sex = ref('男')
return{
name,
sex,
}
}
}
</script>
代码语言:javascript复制<!--使用script setup-->
<template>
<div>
<p>My name is {{name}}</p>
<p>sex is {{sex}}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const name = ref('Tom')
const sex = ref('男')
</script>
组件自动注册
在 script setup 中,引入的组件可以直接使用,无需再通过components
进行注册
<!--不使用script setup-->
<template>
<Header/>
<Footer/>
</template>
<script>
import Header from '@/components/Header.vue'
import Footer from '@/components/Footer.vue'
export default {
components: {
Header,
Footer,
}
}
</script>
代码语言:javascript复制<!--使用script setup-->
<template>
<Header/>
<Footer/>
</template>
<script setup>
import Header from '@/components/Header.vue'
import Footer from '@/components/Footer.vue'
</script>
无需指定组件name
无需指定当前组件的名字,它会自动以文件名为主,也就是不用再写name
属性了。如果需要定义类似 name 的属性,可以再加个平级的 script 标签,在里面实现即可。
<!--不使用script setup-->
<template>
<el-footer class="footer">
<span>我是页底</span>
</el-footer>
</template>
<script>
export default{
name:'Footer',
}
</script>
代码语言:javascript复制<!--使用script setup-->
<template>
<el-footer class="footer">
<span>我是页底</span>
</el-footer>
</template>
<script setup>
</script>
使用 props
通过defineProps
指定当前 props 类型,获得上下文的props对象。示例:
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
title: String,
})
</script>
使用 emits
使用defineEmit
定义当前组件含有的事件,并通过返回的上下文去执行 emit。示例:
<script setup>
import { defineEmits } from 'vue'
const emit = defineEmits(['change', 'delete'])
</script>
获取 slots 和 attrs
可以通过useContext
从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrs
和useSlots
。示例:
<!--旧-->
<script setup>
import { useContext } from 'vue'
const { slots, attrs } = useContext()
</script>
<!--新-->
<script setup>
import { useAttrs, useSlots } from 'vue'
const attrs = useAttrs()
const slots = useSlots()
</script>
父子组件传值
- 子组件获取到父组件的值用defineEmit
- 子组件给父组件传值用defineProps
- 子组件暴露自己的数据和方法用defineExpose
defineEmit
defineProps
defineExpose
传统的写法,我们可以在父组件中,通过 ref 实例的方式去访问子组件的内容,但在 script setup 中,该方法就不能用了,setup 相当于是一个闭包,除了内部的 template
模板,谁都不能访问内部的数据和方法。如果需要对外暴露 setup 中的数据和方法,需要使用 defineExpose API。
//child.vue
<template>
<div>{{num}}</div>
</template>
<script setup>
import {ref,defineExpose} from 'vue'
const num = ref(123)
defineExpose({
num
})
</script>
//father.vue
<template>
<div>
<Child ref="child"></Child>
</div>
</template>
<script setup>
import {ref} from 'vue'
import Child from './child.vue'
const child = ref(null)
setTimeout (() => {
console.log(child.value.num )
},1000)
</script>
ref & reactive
Vue3 中主要用 reactive 和 ref 进行响应数据的监听。他俩的区别在于:
- ①reactive中必须存放对象(json、数组等),不能存放基本数据类型
- ②ref则可以存放基本数据类型【注:ref本质还是reactive】
let a = reactive({
name:'Tom',
sex:'man'
});
let b = ref(5);
ref
功能
- 1.基本类型封装,使数据响应式
- 2.模板ref,获取dom元素节点
2.ref属性获取dom元素
在vue2.x
中,可以通过给元素添加ref='xxx'
属性,然后在代码中通过this.$refs.xxx
获取到对应的元素
然而在vue3
中时没有$refs
这个东西的,因此vue3
中通过ref
属性获取元素就不能按照vue2
的方式来获取
vue3
需要借助生命周期方法,原因很简单,在setup
执行时,template
中的元素还没挂载到页面上,所以必须在mounted
之后才能获取到元素。
<template>
<div ref='box'>I am DIV</div>
</template>
<script>
import {ref,onMounted}
export default{
setup(){
let box = ref(null);
onMounted(()=>{
console.log(box.value)
});
return {box}
}
}
</script>
如上代码,vue3
中,所有生命周期方法都抽离出去了,需要用时直接import
。这里导入了一个onMounted
当界面挂载出来的时候,就会自动执行onMounted
的回调函数,里头就可以获取到dom元素
vue3如何通过ref属性获取界面上的元素? 在 template 中的写法跟 Vue2 一样,给元素添加个 ref=’xxx’, 在 setup 中,先创建一个响应式数据,并且要把响应式数据暴露出去,当元素被创建出来的时候,就会给对应的响应数据赋值,当响应式数据被赋值之后,就可以利用生命周期方法,在生命周期方法中获取对应的响应式数据,即DOM元素
Element UI
Element 官网:Vue 2 UI 框架 | Element、Vue 3 UI 框架 | Element Plus
快速入门
1、引入资源
代码语言:javascript复制<!-- 引入Vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
2、创建 Vue 对象
代码语言:javascript复制<script>
new Vue({
el:"#app"
})
</script>
3、使用Element组件代码
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- element代码 -->
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">删除</el-button>
</el-row>
</div>
<!-- 引入Vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el:"#app"
})
</script>
</body>
</html>