1.先要安装node.js 16以上的版本
安装成功后查看版本:node -v
2.在要创建vue项目的文件夹中运行命令:
npm init vue@latest
此命令用于创建一个使用最新版本Vue.js的项目
3.在“Project name: ...”后面给项目命名为“vue-base”(小写)
Project name: ... vue-base
4.进入创建好的项目:
cd vue-base
5.在项目中安装所需的依赖包:
npm install 或者 cnpm install(这个快)
6.运行项目:
npm run dev
7.运行之后,会看到一个地址,在浏览器能访问这个地址,就说明vue项目创建好了
Local: http://localhost:5173/
1.选择合适的开发工具
2.Vue前端开发一般使用vscode + Volar插件,但我是后端开发人员,所以用的idea
刚刚创建好的“vue-base”项目,在idea中打开是这样的:
这些文件的作用
.vscode VSCode工具的配置文件
node_modules Vue项目的运行依赖文件
public 资源文件夹(浏览器图标)
src 源码文件夹
.gitignore git忽略文件
index.html 入口HTML文件
package.json 信息描述文件
package-lock.json 确保项目在不同环境中都能复现相同的结果
README.md 注释文件
vite.config.js Vue配置文件
删除一些文件,来试着写一个纯净的案例
- 新建一个vue项目
- 删除components文件夹中的所有内容
- 删除main.js中的:import ‘./assets/main.css’
- 在App.vue中写以下代码:
<template>
<h3>模板语法h3>
<p>{{ msg }}p>
template>
<script>
export default {
data() {
return {
msg: "vue语法"
}
}
}
script>
浏览器运行效果:
<template>
<h3>模板语法h3>
<p>{{ msg }}p>
<p>{{ num + 3}}p>
<p>{{ ok ? '没毛病' : '有毛病'}}p>
<p>{{message.split("").reverse().join("")}}p>
template>
<script>
export default {
data() {
return {
msg: "vue语法",
num:10,
ok:true,
message:'大家好'
}
}
}
script>
无效
<!--这是一个语句,而非表达式-->
{{ var a = 1 }}
<!--不支持条件控制,请使用三元表达式-->
{{ if (ok) {return message }}}
<template>
<p>{{ rawHtml}}p>
<p v-html="rawHtml">p>
template>
<script>
export default {
data() {
return {
rawHtml:"茶碗儿学Vue"
}
}
}
script>
浏览器效果
<template>
<div v-bind:id="dynamicId" v-bind:class="dynamicClass" :title="dynamicTitle">{{ msg }}div>
<button :disabled="isButtonDisabled">这是按钮button>
<div v-bind="arrObject">绑定对象div>
template>
<script>
export default {
data() {
return {
msg: "这是HelloWord文件",
dynamicClass: "appClass",
dynamicId: "appId",
dynamicTitle:null,
isButtonDisabled:true,
// 对象
arrObject:{
class: "arrClass",
id: "arrId"
}
}
}
}
script>
<style>
.appClass {
color: red;
}
style>
浏览器效果
注意:
- 属性绑定时,v-bind可以省略不写
- 属性绑定的值为null或者undefined时,会自动忽略
- v-if
- v-else
- v-else-if
- v-show
指令表达式返回为真的时候才会被渲染
案例:
<template>
<h3>条件渲染h3>
<div v-if="flag">v-if测试div>
template>
<script>
export default {
data() {
return {
flag: true
}
}
}
script>
浏览器效果
- v-if:为假的时候,才返回v-else
- v-else-if:相当于“else if”,可以连续多次重复使用
- v-show:跟v-if用法一样,为真时显示,为假时不显示
案例:
<template>
<h3>条件渲染h3>
<div v-if="flag">v-if测试div>
<div v-else>v-else测试div>
<div v-if="type==='A'">Adiv>
<div v-else-if="type==='B'">Bdiv>
<div v-else-if="type==='C'">Vdiv>
<div v-else>It's D,Not A/B/Cdiv>
<div v-show="vsFlag">v-show测试div>
template>
<script>
export default {
data() {
return {
flag: false,
type:"D",
vsFlag:true
}
}
}
script>
浏览器效果
- 1.控制手段不同:v-show隐藏则是为该元素添加css–display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除。
- 2.编译过程不同:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换。
- 3.编译条件不同:v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染。v-show由false变为true的时候不会触发组件的生命周期。
- 4.性能消耗不同:v-if有更高的切换消耗;v-show有更高的初始渲染消耗。
- 5.用途不同:v-if更适合于带有权限的操作,渲染时判断权限数据。v-show更适合于日常使用,可以减少数据的渲染,减少不必要的操作。
v-if和v-show虽然看起来很相似,但是它们的使用方法和场景是有很大区别的。
- v-if适合用在数据不会频繁切换的场景。
- v-show适合用在数据会频繁切换的场景。
v-for的作用
- 遍历数组中的元素
- 遍历对象中的属性
使用 v-for 指令基于数组来渲染一个列表
- 值需要使用 item in items 形式的语法(in可以写成of)
- 此时item代表数组中的一个元素,items代表数组
v-for 也支持使用可选的第二个参数表示当前项的索引
- (item,index) in items index表示索引下标
案例1
<template>
<h3>列表渲染h3>
<p v-for="name in names">{{ name }}p>
<div v-for="user in result">
<p>{{ user.id }}-{{ user.address }}-{{ user.say }}p>
div>
template>
<script>
export default {
data() {
return {
names: ["张大仙", "马保国", "蔡徐坤", "沙悟净", "流川枫"],
result: [
{
"id": 10,
"address": "杭州",
"say": "亚运会"
},
{
"id": 13,
"address": "北京",
"say": "村委会"
},
{
"id": 21,
"address": "上海",
"say": "刘奶奶喝牛奶"
},
{
"id": 35,
"address": "杭州",
"say": "不抽烟不喝酒"
},
{
"id": 61,
"address": "杭州",
"say": "饿了就吃饭"
}
]
}
}
}
script>
浏览器效果
案例2
<template>
<div v-for="(name,index) in names">
<p>{{ index }}:{{ name }}p>
div>
template>
<script>
export default {
data() {
return {
names: ["张大仙", "马保国", "蔡徐坤", "沙悟净", "流川枫"]
}
}
}
script>
浏览器效果
v-for 也可以遍历一个对象的所有属性
- 使用 item in items 形式的语法(in可以写成of)
- 此时item代表对象中的一个属性,items代表对象
案例
<template>
<p v-for="item of user">{{ item }}p>
<p v-for="(value,key,index) of user">{{ index}}:{{ key }}-{{value}}p>
template>
<script>
export default {
data() {
return {
user: {
name: "林雨薇",
age: "1999年5月2日",
sex: "女"
}
}
}
}
script>
浏览器效果
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
<p>{{ message }}p>
<p>{{ msg }}p>
<p>{{ cc() }}p>
<p>{{ aa }}p>
div>
<script>
// 必须写:创建应用,响应式数据
const { createApp, ref } = Vue
createApp({
setup() {
//响应式数据
const message = ref('Hello Vue3!')
return {
message,
//静态文本
msg:"茶碗儿学Vue3",
//方法
cc(){
console.log("这是一个方法")
return "方法被调用"
}
}
},
// 计算属性在这里面写
computed: {
aa(){
console.log('本事要大,脾气要小')
return "计算属性被计算"
}
}
}).mount('#app')
script>
body>
html>
浏览器效果
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
<button @click="hello">{{message}}button><br>
<button @click="study('Vue3')">{{msg}}button>
<P>拆分字符串为字符数组:{{msg.split('')}}P>
<P>反转字符数组:{{msg.split('').reverse()}}P>
<P>字符数组转为字符串:{{msg.split('').reverse().join('')}}P>
div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
//响应式数据
const message = ref('点击')
return {
message,
//静态数据
msg:"学习",
//方法
hello(){
alert("WOC,Vue3真难……")
},
study(str){
alert(str+"真令人头大……")
}
}
}
}).mount('#app')
script>
body>
html>
解决:大量代码逻辑写在视图中,页面代码不简洁
- 方法:缺点【多次使用会重复调用方法】
- 计算属性:优点【多次调用也只执行一次】
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
<p>方法:{{reversed()}}p>
<p>方法:{{reversed()}}p>
<p>方法:{{reversed()}}p>
<p>计算属性:{{reversedMsg}}p>
<p>计算属性:{{reversedMsg}}p>
<p>计算属性:{{reversedMsg}}p>
div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
//响应式数据
const message = ref('好好学习')
return {
message,
//方法
reversed(){
console.log('reversed()方法被调用')
return this.message.split('').reverse().join('')
}
}
},
// 计算属性
computed: {
//在计算属性里面写方法,多次调用也只执行一次
reversedMsg(){
console.log('reversedMsg()计算属性被计算')
return this.message.split('').reverse().join('')
}
}
}).mount('#app')
script>
body>
html>
查看控制台
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
姓:{{firstName}}<input type="text" v-model="firstName"><br>
名:{{lastName}}<input type="text" v-model="lastName"><br>
全名:{{fullName}}<input type="text" v-model="fullName"><br>
div>
<script>
const { createApp, ref } = Vue
createApp({
//data.return
setup() {
//响应式数据
const firstName = ref('迈克尔')
const lastName = ref('乔丹')
return {
firstName,
lastName
}
},
// 计算属性在这里面写
computed: {
//计算属性的setter和getter
fullName:{
set(value){
console.log("运行fullName计算属性的set方法,fullName="+value)
// 将fullName通过-分割后,再传给firstName和lastName
const names = value.split("-")
this.firstName = names[0]
this.lastName = names[1]
},
get(){
console.log("运行fullName计算属性的get方法")
return this.firstName+"-"+this.lastName;
}
}
}
}).mount('#app')
script>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
姓:{{firstName}}<input type="text" v-model="firstName"><br>
名:{{lastName}}<input type="text" v-model="lastName"><br>
全名:{{fullName}}<input type="text" v-model="fullName"><br>
div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const firstName = ref('迈克尔')
const lastName = ref('乔丹')
const fullName = ref('')
return {
firstName,
lastName,
fullName
}
},
// 监听
watch: {
// firstName变化时执行
firstName(value){
// firstName变化时打印
console.log("firstName变化:"+value)
// 此时的fullName为
this.fullName = value + "-" + this.lastName
},
// lastName变化时执行
lastName(value){
// lastName变化时打印
console.log("lastName变化:"+value)
// 此时的fullName为
this.fullName = this.firstName + "-" + value
},
// fullName变化时执行
fullName(value){
// 将fullName通过-分割后,再给到firstName和lastName
const names = value.split("-")
this.firstName = names[0]
this.lastName = names[1]
}
}
}).mount('#app')
script>
body>
html>
需求:如果复选框被勾选,则能点击"确定按钮",反之则不能点击"确定"按钮
- 方式一:v-if, v-else (删除 / 创建节点)
- 方式二:v-show (隐藏 / 展示节点)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
<input type="checkbox" v-model="ok">是否同意许可?<br>
<button v-if="ok">确定button>
<button v-else disabled>确定button>
<br>
<br>
<input type="checkbox" v-model="ok1">是否同意许可?<br>
<button v-show="ok1">确定button>
<button v-show="!ok1" disabled>确定button>
div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
//设置响应式数据的初始值
const ok = ref(false)
const ok1 = ref(false)
return {
ok,
ok1
}
}
}).mount('#app')
script>
body>
html>
- 遍历数组
- 遍历对象
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
<p v-for="name in names">{{ name }}p>
<ul>
<li v-for="(user,index) in result">
{{index+1}},{{ user.id }},{{ user.address }},{{ user.say }}
li>
ul>
div>
<script>
const { createApp} = Vue
createApp({
setup() {
return {
// 数组
names: ["张大仙", "马保国", "蔡徐坤", "沙悟净", "流川枫"],
// 对象
result: [
{
"id": 10,
"address": "杭州",
"say": "亚运会"
},
{
"id": 13,
"address": "北京",
"say": "村委会"
},
{
"id": 21,
"address": "上海",
"say": "刘奶奶喝牛奶"
},
{
"id": 35,
"address": "杭州",
"say": "不抽烟不喝酒"
},
{
"id": 61,
"address": "杭州",
"say": "饿了就吃饭"
}
]
}
}
}).mount('#app')
script>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
head>
<body>
<div id="app">
<h1 id="msg">{{message}}h1>
div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const message = ref('我爱油泼面')
return {
message,
// 方法可以在这里写
add(){
console.log("访问add方法")
}
}
},
// 方法可以在这里写
methods: {
show(){
console.log('访问show方法')
}
},
// 创建完成
// 先执行,可以访问到数据模型,可以访问到成员方法
created () {
console.log('vue实例创建完成')
console.log('created中获取message的定义:'+this.message)
this.show()
this.add()
// 没有被渲染到页面上,所以无法获取到元素内容
// 遗留问题:预期获取不到元素,但应该会打印"{{message}}",但其实会报错,这块我还不知道为什么
console.log("created中获取元素内容:"+document.getElementById("msg").innerText)
},
// 渲染完成
// 后执行,可以访问到数据模型,可以访问到成员方法
mounted () {
console.log('vue页面渲染完成')
console.log('mounted中获取message的定义:'+this.message)
this.show()
this.add()
// 页面渲染完成,可以获取到元素
console.log("mounted中获取元素内容:"+document.getElementById("msg").innerText)
}
}).mount('#app')
script>
body>
html>