前端工程化之nodejs+Vue3速通

npm

npm是nodejs中进行包管理的工具
下载:https://nodejs.org/zh-cn/download

  1. 环境
    安装Node.js
    在这里插入图片描述
    看到以上截图,表明安装成功

配置npm(设置npm镜像源)

npm config set registry https://registry.npmmirror.com		#设置阿里云镜像源
npm config get registry		#查看镜像源
  1. 命令
    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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值