首页 > 其他分享 >VUE学习笔记

VUE学习笔记

时间:2022-11-07 15:14:30浏览次数:72  
标签:npm count VUE default 笔记 学习 vue 组件 import

VUE配置

切换国内下载源

npm config set registry http://registry.npm.taobao.org

安装vue

npm install vue -g

安装VUE-CLI

快速构建vue项目的工具

2.X版本
npm install vue-cli -g
3.X版本
如果以及安装过2.X或3.X版本,需要先卸载
卸载2.X:npm uninstall vue-cli -g
卸载3.X:npm uninstall @vue/cli -g

安装3.X版本
npm install @vue/cli –g

安装webpack

npm install webpack -g

安装vue-router

npm install vue-router -g

常用命令

源相关
1.查看镜像源
npm get registry
2.切换官方源
npm config set registry http://www.npmjs.org
3.切换淘宝源
npm config set registry http://registry.npm.taobao.org
其他
# 查看npm版本
npm -v

# 查看当前项目的依赖
npm ls

# 查看 npm 的配置
npm config list -l

# 安装模块
npm install (简写:npm i) 模块名 (当前应用安装至package.json的dependencies中)
npm install 模块名 -g (全局安装)
npm i 模块名 --save-prod(简写:-P) (生产环境安装) 
npm i 模块名 --save-dev(简写:-D) (开发环境安装至package.json的devDependencies)

# 更新模块
npm update 模块名
...(同安装模块)

# 卸载模块
npm uninstall 模块名
...(同安装模块)

快速构建vue项目

输入命令构建名为vue-demo的项目

vue create vue-demo

剩下的根据需求自己选择即可

各文件作用

node_modules

里面放置所有的npm下载的依赖

public

存放项目的静态资源(webpack打包时会直接放入dist文件夹内)

src

开发的应用的包

assets

存放src内组件要使用的静态资源(webpack打包时会被当成一个模块打包到js文件夹里)

components

放置非路由组件(全局组件),公共组件

App.vue

根(主)组件

main.js

主项目的入口文件,最先执行,主要作用是初始化vue实例,并引入所需要的插件

.gitignore

配置git提交时忽略上传的文件

babel.config.js

项目的配置文件,一般用于兼容es5和es6语法

package-lock.json

可以删除,是一个缓存文件

package.json

记录vue项目的相关信息

veu3完整的组件

<template>
  <div class="hello">
    <h1>{{ message }}</h1>
    <text v-text="counts"></text>
    <br>
    <input type="button" @click="add" value="按钮">
  </div>
</template>

<script>
// import ...导入子组件
export default {	// 导出组件
  name: 'HelloWorld',	// 组件名
  data() {	// 存放数据
      return {
          message: "你好哇!",
          counts: 1
      }
  },
  methods: {  // 存放方法函数
    add() {
      this.counts +=  1
    }
  },
   components: {	// 导入的组件名
    // 组件名
  }
}
</script>
// scoped表示当前样式只在当前组件中生效
<style scoped>
</style>

指令

v-text

{{message}}相比会替换标签中的所有文本内容

v-html

文本中的html标签会被解析出来

v-on

事件绑定,形如v-on:click@click,两者是等价的

v-bing

属性绑定,v-bind:title="message"可以简写为:title="message"

v-show

设置元素是否隐藏,v-show="true"显示,v-show="false"隐藏,里面是一个bool值,可以自己设置

v-if、v-else、v-else-if

条件判断

v-ifv-show的区别是:前者会直接销毁不符合条件的内容(组件)或重建布拉布拉,而后者只是隐藏起来不显示,内容会一直渲染。对于频繁需要切换的场景,应使用后者

v-for

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

唯一的key记录每个数据的下标、用于跟踪判断列表或数组中的新旧数据,然后渲染新的数据,旧的数据不需要再次渲染,提高性能

v-model

数据双向绑定,修改表单的值,属性的值会同步修改,反之亦然

v-model.lazy

当用户输入的数据失去焦点时才会同步修改

v-model.trim

会自动过滤输入首尾的空格

组件

加载组件
  1. 引入组件:import ...
  2. 挂载组件:components: {...}
  3. 显示组件

props组件间参数传递

官方文档

proprs 参数的传递应为单向的父传子

父组件App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <propsTest :titles="titles" :age="age" :arr="arr"/>
</template>

<script>
import propsTest from "./components/propsTest.vue"

export default {
  name: 'App',
  components: {
    propsTest
  },
  data() {
    return {
      titles: "这是一个标题",
      age: 20,
      arr: [1, 2, 3]
    }
  }
}
</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>

子组件propsTest.vue
<template>
    <h1>{{ titles }}</h1>
    <p>age = {{ age }}</p> 
    <ul>
        <li v-for="item in arr" :key="index">{{ item }}</li>
    </ul>
</template>

<script>
export default {
    name: 'propsTest',
    props: {
        titles: {
            type: String,   //参数校验
            // default: "", //默认值,如果未传递参数就用默认值替代
            required: true   //设置当前属性必须传值
        },
        age: {
            type: Number,
            default: 0
        },
        // 数组和对象的默认值应用工厂函数返回
        arr: {
            type: Array,
            default() {
                return { }
            }
        }
    },
    data() {
        return  {

        }
    }
}
</script>

emit组件参数传递

emit可以使得子组件参数传递给父组件

父组件App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <p>{{ message }}</p>
  <myComponentVue @onEvent="getDataHandle"/>  // 函数接受传过来的数据
</template>

<script>
import myComponentVue from './components/myComponent.vue';

export default {
  name: 'App',
  components: {
    myComponentVue
  },
  data() {
    return {
      message: ""
    }
  },
  methods: {
    getDataHandle(data) {
      this.message = data;  //获取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>

子组件myComponent.vue
<template>
    <button @click="sendClickHandle">点我试试</button>
</template>

<script>
export default {
    name: 'myComponent',
    data() {
        return  {
            message: "我是components的参数!"
        }
    },
    methods: {
        sendClickHandle() {
            // 第一个参数是一个字符串,应与父组件中的@..=""对应
            // 第二个参数是要传递的数据
            this.$emit("onEvent", this.message)
        }
    }
}
</script>

组件生命周期

创建时:beforeCreatecreated

渲染时:beforeMountmounted

更新时:beforeUpdateupdated

卸载时:beforeUnmountunmounted

注:vue3增加了setup,其运行在beforeCreatecreated之前

Axios

官方文档

网络请求

首先导入axios,将axios放入main.js中导入全局

main.js

import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import axios from "axios"

const app = createApp(App)
app.config.globalProperties.$axios = axios  // 将axios挂载到全局

app.mount('#app')

axiosTest.vue

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

<script>
import querystring from "querystring"

export default {
    name: "axiosTest",
    data() {
        return {
            ans: {}
        }
    },
    mounted() {
        // this.$axios({
        //     method: "post",
        //     url: "http://iwenwiki.com/api/blueberrypai/login.php",
        //     data: querystring.stringify({
        //         user_id: "[email protected]",
        //         password: "iwen123",
        //         verification_code: "crfvw"
        //     })
        // }).then(res => {
        //     console.log(res.data)
        // })
        // 简洁写法
        this.$axios.get("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php")
        .then(res => {
                this.ans = res.data.chengpinDetails[0],
                console.log(res.data);
            })
        
        this.$axios.post("http://iwenwiki.com/api/blueberrypai/login.php", querystring.stringify({
            user_id: "[email protected]",
            password: "iwen123",
            verification_code: "crfvw"
        })).then(res => {
            console.log(res.data);
        })
    }
}
</script>

请求封装

src文件下创建utils文件,再在里面创建request.js文件,里面编写请求响应的处理

import axios from "axios";
import 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 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)
        }
        return config;
    },
    error => {
        return Promise.reject(error);
    }
)

instance.interceptors.response.use(
    response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response),
    error => {
        errorHandle(error.status, error.info);
    }
)

export default instance;    // 抛出对象

src文件夹下创建名为api的文件,再在里面创建两个js文件

path.js

const base = {
    baseUrl: "http://iwenwiki.com",
    chengpinUrl: "/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.chengpinUrl);
    }
}

export default api;

再在组件axiosTest.vue内调用api/index.js

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

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

export default {
    name: "axiosTest",
    data() {
        return {
            ans: {}
        }
    },
    mounted() {
        api.getChengpin().then(res => {
            this.ans = res.data.chengpinDetails[0],
            console.log(res.data);
        })
    }
}
</script>

跨域问题

什么是跨域

前端调用后端的接口时,出现协议、域名、端口错误的情况,叫做跨域

前端解决方案

配置代理

vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    proxy: {
      '/api': {
        target: 'http://iwenwiki.com',  // 放置跨域的域名地址
        changeOrifin: true
      }
    }
  }
})

axiosTest.vue

<script>
import axios from "axios";

export default {
    name: "axiosTest",

    mounted() {
        axios.get("/api/FingerUnion/list.php")
        .then(res => {
            console.log(res.data);
        })
    }
}
</script>

最后重启,才能拿到数据

Vue-router

用于控制页面跳转关系

安装路由

npm i vue-router

创建界面

src包下创建一个views文件夹,在文件夹内再创建两个vue组件

HomeVue.vue

<template>
    <h1>主页</h1>
</template>

AboutVue.vue

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

配置路由

src包下创建router文件夹,在文件夹下创建index.js文件

index.js

import { createRouter, createWebHashHistory } from "vue-router"
import HomeVue from "../views/HomeVue"

const routes = [
    { path: '/', component: HomeVue },
    // 除了首页以外采用异步加载,不点击页面就不加载
    { path: '/about', component: () => import("../views/AboutVue") },
]

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

export default router;

main.js加入两行,引入路由

import router from './router'

app.use(router)

App.vue

<template>
  <RouterLink to="/">首页 | </RouterLink>
  <RouterLink to="/about">关于</RouterLink>
  <RouterView></RouterView>
</template>

<script>

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

参数传递

views包下新建NewsView.vueNewsDetails.vue

NewsView.vue

<template>
    <ul>
        <li>
            <RouterLink to="/news/百度">百度新闻</RouterLink>
            <RouterLink to="/news/网易">网易新闻</RouterLink>
            <RouterLink to="/news/头条">头条新闻</RouterLink>
        </li>
    </ul>
</template>

NewsDetails.vue

<template>
    <!-- $route.params.name获取参数 -->
    <h2>{{ $route.params.name }}新闻详情</h2>
</template>

配置路由

index.js

import { createRouter, createWebHashHistory } from "vue-router"
import HomeVue from "../views/HomeVue"

const routes = [
    { path: '/', component: HomeVue },
    // 除了首页以外采用异步加载,不点击页面就不加载
    { path: '/about', component: () => import("../views/AboutVue") },
    { path: '/news', component: () => import("../views/NewsView")},
    { path: '/news/:name', component: () => import("../views/NewsDetails")}
]

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

export default router;

App.vue

<template>
  <nav>
    <RouterLink to="/">首页|</RouterLink>
    <RouterLink to="/about">关于|</RouterLink>
    <RouterLink to="/news">新闻</RouterLink>
  </nav>
  <RouterView></RouterView>
</template>

<script>

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

嵌套路由

src/views下新建文件夹aboutSub,里面放AboutVue.vue页面的二级嵌套页面:AboutUs.vueAboutInfo.vue

AboutUs.vue

<template>
    <h2>关于我们</h2>
</template>

AboutInfo.vue

<template>
    <h2>关于信息</h2>
</template>

AboutVue.vue

<template>
    <RouterLink to="/about/us">关于我们</RouterLink> |
    <RouterLink to="/about/info">关于信息</RouterLink>
    <h1>关于页面</h1>
    <RouterView></RouterView>
</template>

index.js内配置嵌套路由

import { createRouter, createWebHashHistory } from "vue-router"
import HomeVue from "../views/HomeVue"

const routes = [
    { path: '/', component: HomeVue },
    // 除了首页以外采用异步加载,不点击页面就不加载
    { path: '/about', component: () => import("../views/AboutVue"),
    redirect: "/about/us",  // 重定向,每次点击到/about页面默认先加载/about/us
    children: [
        {
            path: 'us',
            component: () => import("../views/aboutSub/AboutUs")
        },
        {
            path: 'info',
            component: () => import("../views/aboutSub/AboutInfo")
        }
    ]},
    { path: '/news', component: () => import("../views/NewsView")},
    { path: '/news/:name', component: () => import("../views/NewsDetails")}
]

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

export default router;

Vuex

官方文档

用于管理组件间的状态

state

里面存放数据

安装vuex

npm i vuex

src下创建store文件夹,再在里面创建index.js

import { createStore } from 'vuex'

export default createStore ({
    state: {
        count: 20
    }
})

src/main.js内新增两行

import store from './store'

app.use(store)

两种读取vuex中数据的方法

App.vue

<template>
  <!-- 第一种 -->
  <p>count = {{ $store.state.count }}</p>
  <p>count = {{ count }}</p>
</template>

<script>
import { mapState } from 'vuex';


export default {
  name: 'App',
  // 第二种
  computed: {
    ...mapState(['count'])
  }
}
</script>

getters

用于读取state中的数据

index.js

export default createStore ({
    state: {
        count: 20
    },
    getters: {
        getCount(state) {
            return state.count > 0 ? state.count : "数据异常"
        }
    }
})

App.vue

<template>
  <!-- 第一种 -->
  <p>count = {{ $store.state.count }}</p>
  <p>count = {{ getCount }}</p>
</template>

<script>
import { mapGetters, mapState } from 'vuex';

export default {
  name: 'App',
  // 第二种
  computed: {
    ...mapGetters(['getCount'])
  }
</script>

mutations

同步修改state的值

index.js

import { createStore } from 'vuex'

export default createStore ({
    state: {
        count: 20
    },
    getters: {
        getCount(state) {
            return state.count > 0 ? state.count : "数据异常"
        }
    },
    mutations: {
        addCount(state, num) {
            state.count += num
        }
    }
})

App.vue

<template>
  <!-- 第一种 -->
  <p>count = {{ $store.state.count }}</p>
  <p>count = {{ getCount }}</p>
  <button @click="addClickHandle">增加</button>
</template>

<script>
import { mapGetters, mapMutations } from 'vuex';

export default {
  name: 'App',
  // 第二种
  computed: {
    ...mapGetters(['getCount'])
  },
  methods: {
      ...mapMutations(['addCount']),
    addClickHandle() {
      // 调用mutations内的方法
      // this.$store.commit("addCount", 10)
      this.addCount(10);
    }
  }
}
</script>

action

action可以同步操作和异步操作,mutations只能同步操作

index.js

import axios from 'axios'
import { createStore } from 'vuex'

export default createStore ({
    state: {
        count: 20
    },
    getters: {
        getCount(state) {
            return state.count > 0 ? state.count : "数据异常"
        }
    },
    mutations: {
        addCount(state, num) {
            state.count += num
        }
    },
    actions: {
        asyncAddCount({ commit }) {
            axios.get("http://iwenwiki.com/api/generator/list.php")
            .then(res => {
                commit("addCount", res.data[0])
            })
        }
    }
})

App.vue

<template>
  <!-- 第一种 -->
  <p>count = {{ $store.state.count }}</p>
  <p>count = {{ getCount }}</p>
  <button @click="addClickHandle">增加</button>
  <button @click="addAsyncClickHandle">异步增加</button>
</template>

<script>
import { mapActions, mapGetters, mapMutations } from 'vuex';

export default {
  name: 'App',
  // 第二种
  computed: {
    ...mapGetters(['getCount'])
  },
  methods: {
    ...mapMutations(['addCount']),
    ...mapActions(['asyncAddCount']),
    addClickHandle() {
      // 调用mutations内的方法
      // this.$store.commit("addCount", 10),
      this.addCount(20);
    },
    addAsyncClickHandle() {
      // this.$store.dispatch("asyncAddCount"),
      this.asyncAddCount();
    }
  }
}
</script>

标签:npm,count,VUE,default,笔记,学习,vue,组件,import
From: https://www.cnblogs.com/RCLiu/p/16865995.html

相关文章

  • django-environ学习
    官方说明:https://django-environ.readthedocs.io/en/latest/index.htmlinstallpipinstalldjango-environquickstartimportenvironimportosenv=environ.Env(......
  • vue-监视属性
    文本转自于:https://blog.csdn.net/weixin_46376652/article/details/125689307作者:frontEndSmallWhite 一、两种监视方式1、watch属性直接监视如果刚开始确定监视对......
  • 课程学习进度
    我的课程个人中心里面展示我的课程界面效果src/components/user/Course.vue,代码:<template><divclass="right-containerl"><divclass="right-title">......
  • VSCode使用笔记
    官网下载下载慢解决方式点击下载获取下载地址这个时候直接复制vscode.cdn.azure.cn替换地址上面的下载......
  • 人工智能、机器学习和深度学习有什么区别?
    在大数据时代,人们往往被人工智能(AI)、机器学习(ML)、深度学习(DL)这一些热词轰炸。但不少人对这些词汇的含义以及之间的关系比较模糊,甚至混为一谈。本章作为人工智能的第一章节......
  • 谈谈vue面试那些题
    Vue组件data为什么必须是个函数?根实例对象data可以是对象也可以是函数(根实例是单例),不会产生数据污染情况组件实例对象data必须为函数一个组件被复用多次的话,也就会创......
  • 如何准备好一场vue面试
    对SSR的理解SSR也就是服务端渲染,也就是将Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端SSR的优势:更好的SEO首屏加载速度更快SSR的......
  • 深度学习基础课:全连接层的梯度检查
    大家好~我开设了“深度学习基础班”的线上课程,带领同学从0开始学习全连接和卷积神经网络,进行数学推导,并且实现可以运行的Demo程序线上课程资料:本节课录像回放1加QQ群,获......
  • 前端vue2项目引入第三方js文件或者远程js文件并执行相应方法
    啥也不多说,直接上结论新建一个目录和文件例如:./tools/load.js //引入远程js,加载完成后执行相应方法functionloadJs(src){returnnewPromise((resolve,reject)=......
  • vue面试之Composition-API响应式包装对象原理
    本文主要分以下两个部分对CompositionAPI的原理进行解读:reactiveAPI原理refAPI原理reactiveAPI原理打开源码可以找到reactive的入口,在composition-api/src/......