npm
npm是nodejs中进行包管理的工具
下载:https://nodejs.org/zh-cn/download
- 环境
安装Node.js
看到以上截图,表明安装成功
配置npm(设置npm镜像源)
npm config set registry https://registry.npmmirror.com #设置阿里云镜像源
npm config get registry #查看镜像源
- 命令
npm init 项目初始化
npm init -y 默认一路yes
测试npm init命令,出现报错
解决方法:
①以管理员身份运行 PowerShell
按下 Win + X, Windows Terminal (管理员)。
②设置 PowerShell 执行策略
在 PowerShell 窗口中,你可以通过设置执行策略来允许运行脚本。执行以下命令来更改执行策略:
Set-ExecutionPolicy RemoteSigned
之后再执行npm init即可
npm install 包名 安装js包到项目中(仅当前项目有效)
npm install -g 全局安装,所有都能用
npm update 包名 升级包到最新版本
npm uninstall 包名 卸载包
npm run 项目运行
Vite
官⽹:https://cn.vitejs.dev
npm create vite 创建项目脚手架
npm install 安装项目所有依赖
npm run dev 启动项目
Vue3
组件化
组件系统是一个抽象的概念;
组件:小型、独立、可复用的单元
组合:通过组件之间的组合,包含关系构建出一个完整的应用。
几乎任意类型的应用都可以抽象为一个组件树。
SFC
Vue的单文件组件 即Single File Component,简称SFC;是一种特殊的文件格式,是我们能够将一个Vue组件的模板、逻辑与央视封装在单个文件中。
<script setup>
//编写脚本
</script>
<template>
//编写页面模板
</template>
<style scoped>
//编写样式
</style>
Vue工程
工作原理
基础使用
插值 {{}}
<script setup>
let name = "张三"
let car = {
brand: "小米",
price: 9999
}
</script>
<template>
<h2>姓名:{{name}}</h2>
<h2>品牌:{{car.brand}}</h2>
<h2>价格:{{car.price}}</h2>
</template>
<style scoped>
</style>
指令
事件绑定:v-on 可以简写为:@
<script setup>
function buy() {
alert("购买成功")
}
</script>
<template>
<button v-on:click="buy">购买</button>
<button @click.once="buy">购买</button>
</template>
<style scoped>
</style>
Modifiers:修饰符详情
https://cn.vuejs.org/guide/essentials/event-handling
条件判断:v-if v-else v-else-if
<script setup>
let car ={
brand: "小米",
price: 9999
}
</script>
<template>
<span style="color: green" v-if="car.price < 1000">很便宜</span>
<span style="color: red" v-else="car.price ">太贵了</span>
</template>
<style scoped>
</style>
循环:v-for
<script setup>
let fruits = ["苹果", "香蕉", "梨"]
</script>
<template>
<li v-for="(f,i) in fruits">{{ f }} ==> {{ i }}</li>
</template>
<style scoped>
</style>
属性绑定:v-bind:属性=‘XX’,可以简写为:属性=‘XX’ 单向绑定:数据-页面
默认数据不具备响应式特性
<script setup>
let url = "https://www.baidu.com";
</script>
<template>
<a v-bind:href="url" > Go1!</a>
<a :href="url" > Go2 !</a>
</template>
<style scoped>
</style>
响应式:ref() 和 reactive() 数据的变化可以更新到页面效果上
ref():
1、把基本类型、对象类型数据使用 ref() 包装成响应式数据
2、使用 代理对象.value = “”
3、页面取值、属性绑定 直接 {{代理对象}}
<script setup>
import {ref} from "vue";
const url = ref("https://www.baidu.com");
function changeUrl() {
console.log(url)
url.value = "https://www.atguigu.com"
}
</script>
<template>
<a :href="url" :abc="url"> Go ! {{ url }}</a>
<button @click="changeUrl">改变地址</button>
</template>
<style scoped>
</style>
reactive():
1、把对象类型使用 reactive() 包装成响应式数据
2、使用 代理对象 = “”、
3、页面取值、属性绑定 直接 {{变量名}}
<script setup>
import {reactive} from "vue";
let car = reactive({
brand: "小米",
price: 9999
})
function addPrice() {
car.price += 100;
}
</script>
<template>
<button @click="addPrice">加价</button>
</template>
<style scoped>
</style>
表单绑定:v-model 双向绑定:数据-页面 页面-数据
<script setup>
import {reactive} from "vue";
const data = reactive({
username: "zhangsan",
agree: true,
hobby: [],
gender: "女",
degree: "",
course: []
})
</script>
<template>
<div style="display: flex;">
<div style="border: 1px solid black;width: 300px">
<form>
<h1>表单绑定</h1>
<p style="background-color: azure">
<label>姓名(文本框):</label>
<input v-model="data.username"/>
</p>
<p style="background-color: azure"><label>同意协议(checkbox):</label>
<input type="checkbox" v-model="data.agree"/>
</p>
<p style="background-color: azure">
<label>兴趣(多选框):</label><br/>
<label><input type="checkbox" value="足球" v-model="data.hobby"/>足球</label>
<label><input type="checkbox" value="篮球" v-model="data.hobby"/>篮球</label>
<label><input type="checkbox" value="羽毛球" v-model="data.hobby"/>羽毛球</label>
<label><input type="checkbox" value="乒乓球" v-model="data.hobby"/>乒乓球</label>
</p>
<p style="background-color: azure">
<label>性别(单选框):</label>
<label><input type="radio" name="sex" value="男" v-model="data.gender">男</label>
<label><input type="radio" name="sex" value="女" v-model="data.gender">女</label>
</p>
<p style="background-color: azure">
<label>学历(单选下拉列表):</label>
<select v-model="data.degree">
<option disabled value="">选择学历</option>
<option>小学</option>
<option>初中</option>
<option>高中</option>
<option>大学</option>
</select>
</p>
<p style="background-color: azure">
<label>课程(多选下拉列表):</label>
<br/>
<select multiple v-model="data.course">
<option disabled value="">选择课程</option>
<option>语文</option>
<option>数学</option>
<option>英语</option>
<option>道法</option>
</select>
</p>
</form>
</div>
<div style="border: 1px solid blue;width: 200px">
<h1>结果预览</h1>
<p style="background-color: azure"><label>姓名:{{data.username}}</label></p>
<p style="background-color: azure"><label>同意协议:{{data.agree}}</label>
</p>
<p style="background-color: azure">
<label>兴趣:
<li v-for="h in data.hobby">{{h}}</li>
</label>
</p>
<p style="background-color: azure">
<label>性别:{{data.gender}}</label>
</p>
<p style="background-color: azure">
<label>学历:{{data.degree}}</label>
</p>
<p style="background-color: azure">
<label>课程:
<li v-for="c in data.course">{{c}}</li>
</label>
</p>
</div>
</div>
</template>
<style scoped>
</style>
计算属性 computed 根据已有数据计算出新数据
<script setup>
import {computed, reactive, ref} from "vue";
let car = reactive({
brand: "小米",
price: 9999
})
function addPrice() {
car.price += 100;
}
const num = ref(1);
const totalPrice = computed(() => car.price * num.value);
</script>
<template>
<template>
<h2>品牌:{{ car.brand }}</h2>
<h2>价格:{{ car.price }}</h2>
<h2>数量:{{ num }}</h2>
<button @click="addPrice">加价</button>
<button @click="num++">加量</button>
<button @click.once="buy">购买 {{ totalPrice }}</button>
</template>
<style scoped>
</style>
进阶用法
监听 watch 和 watchEffect
watch(num,(value, oldValue, onCleanup)=>{
console.log("value",value)
console.log("oldValue",oldValue)
})
watchEffect(() => {
if (num.value > 3) {
alert("超出限购数量")
num.value = 3;
}
if (car.price > 11000) {
alert("太贵了")
car.price = 11000;
}
})
生命周期
⽣命周期整体分为四个阶段,分别是: 创建、挂载、更新、销毁 ,每个阶段都有两个钩⼦,⼀前⼀
后。
常用钩子函数:
onMounted(挂载完成)
onUpdated(更新完成)
onBeforeUnmount(卸载之前)
<script setup>
import {onBeforeMount, onBeforeUpdate, onMounted, onUpdated, ref} from "vue";
const count = ref(1);
function countAdd(){
count.value ++;
}
//生命周期钩子函数
//挂载 去后台查询用户信息
onBeforeMount(()=>{
//
console.log("挂载前:count",count.value)
console.log("挂载前:",document.getElementById("btn01"))
})
onMounted(()=>{
//
console.log("挂载完成:count",count.value)
console.log("挂载完成:",document.getElementById("btn01"))
})
//更新: 前内容未变,数据变了
onBeforeUpdate(()=>{
console.log("更新前:count",count.value)
console.log("更新前:btn内容",document.getElementById("btn01").innerHTML)
})
onUpdated(()=>{
console.log("更新完:count",count.value)
console.log("更新完:btn内容",document.getElementById("btn01").innerHTML)
})
</script>
<template>
<button id="btn01" @click="countAdd">点 {{count}}</button>
</template>
<style scoped>
</style>
组件传值 父组件与子组件之间传值
父传子 Props
单向数据流效果:
父组件修改值,子组件发生变化
子组件修改值,父组件不会感知
//父组件给子组件传递数据:使用属性绑定
<Son :books="data.books" :money="data.money">
//子组件定义接收父组件属性
let props = defineProps({
money: {
type: Number,
required: true,
default: 200
},
books: Array
});
子传父 Emit
//子组件定义发生的事件
let emits = defineEmits(['buy']);
function buy(){
// props.money -= 5;
emits('buy',-5);
}
//父组件感知事件和接收事件值
<Son :books="data.books" :money="data.money" @buy="moneyMinis"/>
插槽 Slots v-slot可以简写为#
子组件可以使用插槽接受模板内容
基本用法
<button class="fancy-btn">
<slot></slot><!--插槽出口-->
</button>
<FancyButton>
Click me!<!--插槽内容-->
</FancyButton>
具名插槽
<Son v-bind="data">
<template v-slot:title>
哈哈SonSon
</template>
<template #btn>
买飞机
</template>
</Son>
<h3>
<slot name="title">
哈哈Son
</slot>
</h3>
<button @click="buy">
<slot name="btn"/>
</button>