1.el 用于挂载管理的元素 2.data定义数据(组件当中必须是一个函数) 3.methods定义方法
(会更新)
Vue插值语法 指令(了解)
1.Mustache 这个就是vue里面的大括号{{}} (可以写变量,和表达式)
2.v-once指令 该指令表示元素和组件,只渲染一次,不会随数据的改变而改变(不常用)
3.v-html指令 用于解析HTML代码,然后展示,把string解析渲染出来
4.v-text指令 不用大括号
5.v-pre 不解析
6.v-cloak 不直接显示页面,过秒显示
7.v-bind 动态绑定属性 可以是使用 :代替
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<!-- <h1>{{constrr}}</h1> -->
<img :src="constrr" alt=""/> <!-- 语法糖 -->
<img v-bind:src="constrr" alt=""/> <!-- 平常 -->
<a :href="herss">淘宝一下</a>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data:{
constrr:'https://img0.baidu.com/it/u=3101694723,748884042&fm=26&fmt=auto&gp=0.jpg',
herss:'https://www.taobao.com'
}
})
</script>
</body>
</html>
计算属性的getter和setter方法
1.一般我们只用get来获取数据,而set只读
2.get获取值 set 设置值属性
const的使用
什么时候使用const呢?
当我们修饰的标识符不会被再次赋值时,就可以使用const来保证数据的安全性.
事件监听
v-on :绑定事件监听器 缩写@ 参数event
v-on修饰符
1.stop 阻止事件冒泡
2.prevent 阻止默认事件
3.keyCode | keyAlias 只当事件是从特定键触发时才触发回调。
4.native - 监听组件素的原生事件。
5.once 只触发一次
6.串联修饰符 <button @click.stop.prevent="doThis"></button> enter 键别名
v-if 和 v-show的区别
v-if:当条件为false时,包含v-if指令的元素,根本就不会存在dom中
v-show:当条件为false时,v-show只是给我们的元素添加一个行内样式:display: none
1.disabled 禁止按钮点击 v-bind:disabled " 可以这样子判断"
2.toFixed(2) 可以在字符后面加0 要几个输入几个
v-model 数据双向绑定
v-model原理:v-model其实是一个语法糖,它的背后本质上是包含两个操作∶
1.v-bind绑定一个value属性
2.v-on指令给当前元素绑定input事件
v-model绑定radio(女同)
v-model修饰符
1.解决表单空格的,当在v-model后面使用trim,会自动把空格去掉
2.lazy这个跟赖加载类似,当用户在输入框输入内容时,要敲下回车键内容才显示
3.number这个修饰符,无论在输入框输入什么数字,都会被转换成字符串,也会自动转换为数字
<input type="number" v-model="number"/>
<h1>这个是{{typeof ages}}</h1>
<input type="text" v-model.lazy="maqges"/>
<h1>{{maqges}}</h1>
<input type="radio" value="男" id="male" v-model="sex"/>男
组件化的基本使用
<div id="app">
<my-bbv></my-bbv>
<my-bbv></my-bbv>
<my-bbv></my-bbv>
</div>
<script src="../js/vue.js"></script>
<script>
/1.创建组件构造器对象
const bbvC = Vue.extend({
template:`
<div>
<h2>今天努力了吗</h2>
<p>我禁用聊</p>
</div>`
})
//2.注册事件
Vue.component('my-bbv',bbvC)
const app = new Vue({
el:'#app'
})
</script>
[点击并拖拽以移动]
[点击并拖拽以移动]
1.Vue.extend(); 是创建一个组件构造器
2.Vue.component(); 注册为一个组件,并起一个标签名
3.必须在Vue实例使用,不然不生效
全局组件和局部组件
1.全局组件就是在Vue实例外面注册Vue.component('my-bbv',bbvC); 全局和局部都能使用
2.局部组件就是在Vue实例里面注册components:{cpn:cpnC}
面试题:
1.组件中data为什么是一个函数
答:它必须是一个函数,如果不写成函数,会导致组件在复用时会产生连锁反应,相互产生不利的影响
父组件和子组件
1.什么是组件 组件优势是什么
组件是对数据和方法的简单封装
低耦合度 块状化结构,并且方便扩展 标记鲜明,容易维护
什么是父子组件:子组件的数据,能被父组件传递,
父组件传递子组件props 子组件传递父组件$emit
父子访问组件的几个小属性
父组件访问子组件:使用$children或$refs reference(引用)
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>我是子组件</div>
</template>
const app = new Vue({
el:'#app',
methods:{
btnClick() {
//1.$children
// console.log(this.$children);
//调用子组件
// this.$children[0].showMessage();
// for (let c of this.$children) {
// console.log(c.name);
// c.showMessage();
// }
//2.$refs => 对象类型 ,默认是一个空的对象 ref='bbb'
console.log(this.$refs.aaa.name);
}
},
components:{
cpn: {
template:'#cpn',
data() {
return {
name: '我是子组件的name'
}
},
methods:{
showMessage() {
console.log('showMessage');
}
}
}
}
})
子组件访问父组件:使用$parent或 $root (访问根组件)
slot (插槽)
插槽的目的,是让我们原来的设备具备更多的扩展性
组件的插槽︰
组件的插槽也是为了让我们封装的组件更加具有扩展性。
让使用者可以决定组件内部的一些内容到底展示什么。
具名插槽的使用
<div id="app">
<cpn><span slot="left">呵呵</span></cpn>
<cpn><button slot="right">返回</button></cpn>
</div>
<template id="cpn">
<div>
<slot name="left"><span>哈哈</span></slot>
<slot name="center"><span>哈哈</span></slot>
<slot name="right"><span>hhe</span></slot>
<!-- <span>哈哈</span>
<span>哈哈</span> -->
</div>
</template>
导入导出
导出:export 或 export default (前提是引用js文件,类型必须设置为type="module")
1.可以通过对象导出 2.自定义时导出 3.导出函数和类
导入:import 同意全部导入:import * as aaa(取的名字) from './aaa.js'
function add(num1,num2) {
return num1 + num2
}
function mul(num1,num2) {
return num1 * num2
}
//导入
module.exports = {
add,
mul
}
2.创建main.js文件
const {add,mul} = require('./mathutis.js')
console.log(add(20, 30))
console.log(mul(20, 30))
import {name,age,height} from "./uff"
console.log(name);
console.log(age);
console.log(height);
3.2 uff.js
//ES6导入方法 新增
export const name = 'whit';
export const age = 20;
export const height = 1.80;
3.在终端执行 webpack ./src/main.js ./dist/bundle.js (dist)是另一个目录 (bundle)打包到bundle.js 里面 在index.html 导入 bundle.js 就可以执行
CLI(脚手架)
1.cnpm安装 淘宝NPM镜像
可以使用淘宝定制的cnpm (gzip 压缩支持)命令行工具代替默认的npm:
npm install -g cnpm --registry=https://registry.npm.taobao.org这样就可以使用cnpm命令来安装模块了:
cnpm install [name]
2.使用CLI前提:webpack npm install webpack -g(安装webpack)
1. 安装Vue脚手架 npm install -g @vue/cli (-g 代表全局安装)
查看: 1.vue --version 2.vue -V (两种方式)
2.包管理工具
npm install -g vue/cli
yarn global add @vue/cli (脚手架3)
npm install @vue/cli-init -g(脚手架2)
1.vue init webpack vuecli2test(项目名) cli2 创建项目
vue CLI2初始化项目
vue init webpack my-projectvue (项目名)
CLI3初始化项目
vue create my-project(项目名)
路由 vue-router
在命令行中输入npm install vue-router -g来安装vue-router,安装完之后我们可以打package.json文件,在package.json文件中可以看到vue-router的版本号
1.什么是路由
路由是根据不同的 url 地址展示不同的内容或页面
路由器提件了两种机制:路由和转送.
1路由是决定数据包从来源到目的地的路径. 2.转送将输入端的数据转移到合适的输出端.
2.路由表本质上就是一个映射表:决定了数据包的指向
映射表就是地址和某一台电脑的关系
url--hash 和HTML5 history.pushState (不刷新页面 控制台输出)
1.location.hash = 'nnn' 2.hisory.pushState({}, '', 'home')
3.history.go(-1) history.go(1) 前进和后退
router-link
1 .tag 可以指定<router-link>渲染成组件,<router-link to="/" tag="li"> 就会渲染成li
2.replace不会留下history记录,,所以指定replace的情况下,后退键返回不能返回到上一个页面中
3.active-class:当<router-link>对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class设置active-class可以修改默认的名称.
路由赖加载 (方式)
方式一:结合Vue的异步组件和Webpack的代码分析 (这个比较老)
const Home = resolve => { require.ensure([ ' ../components/Home.vue'],() =>i resolve(require( ' ../ components /Home.vue ' )) })};
方式二:AMD写法
const About = resolve => require([ ' ../components/About.vue'],resolve);
方式三:在ES6中有更加简单的写法来组织Vue异步组件和Webpack的代码分割
const Home = () => import( ' ../ components/Home.vue ' ) 推荐 (在router文件下面index.js写)
以赖加载打包: npm run build
嵌套路径
const routes = [
{
path: '/',
name: 'Home',
component: Home
children: [
{
path: '/oess',
name: 'Oess',
component: Oess
},
path: "news",
redirect: 'message'
]
},
$route和$router是有区别的:
1.$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法
2.$route为当前router跳转对象里面可以获取name、path、query.params等
导航守卫
1.前置守卫(guard) router.beforeEach((to, from, next)
to:进入到哪个路由去,from:从哪个路由离开,next:函数,决定是否展示你要看到的路由页面
- 判断to.path当前将要进入的路径是否为登录或注册,如果是就执行next(),展示当前界面。如果不是,就弹出alert,然后移至登录界面。
- 这样就可实现,用户在未登录状态下,展示的一直是登录界面
router.beforeEach((to,from,next)=>{
if(to.path == '/login' || to.path == '/register'){
next();
}else{
alert('您还没有登录,请先登录');
next('/login');
}
})
2.后置钩子(hook) router.afterEach((to, from) 这两个称为全局守卫
每次切换路由时,都会弹出alert,点击确定后,展示当前页面。
router.afterEach((to,from)=>{
alert("after each");
})
路由独享的守卫. 组件内的守卫. (补充回来))
3.组件内守卫
data 组件内守卫有特殊情况,如果我们直接以beforeRouteEnter:(to,from,next)=>{ alert("hello" + this.name);}
进行访问admin页面,会发现alert输出hello undefined
。这是因为,现在访问不到我们的data属性,执行顺序是不一致,这与的声明周期有关。在执行完之前,data数据还未渲染。所以这里,next()会给一个对应的回调
<script>
export default {
data(){
return{
name:"Arya"
}
},
beforeRouteEnter:(to,from,next)=>{
next(vm=>{
alert("hello" + vm.name);
})
}
}
</script>
keep-alive
keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
它们有两个非常重要的属性:
include -字符串或正则表达,只有匹配的组件会被缓存
exclude -字符串或正则表达式,任何匹配的组件都不会被缓存
Promise
Promise到底是做什么的?????
Promise是异步编程的一种解决方案。
基本使用
<script>
//有异步操作
new Promise((resolve, reject)=> { //在执行传入的回调函数时,会传入两个参数,resolve,reject.本身又是函数
setTimeout((data) => {
//成功调用resolve
resolve(data) //传入的参数
//失败调用reject
reject('error message')
},1000)
}).then((data) => {
console.log(data);
}).catch((err) => {
console.log(err);
}) //代码处理
</script>
Vuex
vuex是做什么的?
Vuex是一个专为 Vue.js 应用程序开发的状态管理模式 (官方)
1.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
2.Vuex也集成到Vue的官方调试工具devtools extension,提供了诸如零配置的 time-travel调试、状态快照导入导出等高级调试功能。
1.安装Vuex
npm install vuex --save (npm)yarn add vuex
2.Vuex有几个比较核心的概念:State Getters Mutation Action Module
1.State 单一状态数 vuex来使用单一状态树来管理应用层级全部状态,方便管理和维护
2.getters 是参数和传递参数
axios
安装(终端):npm install axios --save
①“npm install axios”,
②“yarn add axios”,
③“bower install axios
axios封装
import axios from "axios";
//创建一个axios对象
const instance = axios.create({
//baseURL会在发送请求的时候拼接在url参数前面
baseURL: 'https://api.cat-sh.pe.com', //(假的api)
timeout: 5000
})
//全局拦截
//所有网络请求都会先走这个方法,可以添加自定义内容
instance.interceptors.request.use(
function(config) {
console.group('全局请求拦截');
console.log(config);
console.groupEnd(); //结束
config.headers.token = "123121"; //添加一个头
return config;
},
function(err) {
return Promise.reject(err);
}
);
//响应拦截
//所有网络请求返回数据之后都会执行此方法
//此处可以根据服务器的放回状态码做相应的数据
instance.interceptors.request.use(
function(response) {
console.group('响应请求拦截');
console.log(response);
console.groupEnd(); //结束
return response;
},
function(err) {
return Promise.reject(err);
}
);
export function get(url, params) { //发送GET两个参数1:url 2.params
return instance.get(url, { //配置项
//参数
params
})
}
export function post(url, data) {
return instance.post(url, data) //可以为空
}
export function del(url) {
return instance.delete(url); //可以为空
}
export function put(url, data) {
return instance.put(url, data); //可以为空
}
Home.vue组件
<template>
<div class="home">
我是首页阿萨
<button @click="getHandle">发送get请求</button>
<button @click="postHandle">发送post请求</button>
<button @click="getByy">调用封装的get请求</button>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';
import axios from 'axios';
//在这里调用utils
import { get } from '../utils/request'
export default {
name: 'Home',
components: {
HelloWorld
},
methods: {
getHandle(){
//发起get请求
//参数1 表示请求地址
//参数二 表示配置信息 https://api.cat-shop.penkuoer.com/api/v1/products
axios.get("https://api.cat-shop.penkuoer.com/api/v1/products",{
//固定属性
params:{
page:3,
per: 2
}, //表示传递到服务器端的数据,以url参数的形式拼接在请求地址后面
headers:{} //headers表示请求头
}).then(res => console.log(res));
},
postHandle() {
// post请求传递三个参数请求地址
// 传递的数据在请求体中传递
// axios默认发送的数据是json格式的配置信息
// headers
// conttent-type: 'application/json’默认
//
axios.post("https://api.cat-shop.penkuoer.com/api/v1/auth/login",{
userName: 'xiaoming',
password: '11111'
},{
params: { //post
a: 123,
b: "haha"
}
}).then(res => console.log(res))
.catch(err => console.log(err)); //失败的请求
},
getByy() {
get("/api/v1/products",{})
.then(res => console.log(res))
}
}
}
</script>