Vue 学习笔记1(01-39)
学习地址:https://ke.qq.com/course/279700
目录:
- 01-01 git下载代码
- 02-27 Vue2.x
- 28-39 路由精讲
- 40-49 Vue-Cli3.0
- 50-64 Vue2.x-实战项目(个人博客)
- 65-76 Vue2.x-实战项目(用户管理)
- 77-87 Vuex
download
01 第1课到25课代码下载
git clone https://github.com/hemiahwu/vue-basic.git
cd vue-basic
git checkout lesson-* # *为 1~25
vue2
02 Vue2.x-初识Vue及引入CDN
vue的引入
或者
03 Vue2.x-实例化Vue对象
app.js
// 实例化Vue对象
new Vue({
el: '#vue-app',
data: {
name: 'Allenem',
job: 'student'
}
});
/*
* el:element 只能挂载到根容器上
* data:用于数据存储
*/
html中引入数据
{{ name }}
{{ job }}
04 Vue2.x-数据和方法
(1)无参函数
app.js
// methods 用于存储各种方法
methods: {
greet: function(){
return 'Good Morning!'
}
}
index.html中使用方法
{{greet()}}
{{greet}}
(2)有参函数
app.js
methods: {
greet: function(time){
return 'Good '+time+' !';
}
}
index.html中使用方法
{{ greet('Night') }}
{{ greet(Night) }}
(3)方法中用data中的属性
直接使用this.*
,不用this.data.*
app.js
methods: {
greet: function(time){
return 'Good '+ time + this.name+' !';
}
}
05 Vue2.x-属性绑定
绑定属性
app.js
data中添加
website: 'https://github.com/'
index.html
websit
或者简写
websit
绑定标签
app.js
data中添加
websiteTag: "websit"
index.html
websit
{{ websiteTag }}
06 Vue2.x-事件(点击:双击:鼠标事件)
不传参单击双击
注意:绑定事件里方法不传参可以不加括号仍然识别为方法,但在{{}}里一定要写括号才会识别为方法
app.js
data: {
age: 20,
},
methods: {
add: function(){
this.age++;
},
dec: function(){
this.age--;
},
}
index.html
My age is {{ age }}
传参单击双击
app.js
methods: {
add: function(val){
this.age += val;
},
dec: function(val){
this.age -= val;
},
}
index.html
鼠标滚动获取当前位置事件
app.js
methods: {
updateXY: function(event){
this.x = event.offsetX;
this.y = event.offsetY;
},
}
index.html
{{x}},{{y}}
07 Vue2.x-事件修饰符(once:prev:stop)
app.js
// 无变化
index.html
{{x}},{{y}} --
stop moving
<=>
methods:{
stopMove: function(event){
event.stopPropagation();
},
}
index.html
{{x}},{{y}} --
stop moving
08 Vue2.x-键盘事件及键值修饰符(alt:enter)
app.js
data: {
name: 'Allenem',
age: 20,
},
methods: {
logName: function(){
console.log('typing name');
},
logAge: function(){
console.log('typing age');
}
},
index.html
09 Vue2.x-双向数据绑定
app.js
methods: {
logName: function(){
// console.log('typing name');
this.name = this.$refs.name.value;
},
logAge: function(){
// console.log('typing age');
this.age = this.$refs.age.value;
}
},
index.html
10 Vue2.x-计算属性Computed
methods 属性
app.js
methods: {
addA: function(){
console.log('aaa');
return this.a + this.age;
},
addB: function(){
console.log('bbb');
return this.b + this.age;
},
},
index.html
computed 计算属性
A: {{a}}
B {{b}}
Age + A {{addA()}}
Age + B {{addB()}}
computed 属性
app.js
computed: {
addA: function(){
console.log('aaa');
return this.a + this.age;
},
addB: function(){
console.log('bbb');
return this.b + this.age;
},
},
index.html
computed 计算属性
A: {{a}}
B {{b}}
Age + A {{addA}}
Age + B {{addB}}
11 Vue2.x-动态绑定CSS样式
style.css
span{
background: #f00;
display: inline-block;
padding: 10px;
color: #fff;
margin: 10px 0;
}
.changeColor span{
background: #0f0;
}
.changeLength span:after{
content: "length";
margin-left: 10px;
}
app.js
data: {
changeColor:false,
changeLength:false
},
computed: {
compClasses: function(){
return{
changeColor:this.changeColor,
changeLength:this.changeLength
}
}
},
index.html
eg2
lucy
12 Vue2.x-指令v-if
app.js
data: {
err:false,
success:false
},
index.html
err
200
err
200
13 Vue2.x-指令v-for
app.js
data: {
characters:['allen','janny','mike'],
users:[
{name:'hurry',age:20},
{name:'luccy',age:25},
{name:'zero',age:18},
]
},
index.html
- {{index+1}} - {{item.name}} - {{item.age}}
{{item.name}}
{{index+1}} - {{item.age}}
{{item.name}}
{{index+1}} - {{item.age}}
14 Vue2.x-实战DEMO
app.js
data: {
health:100,
ended:false
},
methods: {
punch:function(){
this.health -= 10;
if(this.health <= 0){
this.ended = true;
}
},
restart:function(){
this.health = 100;
this.ended = false;
}
},
index.html
Bag-Demo
style.css
h1{
width: 200px;
margin: 0 auto;
text-align: center;
}
#bag{
width: 200px;
height: 500px;
margin: 0 auto;
background: url(img/bag.png) center no-repeat;
background-size: 80%;
}
#bag.burst{
background-image: url(img/bag-burst.png)
}
#bag-health{
width: 200px;
border: 2px #000 solid;
margin: 0 auto 20px auto;
}
#bag-health div{
height: 20px;
background: crimson;
}
#control{
width: 200px;
margin: 0 auto;
}
#control button{
margin-left: 20px;
}
15 Vue2.x-实例化多个Vue对象
app.js
// 实例化Vue对象
var one = new Vue({
el: '#vue-app-one',
data: {
title: 'one 的内容'
},
methods: {
},
computed: {
greet:function(){
return 'hello app one';
}
},
});
var two = new Vue({
el: '#vue-app-two',
data: {
title: 'two 的内容'
},
methods: {
changeTitle:function(){
one.title = 'changed';
}
},
computed: {
greet:function(){
return 'hello app one';
}
},
});
16 Vue2.x-初识组件的应用
app.js
Vue.component("greeting",{
template:`
{{name}}:大家好,给大家介绍一下我的朋友@关晓彤
`,
data:function(){
return {
name:'鹿晗'
}
},
methods:{
changeName:function(){
this.name = this.name == '鹿晗'?'Hery':'鹿晗'
}
}
})
17 Vue2.x-搭建脚手架CLI
部分特点
- 脚手架是通过webpack搭建的开发环境
- 使用es6语法
- 打包和压缩js为一个文件
- 项目在环境中编译,而不是浏览器
- 实现页面自动刷新
- ...
vue-cli的使用
- 安装 nodejs ,一般选择安装LTS(长期稳定版)版本。官网:https://nodejs.org/en/
# 在terminal、cmd、powershell 中 # 输入 `node -v` 查看 node 版本号 node -v
# 输入 `npm -v` 查看 npm 版本号 npm -v
- 安装 cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
- 安装 Vue CLI 3.x
npm install -g @vue/cli # OR yarn global add @vue/cli
# 输入 `vue --version` 查看 npm 版本号 vue --version # OR vue -V
- 创建一个 Vue 项目
vue create projectName
# 创建项目相关帮助 vue create --help
- 运行相关
# Project setup npm install # Compiles and hot-reloads for development npm run serve # Compiles and minifies for production npm run build # Run your tests npm run test # Lints and fixes files npm run lint
- (PS)旧版本 Vue CLI 2.x
npm install -g @vue/cli-init # `vue init` 的运行效果将会跟 `[email protected]` 相同 vue init webpack my-project
18 Vue2.x-介绍SRC文件流程及根组件App
client
│ .gitignore
│ babel.config.js
│ package.json
│ README.md
│
├─public
│ favicon.ico
│ index.html
│
└─src
│ App.vue
│ main.js
│ router.js
│
├─assets
│ bg.jpg
│
└─components
Component1.vue
Component2.vue
index.html -> main.js -> App.vue ()
19 Vue2.x-组件嵌套
可以在main.js中注册全局组件
import Users from './component/Users'
Vue.component('users',Users);
也可以在某些组件中调用
20 Vue2.x-组件CSS作用域
21 Vue2.x-实战Demo(组件嵌套)
略
22 Vue2.x-属性传值Props
父组件:
在调用子组件的位置,绑定自己的属性,第一个是子组件中的名称,第二个是父组件中的名称。
eg:
子组件:
子组件属性 props:['usersSon'],
接收传值。或者用标准写法
props:{
users:{
type:Array;
requied:true;
},
position:{
type:Array;
requied:true;
},
},
eg:
-
{{user.name}}
{{user.position}}
23 公益广告
略
24 Vue2.x-传值和传引用
传值:string number boolean,一处变,全部变
引用:array object,一处变,局部变
25 Vue2.x-事件传值(子to父)
子组件
{{title1}} {{title}}
父组件
26 Vue2.x-生命周期(钩子函数)
8个钩子函数与 methods 并列。
Header.vue
27 Vue2.x-路由和Http(快速入门)(知识点最后一课第25课)
(1) 安装路由模块及引入
npm install vue-router --save
router.js中
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home.vue'
import HelloWorld from './components/HelloWorld.vue'
Vue.use(Router);
export default new Router({
mode: 'history', // 没有#符号
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/helloworld',
name: '',
component: HelloWorld
}
]
})
main.js中
import router from './router';
new Vue({
router,
...
});
App.vue
(2) HTTP
安装依赖:
npm i vue-resource --save
使用:
main.js中
import VueResource from 'vue-resource';
Vue.use(VueResource);
Home.vue中
created(){
this.$http.get('http://jsonplaceholder.typicode.com/users')
.then((data)=>{
// console.log(data);
this.users = data.body;
})
},
router
28 Vue2.x-路由精讲之新建项目
just create an Vue App
29 Vue2.x-路由精讲之制作导航
use bootstraps4 by BootstrapCDN (CSS only)
30 Vue2.x-路由精讲之配置路由跳转
router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home'
import About from './components/about/About'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{path:'/',component:Home},
{path:'/about',component:About},
]
})
Header.vue
App.vue
31 Vue2.x-路由精讲之路由小细节(redirect和tag)
Header.vue
router.js
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{path:'/',component:Home},
{path:'/about',component:About},
{path:'*',redirect:'/'}, //错误输入重定向
]
})
32 Vue2.x-路由精讲之路由name属性及跳转方法
name
{path:'/',name:'homelink',component:Home},
主页
跳转
33 Vue2.x-路由精讲之二级路由和三级路由
router.js
{path:'/about',name:'aboutLink',redirect:'/about/histoey',component:About,
// 二级路由
children:[
{path:'/about/histoey',name:'historyLink',component:History},
{path:'/about/contact',name:'contactLink',redirect:'/phone',component:Contact,children:[
// 三级路由
{path:'/phone',name:'phoneNum',component:Phone},
{path:'/personname',name:'personName',component:Personname},
]},
{path:'/about/orderingguide',name:'orderingGuideLink',component:OrderingGuide},
{path:'/about/delivery',name:'deliveryLink',component:Delivery},
]},
about.vue
34 Vue2.x-路由精讲之导航守卫(全局守卫)
学习地址(https://router.vuejs.org/zh/guide/advanced/navigation-guards.html)
main.js中
// 全局守卫
router.beforeEach((to,from,next) => {
if(to.path == '/login' || to.path == '/register'){
next()
}else{
alert("还没有登录,请先登录!");
next('/login');
}
})
35 Vue2.x-导航守卫(路由独享-组件内守卫)
后置钩子(不常用)
router.afterEach((to,from) => {
alert("after each")
})
路由独享的守卫
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
组件内的守卫
- beforeRouteEnter
- beforeRouteUpdate (2.2 新增)
- beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
beforeRouteLeave (to, from , next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
beforeRouteLeave(to,from,next){
if(confirm('确认离开吗?') == true){
next()
}else{
next(false)
}
}
36 Vue2.x-路由精讲之复用router-view
router。js修改
{path:'/',name:'homeLink',component:Home,},
为
// 注意 components 的 s
{path:'/',name:'homeLink',components:{
default:Home,
'history':History,
'orderingGuide':OrderingGuide,
'delivery':Delivery
}},
App.vue添加
37 Vuv.2x-路由精讲之控制滚动行为
router.js中
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置
}
})
eg:
scrollBehavior (to, from, savedPosition) {
// return {x:0,y:100}; // 滚动到(0,100)
// return {selector:'.btn'}; // 滚动到 第一个.btn
// 浏览器返回上一页面时,回到上次浏览的位置
if(savedPosition){
return savedPosition
}else{
return {x:0,y:0}
}
}
38 课程总结及引导
略
39 Vue2.x-实现跨域请求(fetch/axios/proxytable)
(0)预设
通过vue-cli3.x版本构建的项目使用proxy和以前的项目不同,而且3.x版本构建的时候可以选用typescript了。下面记录一下如何使用proxy跨域。
首先在根目录创建vue.config.js文件,这个配置文件在运行项目的时候自动加载。
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://xxxx/device/', //对应自己的接口
changeOrigin: true,
ws: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
这个文件还可以配置其它信息,比如修改端口号,默认是8080等等。
最后在页面发送请求的时候:
axios.get('/api/getDataPoint').then(res => {
console.log(res)
})
示例如下:
(1)预设
proxyTable:{
' /apis': {
//测试环境
target:'http://www.thenewstep.cn/', //接口域名
change0rigin:true, //是否跨域
pathRewrite: {
'^/apis':'' //需要rewrite重写的,
}
}
},
(2)fetch
created(){
// fetch
fetch("/apis/test/testToken. php", {
method:"post",
headers: {
"Content-type" :"application/json",
token : "f4c902c9ae5a2a9d8f84868ad064e706"
},
body: JSON.stringify({username: "henry" , password :"321321"})
})
. then( result =>{
// console. log( result)
return result. json()
})
. then(data => {
console. log ( data)
})
}
(3)axios
main.js
import axios from 'axios'
axios.defaults.headers.common[ 'token '] = "f4c902c9ae5a2a9d8f84868ad064e706"
axios.defaults.headers.post ["Content-type"] = "application/j son"
Vue. prototype.$axios = axios
App.vue
this.$axios.post("/apis/test/testToken.php" , {username :"hello",password :"123456"})
.then(data => {
console. log(data)
})