51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Vue学习笔记

Vue开发前准备

需要去官网Home | Vue CLI (vuejs.org)安装cli,cli是官方的vue开发环境。

安装成功后,可以通过命令来检测是否安装成功

vue --version

创建项目命令(名字要求全小写)

vue create my-project

选择方式(初学):

vue创建选择选项

然后跳出选择版本的按钮,选择3.x版本即可。

然后就可以进行选择配置文件放在哪里,默认选择第一个即可。

配置文件放在哪里

运行操作

npm run serve

项目打包:需要前往需要打包的文件夹下面的终端

命令
切换目录
cd 目录地址
npm run build

解决打包后的vue项目白屏

vue.config.js文件中添加以下代码即可

// vue.config.js
module.exports = {
    publicPath: './',
}

模板语法

数据绑定语法

通过{}绑定数据,其中data()是一个方法,返回对应的数据值

<template>
  <div class="hello">
    <h1>HelloWorld</h1>
    <h3>{{ message }}</h3>
  </div>
</template>
`<script>
export default {
name: 'HelloWorld',
data() {
return {
message: "测试"
}
}
}
</script>`

原始HTML

双大括号会将数据解释为普通文本,而非HTML代码,为了输出真正的HTML,你需要使用指令v-html指令

<p>
    Using mustaches:{{rawHtml}}
</p>
<p>
    Using v-html directive:<span v-html="rawHtml"></span>
</p>
data(){
    return{
        rawHtml:"<a href='https://www.fish9.cn'>吃猫的鱼</a>"
    }
}

完整示例代码:

<template>
  <div class="hello">
    <h1>HelloWorld</h1>
    <h3>{{ message }}</h3>
    <div>{{ rawHtml }}</div>        //输出文本
    <div v-html="rawHtml"></div>    //输出html代码
  </div>
</template>
`<script>
export default {
name: 'HelloWorld',
data() {
return {
message: "测试",
rawHtml: "<a href='https://www.fish9.cn'>吃猫的鱼</a>"
}
}
}
</script>`

运行截图:

运行截图

属性Attribute

Mustache语法不能再HTML属性中使用,然而可以使用v-bind指令

当我们标签中的属性需要发生变化的时候,可以通过v-bing对其进行动态修改。

v-bind 可以简写成 :

<div v-bind:id="dynamicId"></div>    完整写
<div :id="dynamicId"></div>            简写
`<script>
export default {
name: 'HelloWorld',
data() {
return {
dynamicId: 1001
}
}
}
</script>`

使用JavaScript表达式

Vue.js提供完全的js表达式,{{ }}里面可以进行js的相关符号式的操作。

表达式会再当前活动实例的数据作用域下作为JavaScript被解析。有个限制就是,每个绑定都只能包含单个表达式。

条件渲染

指令用于条件性地渲染一块内容,这块内容只能在指令的表达式返回true才会被渲染

    <p v-if="flag">我是吃猫的鱼</p>
<script>
export default {
  data() {
    return {
      flag: true
    }
  }
}
</script>

v-else:

    <!-- 条件渲染 -->
    <p v-if="flag">我是吃猫的鱼1</p>
    <p v-else="flag">我是吃猫的鱼2</p>
<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      flag: false
    }
  }
}
</script>

上面代码显示的是我是吃猫的鱼2

另一个用于条件性展示元素的是v-show指令,使用方式

<h1 v-show="flag">Hello!</h1>

v-if和v-show的区别

v-if是"真正"的条件渲染,因为它会确保在切换过程中,条件块内的时间监听器和子组件适当地被销毁和重建。

v-if 也是惰性的,如果在初始渲染时条件为假,则什么也不做知道条件第一次变为真时,才会开始渲染条件快。

相比之下,v-show就简单得多-不管初始条件是什么,元素总是会被渲染,并且只是简单地基于css进行切换。

一般来说,v-if 有更高的切换开销,而v-show有更高的初始渲染开销,因此,如果需要非常频繁地切换,则使用v-show较好,如果在运行时条件很少改变,则使用v-if较好。

列表渲染

用v-for把一个数组映射位一组元素。

我们可以用v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items 形式的特殊语法,其中items是源数据数组,而item则是被迭代的数组元素的别名。

    <ul>
      <li v-for="item in items">{{ item.message }}</li>
    </ul>
data() {
    return {
      items: [{ message: 'Foo' }, { message: 'Bar' }]
    }
  }

维护状态

当Vue正在更新使用v-for渲染的元素列表时,它默认使用"就地更新"的策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。

为了给Vue一个提示,以便它能跟踪每个结点的身份,从而重用和冲i性能排序现有元素,你需要为每项提供一个唯一的keyattribute:

<div v-for="(item,index) in items" :key="item.id|index">
    <!--内容-->
</div>

事件处理

可以使用v-on指令(通常缩写为@符号)来监听DOM事件,并在触发事件时执行一些JavaScript,用法为v-on:click="mathodName"或使用快捷方式@click="methodName"

<button @click="counter+=1">
    Add 1
</button>
data(){
    return{
        counter:0
    }
}

事件处理方法

很多事件处理逻辑会更加复杂,所以直接把JavaScript代码写在v-on指令中是不可行的,因此v-on还可以接受一个需要调用的方法名称

<button @click="greet">
    Greet
</button>
methods:{
    greet(event){
        //'event'是原生DOM event
        if(event){
            alert(event.target.tagName)
        }
    }
}

实例:

    <!-- 事件处理 -->
    <button @click="counter += 1">点击{{ counter }}</button>
    <button @click="clickHandle">控制台输出"哈哈哈"</button>
    <p @click="change">{{ message }}</p><!--点击撤回-->
data() {
    return {
      message: "测试",
      counter: 1
    }
  },
  methods: {
    clickHandle() {
      console.log("哈哈哈");
    },
    change() {
      //事件中,读取data中的属性,需要通过this.属性
      this.message = "消息消失了";
    }
  }

内联处理器中的方法

相当于"事件传递参数"

<button @click="say('hi')">Say hi</button>
<button @click="say('what')">Say what</button>
methods:{
    say(message){
        alert(message)
    }
}

表单输入绑定

可以使用v-model指令在表单inputtextarea<select> 元素上创建双向数据绑定,它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model本质上不过是语法糖。它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。

<input v-model="message" placeholdere="edit me"/>
<p>
    Message is :{{message}}
</p>
data(){
    return {
        message:""
    }
}

修饰符

.lazy

在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步。你可以通过lazy修饰符,从而转为在change事件之后进行同步

<input v-model.lazy="message"/>
<p>
    Message is:{{message}}
</p>
data(){
    return {
        message:""
    }
}

trim

如果要自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符

<input v-model.trim="message"/>
data(){
    return {
        message:""
    }
}

组件基础

单文件组件

Vue单文件组件(又名 *.vue文件,缩写为SFC)是一种特殊的文件格式,它允许将Vue组件的模板、逻辑与样式封装在单个文件中。

加载组件

第一步 :引入组件 import MyComponentVue from'./components/MyComponent.vue'

第二步:挂载组件compnents:{MyCDomponentVue}

第三步:显示组件<my-componentVue/>

示例代码

MyComponents中代码

<template>
    <h3>我是单文件组件</h3>
</template>
`<script>
export default {
name: "MyComponent"
}
</script>
<!-- scoped:如果在style中添加此属性,就代表着,当前样式,只在当前组件中生效-->
<style scoped>
h3 {
color: red;
}
</style>`

App.vue中代码

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App" />
  <MyComponents />
  <my-components />
</template>

\<script\>


import MyComponents from './components/MyComponents.vue';
import HelloWorld from './components/HelloWorld.vue'

`export default {
name: 'App',
components: {
HelloWorld,
MyComponents
}
}
</script>`

在App.vue中

组件的组织

通常一个应用会以一棵嵌套的组件树的形式来组织

props组件交互

组件与组件之间进行交互。

App.vue可以向组件传递参数,例如

<MyComponents :title="title" :age="age" :name="name"/>

然后在组件中需要接受传过来的参数,接过来需要给参数赋值类型和默认值。

<script>
export default {
    name: "MyComponents",
    props: {
        title: {
            type: String,
            default: ""
        },
        age: {
            type: Number,
            default: 0
        },
        name: {
            type: String,
            //数组和对象必须使用函数返回
            default: function () {
                return []
            }
        }
    }
}
</script>

完整示例代码:

App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <MyComponents :title="title" :age="age" :name="name"/>
</template>

\<script\>


import MyComponents from './components/MyComponents.vue';


export default {
name: 'App',
data() {
return {
title: "我是一个标题",
age: 20,
name:\["aa","bb","cc","dd"\]
}
},
components: {
MyComponents
}
}
\</script\>

`<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
`

MyComponents.vue

<template>
    <h3>我是单文件组件</h3>
    <h2>{{ title }}</h2>
    <p>{{ age }}</p>
    <ul>
        <li v-for="item, index in name" :key="index">{{ item }}</li>
    </ul>
</template>
`<script>
export default {
name: "MyComponents",
props: {
title: {
type: String,
default: ""
},
age: {
type: Number,
default: 0
},
name: {
type: String,
//数组和对象必须使用函数返回
default: function () {
return []
}
}
}
}
</script>
<!-- scoped:如果在style中添加此属性,就代表着,当前样式,只在当前组件中生效-->
<style scoped>
h3 {
color: red;
}
</style>`

自定义事件组件交互

自定义事件可以在组件中反向传递数据,prop可以将数据从父组件传递到子组件,想要反向操作,可以使用自定义事件实现。

可以通过在组件中自定义方法,向app.vue中传递.

在自定义方法中使用

this.$emit("onEvent", this.message)

然后再app,vue中接收这个方法

 <MyComponents @onEvent="getDataHandle" />
methods: {
    getDataHandle(data) {
      this.message = data
    }
  }

完整示例代码

MyComponents.vue

<template>
    <h3>自定义事件传递数据</h3>
    <button @click="sendClickHandle">点我传递</button>
</template>
`<script>
export default {
name: "MyComponents",
data() {
return {
message: "我是MyComponents数据"
}
},
methods: {
sendClickHandle() {
//参数一是字符串,理论上是随意的,但是需要具有意义
//参数二是传递的数据
this.$emit("onEvent", this.message)
}
}
}
</script>
<!-- scoped:如果在style中添加此属性,就代表着,当前样式,只在当前组件中生效-->
<style scoped>
h3 {
color: red;
}
</style>`

App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <MyComponents @onEvent="getDataHandle" />

\<h1\>{{ message }}\</h1\>
\</template\>


\<script\>


import MyComponents from './components/MyComponents.vue';


export default {
name: 'App',
data() {
return {
message: ""
}
},
components: {
MyComponents
},
methods: {
getDataHandle(data) {
this.message = data
}
}
}
\</script\>

`<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>`

组件生命周期

分类

创建时:beforeCreatecreated

渲染时:beforeMountmounted (网络请求一般放到这里)

更新时: beforeUpdateupdated

卸载时:beforeUnmountunmounted

vue引入第三方扩展

swiper中vue引入官方文档 https://swiperjs.com/vue/

安装指定版本:npm instal --save swiper@8.1.6

Axios发起网络请求

Axios 是一个基于promise的网络请求库

安装

Axios的应用是需要单独安装的npm install --save axios

引入

组件中引入:import axios from "axios"

全局引用:

import axios from "axios"

const app = createApp(App);
app.config.globalProperties.$axios = axios
app.mount("#app")

`//在组件中调用
this.$axios`

网络请求基本示例

get请求(post请求同理)

axios({
      method: "get",
      url: "http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php",
      data:{
          userid:"123",
          psw:"123456"
      }
    }).then(res => {
      this.chengpin = res.data.chengpinDetails[0]
    })

建议放在组件渲染完成后。

完整示例代码

<template>
  <div class="hello">
    <p>{{ chengpin.title }}</p>
  </div>
</template>

\<script\>
import axios from "axios"

`export default {
name: 'HelloWorld',
data() {
return {
chengpin: {}
}
},
mounted() {   //组件渲染完成
axios({
method: "get",
url: "http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php"
}).then(res => {
this.chengpin = res.data.chengpinDetails[0]
})
}
}
</script>`

注意

post请求参数是需要额外处理的

安装依赖 npm install --save querystring

转换参数格式:qs.stringify({})

简单使用

axios.get("url")
.then(res =>{
    console.log(res.data);
})
`axios.post("url",stringify({
user:"",
psw:""
})).then(res =>{
console.log(res.data);
})`

Axios网络请求封装

在目录utils下新建request.js用来封装Axios网络请求

import axios from "axios";
import { resolve4 } from "dns";
import querystring from "querystring"

const errqrHandle = (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;`

封装可以新建一个目录api,然后将所有api请求都放在这个文件夹。

path.js //存放路径

const base = {
    baseUrl:"主要域名,如:https://www.fish9.cn",
    chengpin:"/api/chengpin"
}
`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`

组件中使用

<script>
import api from "../api/index"

    export default{
        name:'HelloWorld',
        mounted(){
            api.getChengpin().then(res =&gt;{
                console.log(res.data);
            })
        }
    }



`</script>`

页面关系管理

在vue中,我们可以通过vue-router路由管理页面之间的关系

Vue Router 是Vue.js的官方路由,它与Vue.js深度集成,让用Vue.js构建单页应用变得轻而易举。

在Vue中引入路由

第一步:安装路由 npm install --save vue-router

第二步:配置独立的路由文件

新建router目录,新建index.js

import { createRouter, createWebHashHistory } from "vue-router"
import HomeView from "../views/HomeView"
//配置信息中需要页面的相关配置
const routes = [
    {
        path: "/",
        name:"home",
        component: HomeView
    },
    {
        path: "/about",
        name:"about",
        //这是异步加载方式
        component: () => import("../views/AboutView.vue")
    }
]
const router = createRouter({
    history: createWebHashHistory(),
    routes
})
export default router;

新建views文件夹两个文件HomeView.vue ,AboutView.vue

AboutView.vue

<template>
    <h3>关于页面</h3>
</template>

HomeView.vue

<template>
    <h3>首页</h3>
</template>

然后在main.js引入import router from "./router",然后再改成:

createApp(App).use(router).mount('#app')

App.vue

<template>
  <!-- 路由的显示入口 -->
  <router-view></router-view>
  <router-link to="/">首页</router-link>
  <router-link to="/about">关于</router-link>
</template>

\<script\>


export default {
name: 'App'
}
\</script\>

`<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>`

路由传递参数

第一步:在路由配置中指定参数的key

    {
        path: "/newsdetails/:name",
        name: "newsdetails",
        component: () => import("../views/NewsDetailView.vue")
    }

第二步:在跳转过程中携带参数

<template>
    <ul>
        <li><router-link to="/newsdetails/百度">百度新闻</router-link></li>
        <li><router-link to="/newsdetails/网易">网易新闻</router-link></li>
        <li><router-link to="/newsdetails/头条">头条新闻</router-link></li>
    </ul>
</template>

第三步:在详情页面读取路由携带的参数

<template>
    <h3>{{ $route.params.name }}新闻详情</h3>
</template>

赞(0)
未经允许不得转载:工具盒子 » Vue学习笔记