学习vue
vue
1、开发环境准备
安装node https://nodejs.org/en/
安装Vue工具
Vue CLi 安装命令:npm install -g @vue/cli
安装之后查看
vue --version

vue 官网:https://cn.vuejs.org/
2、创建项目
vue create 项目名
注意:项目名字不能大写

选择

根据自己的需要选择

默认即可

输入n即可

根据提示运行项目

启动成功


3、模板语法
<template>
<div>
<h3>学习模板语法</h3>
<p>{{message}}</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
message:"测试"
}
}
}
</script>
1、v-html 解析html标签
2、v-bind 响应式地绑定
3、v-if、v-else 根据值的真假移除或添加元素
4、v-show 根据值的真假显示或隐藏元素
4、列表渲染
v-for
<template>
<div>
<h3>列表渲染</h3>
<ul>
<li v-for="(item,index) in names">{{ item.name }}------>{{ index }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
names: [
{id: 1, name: "小明"},
{id: 2, name: "老大"},
{id: 3, name: "老二"}
]
}
}
}
</script>
<style scoped>
ul {
list-style: none;
}
</style>

注意
<li v-for="(item,index) in names" :key="item.id">{{ item.name }}------>{{ index }}</li> :key="item.id" 在数组元素改变时,会只重新渲染改变的数据,其它没变的不会重新渲染 减少性能的消耗
5、事件处理
@click或v-on:click
<template>
<div>
<h3>事件处理</h3>
<button v-on:click="dianJi">点击</button>
<h3>{{num}}</h3>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
num: 0
}
},
methods: {
dianJi() {
this.num += 1;
}
}
}
</script>
<style scoped>
ul {
list-style: none;
}
</style>

6、双向数据绑定
v-model
<template>
<div>
<h3>双向数据绑定</h3>
<input type="text" v-model="username">
<h3>{{username}}</h3>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
username: ""
}
}
}
</script>
<style scoped>
ul {
list-style: none;
}
</style>

1、v-model.lazy 加上后输入数据回车或失去焦点才进行同步
2、v-model.trim 去除输入的空格
7、单文件组件
1、组件内容
<template>
<div>
<h3>单文件组件</h3>
</div>
</template>
<script>
export default { //导出
name: "MyComponents",
data() {
return {}
}
}
</script>
//scoped 添加这属性 组件内设置的样式只会作用在这个组件
<style scoped>
h3 {
color: red;
}
</style>
2、加载组件
1、引入组件 import myComponents from "@/components/MyComponents";
2、挂载组件components: {myComponents}
3、显示组件<my-components/>

8、组件交互
props 父组件向子组件传值
1、在父组件定义好值
data() {
return {
title: "我是一个标题",
age: 100
}
}
2、在显示组件上引用
<my-components :oneHiz="title" :age="age"/>
3、最后在子组件上使用
export default {
name: "MyComponents",
props:{
oneHiz:{ //需要定义类型
type:String,
default:""
},
age:{
type:Number,
default:0
}
}
}
9、自定义事件组件交互
现在子组件定义传递的值和事件
<template>
<div>
<h3>自定义组件传递数据</h3>
<button @click="sendFather">发送</button>
</div>
</template>
<script>
export default {
name: "MyComponents",
data() {
return {
msg: "我是MyComponents数据"
}
},
methods: {
sendFather() {
//参数1: 字符串
//参数2: 传递的数据
this.$emit("onEvent", this.msg)
}
}
}
</script>
<style scoped>
h3 {
color: red;
}
</style>
父组件接受值
<template>
<div>
<img alt="Vue logo" src="./assets/logo.png">
<my-components @onEvent="getData"/>
</div>
</template>
<script>
import myComponents from "@/components/MyComponents";
export default {
name: 'App',
components: {
myComponents
},
methods: {
getData(data) {
console.log(data)
}
}
}
</script>
<style>
div {
width: 400px;
height: 400px;
text-align: center;
margin: 0 auto;
}
</style>
作用:子组件向父组件传递值
时间:2022-10-28 晚上
10、组件的生命周期
创建时: beforeCreate、Created
渲染时: beforeMount、mounted
更新时: beforeUpdate、updated
卸载时: beforeUnmount、unmounted
<template>
<div>
<h3>组件生命周期</h3>
<p>{{ msg }}</p>
<button @click="msg='数据'">点击</button>
</div>
</template>
<script>
export default {
name: "MyComponents",
data() {
return {
msg: ""
}
},
beforeCreate() {
console.log("beforeCreate:组件创建之前!")
},
created() {
console.log("created:组件创建完成!")
},
beforeMount() {
console.log("beforeCreate:组件渲染之前!")
},
mounted() {
//网络请求通常放在这里
console.log("created:组件渲染完成!")
},
beforeUpdate() {
console.log("beforeCreate:组件更新之前!")
},
updated() {
console.log("created:组件更新完成!")
},
beforeUnmount() {
//把消耗性能的处理都干掉 例如: 定时器
console.log("beforeCreate:组件卸载之前!")
},
unmounted() {
console.log("created:组件卸载完成!")
}
}
</script>
<style scoped>
h3 {
color: red;
}
</style>


11、vue引入第三方

swiper官网:https://swiper.com.cn/
安装: cnpm install --save swiper
指定版本安装 : cnpm install --save swiper@8.1.6
卸载依赖包: cnpm uninstall swiper --save
12、Axios 网络请求
安装依赖包:cnpm install --save axios
1、局部引入
<template>
<div>
<h3>{{ Details.title }}</h3>
<p>{{ Details.content }}</p>
</div>
</template>
<script>
import axios from 'axios'
import querystring from "querystring"
export default {
name: "MyComponents",
data() {
return {
Details: [{
title: "",
content: ""
}]
}
},
mounted() {
axios.get("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php").then(res => {
this.Details = res.data.chengpinDetails[0]
});
axios.post("http://iwenwiki.com/api/blueberrypai/login.php", querystring.stringify({
user_id: "iwen@qq.com",
password: "iwen123",
verification_code: "crfvw"
})).then(res=>{
console.log(res.data)
});
}
}
</script>
<style scoped>
h3 {
color: red;
}
</style>

2、全局引入

引入

13、网络请求的封装

request.js
import axios from "axios"
import * as querystring from "querystring";
const errorHandle = (status, info) => {
switch (status) {
case 400:
console.log("语义有误");
break;
case 401:
console.log("服务器认证失败");
break;
case 403:
console.log("服务器拒绝访问");
break;
case 404:
console.log("地址错误");
break;
case 500:
console.log("服务器遇到意外");
break;
case 502:
console.log("服务器无响应");
break;
default:
console.log(info)
break;
}
}
const instance = axios.create({
//网络请求的公共配置
timeout: 5000
})
//拦截器
//发送数据之前
instance.interceptors.request.use(config => {
if (config.method === "post") {
config.data = querystring.stringify(config.data)
}
//config包含网络请求的所有信息
return config;
}, error => {
return Promise.reject(error)
})
//获取数据之前
instance.interceptors.response.use(
response => {
return response.status === 200 ? Promise.resolve(response) : Promise.reject(response)
}, error => {
const {response} = error;
//错误的处理
errorHandle(response.status, response.info)
}
)
export default instance;
path.js
const base = {
baseUrL: "http://iwenwiki.com",
chengpin: "/api/blueberrypai/getChengpinDetails.php"
}
export default base
index.js
import axios from "../utils/request";
import path from "./path"
const api = {
//成品详情地址
getChengpin() {
return axios.get(path.baseUrL + path.chengpin)
}
}
export default api
调用接口
<template>
<div>
</div>
</template>
<script>
import api from "../api/index"
export default {
name: "MyComponents",
data() {
return {}
},
mounted() {
api.getChengpin().then(res => {
console.log(res.data)
})
}
}
</script>
<style scoped>
h3 {
color: red;
}
</style>
时间:2022-10-29 晚上
14、网络请求跨域解决方案
目前主流的跨域解决方案有两种
1、后台解决cors
2、前台解决proxy
devServer:{
proxy:{
'/api':{
target:'http://iwenwiki.com',//跨域的url
changeOrigin: true
}
}
}


15、vue引入路由
1、安装路由:cnpm install --save vue-router
2、在src创建router文件夹,在创建index.js文件
index.js
import {createRouter, createWebHashHistory} from "vue-router";
import homeView from "@/views/HomeView";
import aboutView from "@/views/AboutView";
//配置信息中需要的页面相关配置
const routes = [
{
path: '/',
component: homeView
},
{
path: '/about',
component: aboutView
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router;


createWebHashHistory和createWebHistory区别
createWebHashHistory

createWebHistory

1、createWebHashHistory
原理:a标签锚点链接
2、createWebHistory
此种方式需要后台配合做重定向,否则会出现404问题
原理: H5 pushState()
16、路由传递参数
1、现在路由链接指定:
网易新闻

2、在index.js 文件
{
path: '/details/:name',
name: 'details',
component: () => import('../views/news/NewsDetailsView')
}


17、路由嵌套
首先我创建了如下几个文件

路由设置
{
path: '/books',
name: 'books',
//重定向
redirect: '/books/info',
component: () => import('../views/BookView'),
children: [
{//二级导航的路径不加/
path: 'us',
component: () => import('../views/books/BookUsView')
},
{
path: 'info',
component: () => import('../views/books/BookInfoView')
}
]
}
BookView.vue
<template>
<div>
<router-link to="/books/info">提示信息</router-link>|
<router-link to="/books/us">一起看书</router-link>
</div>
<router-view/>
</template>
<script>
export default {
name: "BookView"
}
</script>
<style scoped>
</style>
18、Vue状态管理(Vuex)
1、安装Vuex :npm install --save vuex
2、配置Vuex文件
import {createStore} from "vuex";
//vuex核心作用就是帮助我们管理组件之间的状态
export default createStore({
//所有的状态都放在这里(数据)
state:{
counter:0
}
})
3、在主文件中引入Vuex
import store from "@/store";
app.use(store)
4、在组件中读取状态
//读取方式
第一种读取方式: {{ $store.state.counter }}
//第二种读取方式
import {mapState} from "vuex";
computed: {
...mapState(["counter"])
}
//如何直接引入
{{ counter }}

19、Vuex状态管理核心
常用核心包括
State Getter Mutation Action
1、Getter
import {createStore} from "vuex";
//vuex核心作用就是帮助我们管理组件之间的状态
export default createStore({
//所有的状态都放在这里(数据)
state: {
counter: 10
},
getters: {
getCounter(state) {
return state.counter > 0 ? state.counter : "counter数据异常";
}
}
})
//直接调用
<p>{{ $store.getters.getCounter }}</p>
//或者这样调用
<p>{{ getCounter }}</p>
<script>
import {mapGetters} from "vuex";
export default {
name: 'App',
computed: {
...mapGetters(["getCounter"])
}
}
</script>
2、Mutation
import {createStore} from "vuex";
//vuex核心作用就是帮助我们管理组件之间的状态
export default createStore({
//所有的状态都放在这里(数据)
state: {
counter: 10
},
getters: {
getCounter(state) {
return state.counter > 0 ? state.counter : "counter数据异常";
}
},
mutations: {//事件
addCounter(state, num) {
state.counter += num
}
}
})
调用
<button @click="addClickHandle">点击</button>
//第一种调用
<script>
import {mapGetters, mapMutations} from "vuex";
export default {
name: 'App',
computed: {
...mapGetters(["getCounter"])
},
methods:{
addClickHandle(){
//固定调用方式
this.$store.commit("addCounter",15)
}
}
}
</script>
<button @click="addClickHandle">点击</button>
//第二种调用方式
<script>
import {mapGetters, mapMutations} from "vuex";
export default {
name: 'App',
computed: {
...mapGetters(["getCounter"])
},
methods:{
...mapMutations(["addCounter"]),
addClickHandle(){
this.addCounter(20)
}
}
}
</script>
3、Action
概述:Action类似于Mutation,不同在于
1、Action提交的是mutation,而不是直接变更状态
2、Action可以包含任意异步操作
import {createStore} from "vuex";
import axios from "axios";
//vuex核心作用就是帮助我们管理组件之间的状态
export default createStore({
//所有的状态都放在这里(数据)
state: {
counter: 10
},
getters: {
getCounter(state) {
return state.counter > 0 ? state.counter : "counter数据异常";
}
},
mutations: {
addCounter(state, num) {
state.counter += num
}
},
//为异步操作所准备的
actions: {
asyncAddCounter({commit}) {
axios.get("http://iwenwiki.com/api/generator/list.php").then(res => {
//使用方式
commit("addCounter",res.data[0])
})
}
}
})
调用
<button @click="addAsyncClickHandle">异步增加</button>
//第一种调用
<script>
import {mapGetters, mapMutations} from "vuex";
export default {
name: 'App',
computed: {
...mapGetters(["getCounter"])
},
methods: {
...mapMutations(["addCounter"]),
addClickHandle() {
this.addCounter(20)
},
addAsyncClickHandle() {
this.$store.dispatch("asyncAddCounter")
}
}
}
</script>
<button @click="addAsyncClickHandle">异步增加</button>
//第二种调用
<script>
import {mapGetters, mapMutations, mapActions} from "vuex";
export default {
name: 'App',
computed: {
...mapGetters(["getCounter"])
},
methods: {
...mapMutations(["addCounter"]),
...mapActions(["asyncAddCounter"]),
addClickHandle() {
//固定调用方式
this.addCounter(20)
},
addAsyncClickHandle() {
this.asyncAddCounter()
}
}
}
</script>
20、Vue3新特性1
ref 或者 reactive
1、在2.x中通过组件data的方法定义一些当前组件的数据
data(){
return{
name:'hu',
list:[]
}
}
2、在3.x中通过ref或者reactive创建响应式对象
<template>
<div>
<h3>关于页面</h3>
<h4>{{ message }}</h4>
<ul>
<li v-for="(item,index) in names.list" :key="index">{{ item }}</li>
</ul>
<button @click="clickHandle">点击</button>
</div>
</template>
<script>
import {ref, reactive} from "vue";
export default {
name: "AboutView",
//组合式API
setup() {
//ref
const message = ref("我是消息")
//reactive
const names = reactive({
list: ["老大", "老二", "老三"]
})
function clickHandle() {
console.log("点击了")
}
return {
message,
names,
clickHandle
}
}
}
</script>
<style scoped>
</style>
时间:2022-10-30 晚上
21、Vue3新特性2
在setup中使用生命周期函数
<script>
import {onMounted} from "vue";
export default {
name: "AboutView",
//组合式API
setup() {
//可以声明多个生命周期函数,在2.x版本每个生命周期函数只能声明一个
onMounted(() => {
console.log("onMounted生命周期1")
})
onMounted(() => {
console.log("onMounted生命周期2")
})
}
}
</script>
Provide 和inject 可以实现嵌套组件间的数据传递
注:这两个函数只能在setup中使用
1、父组件中使用Provide()向下传递数据
2、子组件使用inject() 获取数据
3、传递数据由上至下
//父组件
<script>
import {provide} from "vue";
export default {
setup(){
provide("msg","我是消息")
}
}
</script>
//子组件
<script>
import {inject} from "vue";
const message = inject("msg")
return {
message
}
</script>
fragment
1、在2.x版本组件只能有一个根节点
2、载3.x版本组件根节点个数没有限制
3、但推荐只能有一个根节点
<template>
//多个根节点,但实际还是推荐使用一个根节点
<div>
</div>
<p></p>
</template>
22、Vue3加载Element-plus
安装:cnpm install element-plus --save
1、完整引入 会把整个文件都打包
//导入
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
然后直接使用即可
<template>
<el-row class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>
</template>
2、按需导入
1、首先安装两款插件
cnpm install -D unplugin-vue-components unplugin-auto-import
安装后配置vue.config.js 即可使用
const {defineConfig} = require('@vue/cli-service')
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const {ElementPlusResolver} = require('unplugin-vue-components/resolvers')
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
]
}
})
23、Vue3加载Element-plus的字体图标
1、安装字体图标:cnpm install @element-plus/icons-vue
2、全局注册
//在src下创建plugins文件夹里再创建icons.js
import * as components from "@element-plus/icons-vue"
export default {
install: (app) => {
for (const key in components) {
const componentConfig = components[key]
app.component(componentConfig.name, componentConfig)
}
}
};
3、在main.js引入
import elementIcon from "./plugins/icons"
app.use(elementIcon)
最后引入即可
<el-icon :size="100" color="red"><Unlock /></el-icon>
时间:2022-10-31 午休

浙公网安备 33010602011771号