Vue基础

Vue基础学习网站链接
从入门到起飞1
Vue如何使用与vue常见问题

ES6小基础

箭头字符串

var name = "成哥";
var age = 18;

var str = `姓名:${name},年龄:${age}`;
//相当于
// str = "姓名:" + name + ",年龄:" + age;
console.log(str);

速写方法

var obj = {
  name: "张三",
  sayHello() {
    console.log(this.name);
  },
};
obj.sayHello();

速写属性

var name = "abc";
var age = 13;

var obj = {
  name,
  age,
};

console.log(obj);

在这里插入图片描述

基础

基础语句


<body>
    <div id="app">

    </div>

    <script>
        new Vue({
            el: "#app", //app为前面div区块的id的值,通过"#"号绑定
            //data区域定义属性的值
            data: {
                shuzhu: ""
            },
            //methods区域里面定义自己所写的函数
            methods: {
                //自定义了一个函数,名称为details
                details: function() {
                    //调用该函数的时候,会返回下面的值
                    return;
                }
            },
            //下面是过滤器
            filters: {
                //自定义过滤器的处理函数
                capitalize: function(value) {

                    //返回处理后的字符串      
                    return;
                }
            }
        })
    </script>
</body>

vue之修饰符
计算属性与方法的区别:
1.计算属性是基于他们的依赖进行缓存的
2.方法不存在缓存
侦听器
数据一旦发生变化就通知侦听器所绑定的方法

1.侦听器的应用场景:
验证用户名是否可用(用户名是否已经存在)(注册账号)

数据变化时执行异步或开销较大的操作
只要数据发生变化,方法就会马上变化


    <div id="app">
        <span>用户名:</span>
        <input type="text" v-model.lazy='uname'>
    </div>
    <script>
        /*
                     侦听器
                    1.采用侦听器侦听用户名的变化
                    2.调用后天接口进行验证
                    3.根据验证的结果调整提示信息
                */
        new Vue({
            el: '#app',
            data: {
                uname: '',
                tip: ''
            },
            methods: {
                checkName: function(uname) {
                    //调用接口,但是可以使用定时的任务的方式模拟接口调用
                    var that = this;
                    setTimeout(function() {
                        //模拟接口调用
                        if (uname == 'admin') {
                            that.tip = '用户名已经存在,请更换一个'
                        } else {
                            that.tip = '用户名可以使用'
                        }
                    }, 2000)
                }
            },
            watch: {
                uname: function(val) { //定义的名字要跟你要监听的量的名字一样,只要定义的发生变化,val就会发生变化
                    //val表示变化之后的值
                    //调用后台接口验证用户名的合法性
                    this.checkName(val);
                    //修改提示信息
                    this.tip = '正在验证...';
                }
            },
        })
    </script>
  • 过滤器
    过滤器的作用:
    格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等
  • 自定义过滤器
Vue.filter('过滤器名称',function(value){
	//过滤器的业务逻辑
})
  • 过滤器的使用
<div>{{msg|upper}}</div>
<div>{{msg|upper|lower}}</div>
<div v-bind:id="id|formatId"></div>

实例:输入后显示要求首字母大写

    <div id="app">
        <input type="text" v-model="msg">
        <div>{{msg|upper}}</div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: ''
            },
            filters: {
                upper: function(val) {
                    return val.charAt(0).toUpperCase() + val.slice(1);
                }
            }
        })
    </script>
  • 带参数的过滤器
Vue.filter('format',function(value,arg1){
	//value就是过滤器传过来的参数
})

过滤器的使用

<div>{{data|format('yyyy-MM-dd')}}</div>
  • 修改响应式数据
Vue.set(vm.items,indexOfltem,newValue)
vm.$set(vm.items,indexOfltem,newValue)
1.参数一表示要处理的数组名称
2.参数二表示要处理的数组的索引
3.参数二表示要处理的数组的值
<div id="app">
	<ul>
		<li v-for='i in list'>{{i}}</li>
	</ul>
</div>
<script>
	var vm = new Vue({
		el: '#app',
		data: {
			list: ['apple', 'orange', 'banana']
		},
	});
	Vue.set(vm.list, 2, 'lemon')//在list中修改第三个数的值为lemon
</script>

组件

组件详解
注意事项:
组件配置对象和vue实例有以下几点差异:

如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰方式使用组件,但是如果在普通标签模板中,必须使用短横线的方式使用组件。

  • 无el
  • data必须是一个函数,该函数返回的对象作为数据
  • 由于没有el配置,组件的模板必须定义在template中

注册组件
注册组件分为两种方式,一种是全局注册,一种是局部注册

  • 全局注册
    一旦全局注册了一个组件,整个应用中任何地方都可以使用该组件

全局注册的方式是:

// 参数1:组件名称,将来在模板中使用组件时,会使用该名称
// 参数2:组件配置对象
// 该代码运行后,即可在模板中使用组件
Vue.component('my-comp', myComp)

在模板中,可以使用组件了

<my-comp />
<!---->
<my-comp></my-comp>

但在一些工程化的大型项目中,很多组件都不需要全局使用。
比如一个登录组件,只有在登录的相关页面中使用,如果全局注册,将导致构建工具无法优化打包
因此,除非组件特别通用,否则不建议使用全局注册

  • 局部注册
    局部注册就是哪里要用到组件,就在哪里注册

局部注册的方式是,在要使用组件的组件或实例中加入一个配置:

<div id="app">
        <Count></Count>
    </div>

    <script>
        var Count = {
            template: '<h1>你好啊</h1>' //模板
        }
        new Vue({
            el: "#app",
            data: {},
            components: { //注册组件
                Count
            }
        })
    </script>

// 这是另一个要使用my-comp的组件
var otherComp = {
  components:{
    // 属性名为组件名称,模板中将使用该名称
    // 属性值为组件配置对象
    "my-comp": myComp
  },
  template: `
    <div>
      <!-- 该组件的其他内容 -->
      <my-comp></my-comp>
    </div>
  `;
}
import UserInfo from "./components/UserInfo.js";

var template = `<div id="app">
<UserInfo v-for="(item,i) in users" :key="i" :name="item.name" :age="item.age" />
</div>`;

export default {
  template,//模板
  components: {//注册组件
    UserInfo,//组件
  },
}

向组件传递数据
大部分组件要完成自身的功能,都需要一些额外的信息
比如一个头像组件,需要告诉它头像的地址,这就需要在使用组件时向组件传递数据
传递数据的方式有很多种,最常见的一种是使用组件属性 component props
首先在组件中申明可以接收哪些属性:

<template>
  <div id="app">
    <div style="width:1080px;margin:0px auto">
      <!-- 我是父组件,传递消息给子组件,需要传递的消息在下面输入 -->
      <!-- 父组件,可以在引用子组件的时候,通过属性绑定(v-bind:)的形式,把需要传递给子组件的数据,
      以属性绑定的形式,传递到子组件内部,供子组件使用 -->
      <!-- 绑定自定义属性banners,值等于data属性的banners值 -->
    <Banner :banners="banners"/>
    </div>
  </div>
</template>
export default {
  //注册组件,就可以在这个界面使用了
  //结论:子组件中,默认无法访问到 父组件中的data上的数据 methods中的方法
  components:{
    Banner,
  },
  data() {
    return {
      banners:[
        {url:banner1,link:"https://baidu.com"},
        {url:banner2,link:"https://baidu.com"},
        {url:banner3,link:"https://baidu.com"}
      ]
    }
  },
}

在使用组件时,向其传递属性:

<template>
    
    <div class="banner-container">
        <!-- 图片 -->
        <ul class="images" style="width:300%">
            <li v-for="(item,i) in banners" :key="i">
              <!-- 用动态值的话无法引用 -->
              <a :href="item.link"><img :src="item.url" alt=""></a>
              </li>
        </ul>
        <!-- 小点 -->
        <ul class="dots">
            <li class="active"></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</template>

<script>
//思考:哪些数据需要放到js中管理
//有哪些图片,每张图片的超链接地址(图片信息数组[{url:"xxx",link:"xxx"}]),当前显示的事第几章图片
export default {
  //子组件想要使用传递过来的数据,必须按照传过来的属性,原样定义一个
  //用props定义
  //props中的数据,都是只读的,无法重新赋值,但是自身data的值是可读可写的
  //注意,组件中的所有banners中的数据,都是通过父组件传递给子组件的
  props:{//把父组件传递过来的banners属性,先在props数组中定义一下,这样,才能使用这个数据
  //可以写成props:['banners']
    banners:{
      type: Array,//属性类型是数组
      required:true,//必须要传递该属性
    },
  },
}
</script>

子组件向父组件传值
1.子组件通过自定义事件向父组件传递信息

<button v-on=:click='$emit("enlarge-text")'>扩大字体</button>

2.父组件监听子组件的事件

<menu-item v-on:enlarge-text='fontSize+=0.1'></menu-item>

非父子组件间传递
1.单独的事件中心管理组件间的通信

var eventHub=new Vue()

2.监听事件与销毁时间

eventHub.$on('add-todo',addTodo)
eventHuv.$off('add-todo')

3.触发事件

eventHub.$emit('add-todo',id)

组件插槽的作用
1.父组件向子组件传递内容
在这里插入图片描述
插槽位置:

Vue.component('alert-box',{
	template:`  
		<div class="demo-alter-box">
			<strong>Eroor!</strong>
			<slot></slot>
		</div>
	`
})

插槽内容

<alert-box>传递过去的数据</alert-box>

工程结构
App.js

import UserInfo from "./components/UserInfo.js";

var template = `<div id="app">
<UserInfo v-for="(item,i) in users" :key="i" :name="item.name" :age="item.age" />
</div>`;

export default {
  template,
  components: {
    UserInfo,
  },
  data() {
    return {
      users: [
        { name: "aa", age: 18 },
        { name: "bb", age: 68 },
        { name: "cc", age: 16 },
      ],
    };
  },
};

main.js

import Vue from "./lib/vue.js";
import App from "./App.js";

new Vue({
  render: (h) => h(App),
}).$mount("#app");

组件UserInfo

var template = `<div>
  <p>姓名:{{name}}</p>
  <p>年龄:{{age}}</p>
</div>`;

export default {
  props: ["name", "age"],
  template,
};

Vue-cli基础

安装node.js及npm和cnpm
使用vue-cli提供的命令搭建工程:

vue create 工程名

注意:工程名只能出现英文、数字和短横线
在这里插入图片描述
第一个是默认的,第二个是手动的(选择手动的)
在这里插入图片描述
在这里插入图片描述
创建完后如何运行
找到所在文件夹
打开cmd

先 cd 文件名进入项目
npm run serve启动项目

如何编写代码
创建一个组件

<!--写入default.vue会自动出来一个模板-->
<!--写组件-->
<template>
    <h1>轮播图</h1>
</template>
<!--写js代码-->
<script>
export default {
}
</script>
<!--写css代码-->
<style>
</style>

然后在App.vue中使用

<template>
  <div id="app">
    <Banner />
  </div>
</template>
<script>
// 导入组件
import Banner from "./components/Banner"
export default {
  //注册组件,就可以在这个界面使用了
  components:{
    Banner,
  }
}
</script>

路由

路由的本质就是对应关系
在开发中,路由分为前端路由跟后端路由:

  • 后端路由:
    概念:根据不同的用户URL请求,返回不同的内容
    本质:URL请求地址与服务器资源之间的对应关系
    在这里插入图片描述
    SPA
    后端渲染(存在性能问题)

先安装第三方库

npm i vue-router

准备工作
在入口里面导入

import VueRouter from “vue-router”

//安装
Vue.use(VueRouter );
 //创建路由对象
const router = new VueRouter({
	//配置
	routes
})
new Vue({
	el: "#app",
	router //配置路由到vue实例中
})

路由模式:

  • hash:路径来自于地址栏中#后面的值,这种模式兼容性比较
  • history:路径来自于真实的地址路径,旧浏览器不兼容
  • abstract:路径来自于内存

配置实例

const router = new VueRouter({
	routes,
	//配置
	mode: "history"
})

在导入路由组件的时候会把它们一起导入进去,
所以需要动态导入来提高他们的效率。
需要在同一个界面加载不同数据.用"/地址/:id"

{
	path: '/bar/:id',//后面:id的意思是后面不管加什么,都加载这个界面
	component: ()=>("路由地址"),//走到这就是动态导入
}
地址写成这样后他会在全局添加一个数据 this.$route
要写报错路径
{
path:"*",//匹配所有路径,然后连接报错页面
}
  • 路由重定向

路由重定向指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面;
通过路由规则的redirect属性,指定一个新的路由地址,可以很方便地设置路由的重定向:

const router = new VueRouter({
	routes:[
	//其中,path 表示需要被重定向的原地址,redirect 表示将要被重定向的新地址
		{path:'/',redirect:'/user'},
		{path:'/user',component:User},
		{path:'/register',component:Register}
	]
})
  • 嵌套路由用法:
    1.点击父级路由链接显示模板内容,
    2.模板内容中又有子级路由链接,
    3.点击子级路由链接显示子级模板内容
    在这里插入图片描述
  • 第一步:父路由组件模板
    父级路由链接,
    父组件路由填充位
<div id="app">
	<p>
		<router-link to="/user">foo</router-link>
		<router-link to="/register">bar</router-link>
	</p>
	<div>
		<!-- 控制组件的显示位置 -->
		<router-view></router-view>
	</div>
</div>
  • 第二步:子级路由模板
    子级路由链接
    子级路由填充位
const Register = {
	template: `<div>
		<h1>Register组件</h1>
		<hr/>
		<router-link to="/register/tab1">Tab1</router-link>
		<router-link to="/register/tab2">Tab2</router-link>
		<!-- 子路由填充位置 -->
		<router-view/>
	</div>`
}
  • 第三步:嵌套路由配置
    父级路由通过children属性配置子级路由
const router = new VueRouter({
	routes: [{
		path: '/user',
		component: User
	}, {
		path: '/register',
		component: Register,
		//通过children属性,为/register添加路由规划
		children: [{
			path: '/register/tab1',
			component: Tab1
		}, {
			path: '/register/tab2',
			component: Tab2
		}]
	}]
})
  • 动态匹配路由的基本用法:
<!-- 有如下3个路由链接 -->
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>

const router = new VueRouter({
	routes:[
		//动态路径参数,以冒号开头
		{path:'/user/:id',component:User}
	]
})

const User = {
	//路由组件通过$route.params获取路由参数
	template: '<div>User{{$route.params.id}}</div>'
}
  • 路由组件传递参数
    $route与对应路由形成高度耦合,不够灵活,所以可以使用props将组件和路由解耦
  • 1.props的值为布尔类型
const router = new VueRouter({
	routes: [
		//如果props被设置为true,route.params将会被设置为组件属性
		{
			path: '/user/:id',
			component: User,
			props: true
		}
	]
})
const User = {
	props: ['id'], //使用props接收路由参数
	template: '<div>用户ID:{{id}}</div>'//使用路由参数
}
  • 2.props的值为对象类型
const router = new VueRouter({
	routes: [
		//如果props是一个对象,它会被按原样设置为组件属性
		{
			path: '/user/:id',
			component: User,
			props: {
				uname:'list',
				age:20
			}
		}
	]
})
const User = {
	props: ['uname','age'], //使用props接收路由参数
	template: '<div>用户信息:{{uname+"---"+age}}</div>'//使用路由参数
}
  • 3.props的值为函数类型
const router = new VueRouter({
	routes: [
		//如果props是一个函数,则这个函数接收route对象为自己的参数
		{
			path: '/user/:id',
			component: User,
			props:route=>({uanme:'cb',age:20,id:route.params.id})
		}
	]
})
  • 命名路由的配置规则
<router-link :to="{name:'user',params:{id:123}}">User1</router-link>

const router = new VueRouter({
	routes: [{
		path: '/user/:id',
		name: 'user',//通过name去router-link实现对应的跳转
		component: User
	}]
})
  • 页面导航的两种方式:

  • 声明式导航:通过点击链接实现导航的方式,叫做声明式导航
    列如:普通网页中的< a>< /a>链接或vue中的< router-link>< /router-link>

  • 编程式导航:通过调用javaScript形式的API实现导航的方式,叫做编程式导航
    例如:突破普通网页中的location.href

  • 编程式导航的基本用法

常用的编程式导航API如下:
this. r o u t e r . p u s h ( ′ h a s h 地 址 ′ ) ; / / 实 现 后 退 功 能 t h i s . router.push('hash地址'); //实现后退功能 this. router.push(hash);//退this.router.go(-1)

const User = {
	template:'<div><button @click="goRegister">跳转到注册界面</div>',
	methods: {
		goRegister:function(){
		//用编程的方式控制路由跳转
			this.$router.push('/register');
		}
	},
}

路由归纳
路由基础
路由详情

前后端交互

接口的调用方式和:
1.fetch
2.axios
Promise用法

function (data){
    //data为状态数据
}

//例子
var pro = new Promise((resolve, reject) => {
    console.log("任务进行中....");
    setTimeout(() => {
        resolve("over");
    }, 3000);
});
pro.then((data) => {
    console.log("成功", data);
}, (err) => {
    console.log("失败", err);
});

Promise的链式调用

function delay(duration){
  return new Promise(resolve=>{
    setTimeout(()=>{
      resolve();
    }, duration)
  })
}
/*
异步任务:
1. 等待1秒,输出1
2. 然后等待2秒,输出2
3. 然后等待3秒,输出3
*/
delay(1000).then(()=>{
  console.log(1);
  return delay(2000);
}).then(()=>{
  console.log(2);
  return delay(3000);
}).then(()=>{
  console.log(3);
})

对象方法

Promise.all():
并发处理多个异步任务,所有任务都执行完成才能得到结果
Promise.race():
并发处理多个异步任务,只要有一个任务完成就能得到结果

Promise.all([p1,p2,p3]).then((resole)=>{
	console.log(resole);
})
Promise.race([p1,p2,p3]).then((resole)=>{
	console.log(resole);
})

axios概述

方法一:需要引入

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

方法二:

npm i axios进行安装
安装之后在要使用的页面组件中进行引入。
import axios from ‘axios’

axios的响应结果
data:实际响应回来的数据
headers:响应头信息
status:响应状态码
statusText:响应状态信息

axios的全局配置:

axios.defaults.timeout=3000;//超时时间
axios.defaults.baseURL='http:/localhost:3000/app';//默认地址
axios.defaults.headers['mytoken']='aqwerwqwsghgf';//设置请求头

axios拦截器:
1.请求拦截器:
在请求发出之前设置一些信息
在这里插入图片描述

//添加一个请求拦截器
axios.interceptors.request.use(function(config){
	//在请求发出之前进行一些信息设置
	return config;
},function(err){
	//处理响应的错误信息
})

2.响应拦截器:
在获取数据之前对数据做一些加工处理
在这里插入图片描述

//添加一个响应拦截器
axios.interceptors.response.use(function(res){    
	//在这里对返回的数据进行处理
	return res;
},function(err){
	//处理响应的错误信息
})

小结:
axios的作用:发送异步请求获取数据,常见的方法:get、post;在发送的时候可以指定参数(地址、请求方式和请求头部信息);返回数据结构(data/status/statusText/headers/config)
axios方法及get、post方法使用
目标:使用axios方法获取数据并在页面中将数据遍历显示;切换改为get/post方法实现数据加载
小结:
可以使用axios获取对应服务器数据;如果不是同一个服务器的数据则可能会出现跨域请求;需要在相应额服务器上配置跨域。
在这里插入图片描述
一个简单是实例:

<div id="app">
	<ul>
		<li v-for="(user,i) in users" :key="i">
			{{user}}--{{user.name}}--{{user.age}}
		</li>
	</ul>
</div>

<script>
	var app = new Vue({
		el: "#app",
		data() {
			return {
				users: []
			}
		},
		created() {
			//初始化加载数据
			axios({
				url: "data.json", //到哪个地方去获取数据就填哪个地址
				method: "get" //get方法
			}).then(res => {
				console.log(res);
				//将数据赋值到vue实例中的数据属性userrs;
				//不能使用this,在axios回调函数中表示窗口,不是vue实例
				app.users = res.data; //其中数据属性是放在res的data属性中
			}).catch(err => alert(err));
		//加载成功会调用then方法(返回输入为res),加载失败会掉哟用catch方法(返回数据为err)
		//第二种get写法
		//  axios.get("data.json").then().catch(err => alert(err))
		},
	})
</script>

写在Vue中的service中的话


//要加上async跟await
export async function getNews() {
    var resp = await axios.get("xxxx.xxx")

}

async/await用法

1.async/await的基本用法:
async/await是ES7引入的新语法,可以更加方便的进行异步操作
async关键字用于函数上(async函数的返回值是Promise实例对象)
await关键字用于async函数当中(await可以得到异步的结果)

 async function queryData(id){
	const ret=await new Promise(function(resolve,reject){
		setTimeout(() => {
			resolve('nihao');
		}, 1000);
	})
	return ret;
}
queryData.then(ret=>{
	console.log(ret);
})

async/await处理多个异步请求

async function queryData(id){
	const info=await axios.get('/async1');
	const ret=await axios.get('async2?info='+info.data);
	return ret;
}
queryData.then(ret=>{
	console.log(ret);
})

处理共享数据(vuex)

vuex简介
介绍
注意:并非所有数据都需要让vuex管理,通常vuex只管理那些需要被组件共享的数据

在实际的开发中,一些逻辑特别复杂的数据,尽管不共享,也可能提取到vuex中进行管理

1.安装vuex

在页面中引入vuex库 npm i vuex

该库提供了一个构造函数Vuex.Store,通过该构造函数,即可创建一个数据仓库
创建方法跟router差不多

安装vue devtools
这是一个chrome浏览器插件,用于调试vue、vue-router、vuex应用

import vuex from "vuex"
//安装vuex 
Vue.use(Vuex);
var store = new Vuex.Store({
    // 仓库数据配置
})
new Vue({
    // 其他配置
    store
})

vuex的核心概念

  • 数据的改动:
    必须要提交commit一个mutation
    在vuex中,提交mutation是数据变化的唯一原因
    在mutation中不能出现副作用操作
    什么是副作用操作:
    1. 改动或使用外部的数据
    2. ajax
    3. 其他异步行为

  • 处理副作用
    触发dispatch一个action

store变化逻辑

  1. 直接通过mutation改动仓库数据
    image-20200518124351876
  2. 通过actioin改动仓库数据
    image-20200518124611793
    关系图
    image-20200518124912592
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值