简短的文章介绍:这个是我学vue时的学习笔记。前面“2-3”形式的是学习慕课网的一个课程,没学完。中间有一个“vue文档”。后面的“P4”形式的是跟b站技术胖的Vue2.x基础免费视频。目前同时在看《Vue.js快跑》,如果有需要记录的点,会加以补充。
好像这么弄有些乱,会花些时间重新整理一下的。
2020.6.20 目前在学coderwhy王红远老师的vue课,会对下面的知识点有补充
一、简单介绍vue
vue.js有什么用,是用来做什么的(整理)
Vue的核心是将数据显示在页面上,这一功能通过模板(Template)实现。为正常的HTML添加特殊的属性——被称作指令(Directive)——借助它来告诉Vue我们想要实现的效果以及如何处理提供给它的数据(Data)。——-《Vue.js快跑》
某一天突然发现vue报错,比如“ Vue is not defined”或者是“[Vue warn]: Cannot find element: #app”,莫名其妙不行,又莫名其妙可以...贴一个能运行的代码,以后不行的时候直接拿去调。感觉浏览器对代码格式要求比较严格,格式乖乖按照缩进弄吧
<!DOCTYPE html>
<html lang="en">
<head>
<title> new document </title>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8"/>
<style>
.bg{color:red}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!--放这里可以-->
</head>
<body>
<div class="bg">
<p>哭了 bug在哪里啊啊啊啊啊啊啊啊</p>
</div>
<div id="app">
{{ message }}
</div>
<!-- <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script> 放这里也可以-->
<!--<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 放这里也可以-->
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
vue的编程范式是声明式编程,区别于js的命令式编程
js的命令式编程
// 1.定义数据
let message = 'Hello Vuejs'
// 2.获取DOM
const appDom = document.querySelector('#app')
// 3.将message设置到DOM中
appDom.innerText = message
// 4.修改message,并且将新的message赋值到DOM中
19.12.27更新:可以将vue.js的文件下载下来,然后引用。
开发环境 https://vuejs.org/js/vue.js
生产环境 https://vuejs.org/js/vue.min.js
__________________
Vue有很多特点和Web开发中常见的高级功能
- 解耦视图和数据
- 可复用的组件
- 前端路由技术
- 状态管理
- 虚拟DOM
Vue的MVVM
v-if vs v-show
条件渲染:v-if、v-else、v-else-if、v-show。v-show不支持 <template>元素,也不支持v-else
<!DOCTYPE html>
<html>
<head>
<title> new document </title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style>
.bg{
color:red;
}
</style>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
</head>
<body>
<div id="app">
<div v-if="count >= 0">
情况一:count大于等于0,count的值是:{{count}}
</div>
<div v-else-if="count >= -5">
情况二:count大于等于-5且小于0,count的值是:{{count}}
</div>
<div v-else>
情况三:count小于-5,count的值是:{{count}}
</div>
<div v-show="count == -5">满足show的条件,显示show:{{count}}</div>
</div>
<script>
var arr = 'new test';
var app = new Vue({
el:'#app',// 用于挂载要管理的元素
data: { // 定义数据
msg:'hello vue',
count:0
}
})
</script>
</body>
</html>
v-if vs v-show
v-if(判断是否加载)。是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,那么这个元素不会被插入DOM——直到条件第一次变为真时,才会开始渲染条件块。
相比之下, v-show (改的是display的值)就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
v-if 有更高的切换开销,每次插入或者移除元素时都必须要生成元素内部的DOM树,这在某些时候是非常大的工作量。而 v-show 除了有更高的初始渲染开销外没有额外的开销。如果希望频繁地切换某些内容,v-show更好。
v-for
模板中的循环——该指令通过遍历一个数组或者对象,将指令所在的元素循环输出到页面上。
参数顺序:(value, key)
源码:需要哪个循环就写在哪个标签上。比如要<li>循环,那就<li v-for='item in list'>而不是<ul v-for='...'>
list为数组:
<body>
<div id="app">
<div v-for="item in list">{{item}}</div><!--注意这个for...in与js的不太一样。如果是js的话,会输出索引值-->
</div>
<script>
var arr = 'new test';
var app = new Vue({
el:'#app',
data: {
msg:'hello vue',
list:[5,6,7,8,9]
}
})
</script>
list为数组对象:
<body>
<div id="app">
<div v-for="item in list">输出item:{{item}}</div>
<div v-for="item in list">输出名字item.name:{{item.name}}</div>
<!--如果想添加序号,则:v-for = "(item, index) in list"-->
<!--然后引用index即可。注意,index必须在item之后。参数顺序:(value, key)-->
</div>
<script>
var arr = 'new test';
var app = new Vue({
el:'#app',
data: {
msg:'hello vue',
list:[
{
name: '张三',
age:20
},
{
name:'李四',
age:25
},
{
name:'老五',
age:33
}
]
}
})
</script>
输出结果:
v-for与v-show一起使用:
<div id="app">
<div v-for="item in list">
姓名:{{item.name}},年龄:{{item.age}}
</div>
<div v-for="item in list">
<div v-show="item.age > 24">
年龄大于24的人有:{{item.name}}
</div>
</div>
</div>
2-3 模板语法
- v-bind:绑定属性。可用“:”代替
- v-on:绑定事件并进行监听。可用“@”代替
- v-html:不会将标签显示出来,就是显示文本而已
源码:
<!DOCTYPE html>
<html>
<head>
<title> new document </title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style>
.bg{
color:red;
}
</style>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
</head>
<body>
<div id="app">
<div class="bg">
hello world!
{{msg}}
</div>
<div class="bg">
{{msg}}
</div>
{{count}}
<!-- {{template}} -->
<div v-html="template"></div>
<!-- <a v-bind:href='url'>baidu</a> -->
<a :href='url'>baidu</a>
<!-- <button type="button" v-on:click="submit()">数字加1</button> -->
<button type="button" @click="submit()">数字加1</button>
</div>
<script>
new Vue({
el:'#app',
data: {
msg:'hello vue',
count:0,
template:'<p>hello template</p>',
url:'http://www.baidu.com'
},
methods:{
submit:function(){
this.count++;
}
}
})
</script>
</body>
</html>
2-4 计算属性与侦听器
计算属性:computed。在输出data数据前进行的编程
侦听器:watch 侦听器的属性方法有两个参数:newval(新值),oldval(旧值)。可通过F12的Console窗口修改属性,从而激活这个方法
watch还会用在http的请求
使用场景:
watch:异步场景
computed:数据联动(因为加了this)
watch监听的是一个变量或者是一个常量的变化,变量是单一的变量或数组。
computed可以监听很多的变量,但是变量要在vue的实例里面
源码:
<!DOCTYPE html>
<html>
<head>
<title> new document </title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style>
.bg{
color:red;
}
</style>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
</head>
<body>
<div id="app">
{{msg}}
<p>{{msg1}}</p>
</div>
<script>
var arr = 'new test';
var app = new Vue({
el:'#app',
data: {
msg:'hello vue',
another:'this is another'
},
watch:{
msg: function(newvalue, oldvalue){
console.log('newvalue is:' + newvalue);
console.log('oldvalue is:' + oldvalue);
}
},
computed:{
msg1:function(){
return 'computed:'+this.msg + " " + this.another+" "+arr;
}
}
})
</script>
</body>
</html>
最后一个的测试例子:(在chrome的console处运行)
arr = '123';//"123" app.another = 'hohoho';
2-5 条件渲染、列表渲染、Class与Style绑定
-
条件渲染:v-if、v-else、v-else-if、v-show(是用在html里的)。v-show不支持 <template>元素,也不支持v-else(√)
-
列表渲染:v-for、v-for与v-if结合使用、v-for的高阶使用(√)
-
Class与Style绑定:属性绑定用v-bind。v-bind:class="..." 或 v-bind:。效果:自动在html里添加对应的类和css属性
3.属性绑定
<div id="app">
<div v-for="item in list">
姓名:{{item.name}},年龄:{{item.age}}
</div>
<div v-for="item in list">
<div v-show="item.age > 24" : :class="['banana','more',{'another':item.age < 26}]"><!--:class="{'apple':true}"-->
年龄大于24的人有:{{item.name}}
</div>
</div>
</div>
首先:class有两种写法 ①:class="{'类名':(true or false)}" ② :class="['类名','类名',{'类名':(true or false or判断语句)}]"
疑问:类名是不是一定要加单引号?我遇到的大部分都要加,不然是没反应的。如果不加,要另外在data对象里声明类名,比如有:<div v-bind:class="[classA, classB]"></div>,在data对象里增加: classA:'classA', classB:'classB'
绑定的class和style都会加在每个div中,除了another类,因为该类只有年龄小于26才加。style中每个div都会有color和text-shadow属性,但是年龄小于24的张三会多一个“display:none”,所以他的名字没有显示出来。
如果将张三的年龄修改一下,就会显示出来了
v-if vs v-show
v-if(判断是否加载)。是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下, v-show (改的是display的值)就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
Vue.js官方文档
<!DOCTYPE html>
<html lang="en">
<head>
<title> new document </title>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="demo">
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key = 'username-input'>
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key = 'email-input'>
</template>
<button type="button" @click ="change()">Toggle login type</button>
</div>
<script>
var vm = new Vue({
el: '#demo',
data: {
loginType: 'username'
},
methods:{
change: function(){
if(this.loginType == 'username'){
return this.loginType = 'email';
}else{
return this.loginType = 'username';
}
}
}
})
</script>
</body>
</html>
key
属性,具有唯一值。用来表达“这两个元素是完全独立的,不要复用它们”。有key和无key属性的区别:输入框是否被重新渲染。在F12可看出,无key的话每次点击按钮更新的是label和placeholder,有key的话还会更新<div id='demo'>的div
对props里的post不太能理解。谁是父组件,谁是子组件?
<!DOCTYPE html>
<html lang="en">
<head>
<title> new document </title>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="blog-posts-events-demo">
<div :style="{ fontSize: postFontSize + 'em' }">
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
v-on:enlarge-text="postFontSize += 0.1"
></blog-post>
</div>
</div>
<script>
Vue.component('blog-post', {
props: ['post'],
template: `
<div class="blog-post">
<h3>{{ post.title }}</h3>
<button v-on:click="$emit('enlarge-text')">
Enlarge text
</button>
<div v-html="post.content"></div>
</div>
`
})
new Vue({
el: '#blog-posts-events-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
],
postFontSize: 1
}
})
</script>
</body>
</html>
将事件处理函数改成一个方法onEnlargeText:
<!DOCTYPE html>
<html lang="en">
<head>
<title> new document </title>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="blog-posts-events-demo">
<div v-bind:style="{ fontSize: postFontSize + 'em' }">
<blog-post
v-for="post in posts"
v-bind:key = "post.id"
v-bind:post = "post"
+ v-on:enlarge-text = "onEnlargeText"
></blog-post>
</div>
</div>
<script>
Vue.component('blog-post', {
props:['post'],
template:`
<div class="blog-post">
<h3>{{ post.title }}</h3>
+ <button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
<div v-html="post.content"></div>
</div>
`
})
new Vue({
el:"#blog-posts-events-demo",
data:{
posts: [
{ id: 1, title: 'My journey with Vue' ,content:'What is it?'},
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
],
postFontSize: 1
},
+ methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount;
}
}
})
</script>
</body>
</html>
以下来源技术胖的Vue2.x基础免费视频。
视频讲的比较详细了,一个个实例对着做会有收获的。但后面会讲的就比较匆忙了,只介绍每个知识点,没有把知识点串起来。
对应的github练习代码:https://github.com/Clara-hy/exercise/tree/master/Code/Vue
[第一季]P4:v-text & v-html
{{ }}有个弊端,就是当Vue出错或者网速慢没渲染出来时,会将变量名显示到页面。而这一弊端可以用v-text克服。
而v-html是当data数据存在html标签时用的。但工作时一般不用,会遭到xss攻击
P6: v-model数据源绑定
1.双向数据绑定最最简单的例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>v-model实例</h1>
<hr>
<div id="app">
{{message}}<br/>
<p><input type="text" v-model="message"></p>
</div>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
message:'hello world!'
}
});
</script>
</body>
</html>
2.v-model有几个修饰符
2.1 lazy: v-model.lazy懒加载:当鼠标离开文本框时才更新数据
2.2 number: v-model.number:只有当文本框内容是数字时才会实现数据绑定,如果是数字+其他字符,只输出数字。如果是字符串+数字,那会连同字符串一起输出
2.3 trim: v-model.trim:去掉文本框的空格
3. 双向数据绑定常用于表单
P8: v-pre & v-cloak & v-once
v-pre:对{{ message }}进行原样输出,不进行数据的渲染。即以'{{ message }}'的形式输出
v-cloak:渲染完成后才显示
v-once:只进行一次渲染
[第二季:全局API]P9:Vue.directive 自定义指令
P10:Vue.extend 扩展实例构造器
Vue构造器:用来生成Vue的实例对象
vue.extend 通常会和组件结合一起用
P11:Vue.set
Vue.set存在的意义是,当虚拟dom值里只改变数组(如果同时改变其他变量,那vue是能顺便监测到数组变化的),而且是通过下标来改变数组时,vue是监测不到的(实际上是js的缺陷)。所以vue提供了vue.set方法让我们能在外部监测到变化。
P12:钩子函数
最常用的:做loding。通常应用在单页面应用。比如created加载loding动画,在mounted(挂载完成之后)结束动画,然后显示正常界面。
P13:Template制作模板
做组件肯定要做一个模板的???
三种方法:①用反引号直接写html代码:
var app = new Vue({
el:'#app',
data:{
message:'hello world!'
},
template:`
<h2 style="color:red">我是选项模板</h2>
`
});
②在<template>标签里建模板
③在<script>标签里写。注意此处的<script>的type是x-template。不是text/javascript
*P14-17:组件
组件就是自定义的标签(这个说法不太准确)(做组件肯定要做一个模板的?)
组件是一段独立的、代表页面的一个部分的代码片段。它拥有自己的数据、javaScript脚本,以及样式标签。组件可以包含其他的组件,并且它们之间可以相互通信。组件可以是按钮或者图标这样很小的元素,也可以是一个更大的元素,比如在整个网站或者整个页面上重复使用的表单。
Vue实例中的data属性是一个对象,而组件中的data属性是一个函数。这是因为一个组件可以在同一个页面上被多次引用,肯定不希望它们共享一个data对象,不然修改其中一个实例的data属性,结果其他的data属性都跟着被修改就麻烦了。所以组件的data应该是一个函数,在组件初始化时Vue会调用这个函数来生成data对象。
1、定义全局组件。全局的意义是,只要在vue的实例(不同的实例比如id分别为app和ppa)里面应用该组件,该组件都能起作用。但不能脱离vue环境单独存在。
全局与局部的区别:全局组件在构造器外部定义,局部组件在构造器里面定义
2、props属性设置
3、在外部声明局部组件、父子组件关系
4、component标签(要绑定is属性)
【第三季】P18:选项
computed 的作用主要是对原数据进行改造输出。改造输出:包括格式的编辑,大小写转换,顺序重排,添加符号……。注意:不会污染原始数据
methods ①函数传参 ②$event。
③常用方法:对组件(比如btn)用原始方法(methods),比如click,需要@click.native="add",native:调用构造器里的原始方法,此处为调用add()。我们会定义很多UI组件,它没有实际功能。我们把实际功能写到构造器里面,然后用native进行调用。④在构造器外部定义button但想引用构造器里面的方法:利用var app = new Vue({...})的app
watch 方法一:写在构造器里面;方法二:写在构造器外面:app.$watch()
mixins混入选项 主要目的是,不想污染构造器内部的东西,但又要加需求。就会用到mixins。具体的两种应用情景是:①额外加一个需求(mixins)②很多公用的方法。需要进行全局混入(Vue.mixin)
执行顺序:全局混入最先执行、混入其次,原生最后
extends 顺序和mixins大致相同
通常插值形式是{{}}这样的,如果我不想这样,我想以${}这个形式进行插值,只需要在构造器里添加: delimiters:[' ${ ',' } '] 即可
【第四季】 P24实例和内置组件
引入Jquery
介绍实例方法:
①$mount方法:挂载(之前曾用过:vue.extend.html
②$destroy()卸载方法
③$forceUpdate()更新方法
④$nextTick()数据修改方法。和构造器里updated生命周期很像:可以监测到数据被修改,并作出反应
实例事件:在构造器外部写一个调用构造器内部的方法。
①$on:在构造器外部添加事件。需要跟emit配对使用
②$once:执行一次的事件。需要跟emit配对使用
③$off:关闭事件
内置组件slot
两步:①在组件标签里用slot传递值<span slot ="aaa"> ②在模板里接收并显示<slot>aaa</slot>
【混淆点】
- Vue.extend全局扩展里可以有template,用来新建html代码,如果在html里引入变量,需要另外绑定这个变量,要用到data选项,但这里的data是一个匿名函数,返回一个对象
- 选项components是一个对象,对象里的属性要加双引号(字符串。为什么是字符串?因为要给它起一个名字)。选项data里的属性不需要双引号(变量)
- mixins混入 是一个数组,数组里直接就是变量名,不需要加引号。mixins:[...]
- extends扩展 放的是一个对象,和mixins不同。extends: ...
Vue-cli
P31:Vue-router
<router-link>vue提供的导航功能
<router-link to="/">首页</router-link>
<router-view/>显示的是写在router(路由)里的代码。
子路由。若干个子路由的相同点在于都引用了同一个父页面。
参数传递:有3个方法
①$route.name,但不常用
②先对App.vue的router-link的to属性进行绑定":to",to属性值为对象,对象里有name和params,name值必须和路由对应的name一样。params(参数),params值也是一个对象,里面可以有多个,key-value的形式。
比如:<router-link :to="{name:'hi1',params:{username:'Clara',id:'256'}}">Hi页面1</router-link>。然后在相应的页面里传参,比如{{$route.params.username}}
③url传参
——————————————————————————————————————————
从“vue-cli到参数传递”,对应的代码文件夹是vuecliTest。从下面开始对应的文件夹是vuerouter
——————————————————————————————————————————
单页面多路由区域操作,即在App.vue中有多个<router-view>,怎么区分这些<router-view>呢?设置它们的name属性就好啦。在路由文件(index.js)里配置路由的时候,compoents选项的key值要跟前面说的name属性值相同。
url传参
先在路由文件中新增一个路径:{ path:'/params/:newsId/:newsTitle', component:Params }。接着新建一个params.vue,可以在该文件上对url参数进行引用:<p>newsId:{{ $route.params.newsId }}</p>。然后用<router-link>进行页面导航:
<router-link to="/params/198/clara fighting嘻嘻">params</router-link>。就实现传参了。
<template>要用<div>做根节点
vue-router的重定向
分两种,一种是简单的直接redirect,另一种是加了传参的功能
// index.js
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component:HelloWorld
},{//重定向
path:'/goHome',
redirect:'/'
},{//重定向并且加参数
path:'/goParams/:newsId(\\d+)/:newsTitle',
redirect:'/params/:newsId(\\d+)/:newsTitle'
},{//url传参(上节课做的)
path:'/params/:newsId(\\d+)/:newsTitle',//newsId要求必须是数字,如果是"198aa"或者纯字母则会显示失败
component:Params
}
]
});
//App.vue
<template>
//......
<router-link to="/goParams/666/I like vue.js">goPramas</router-link>
</template>
左边:点击"params"。右图:点击"goParams"。
alias别名的使用
alias的作用跟vue-router重定向差不多,但也有一些差别。
区别是,如果用vue-router重定向,比如:{ path:'/goHome', redirect:'/' },那当我点击"goHome"时,它的url和首页的url是一样的。但用alias时,是不同的两个url,这个效果对用户会更加友好。
// index.js
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component:HelloWorld,
alias: '/home1'
}
//.......
]
});
//App.vue
<template>
//......
<router-link to="/home1">home1</router-link>
</template>
效果图:
路由过渡动画
mode、opacit实现淡入淡出
mode的作业和404页面的处理
// index.js
export default new Router({
routes: [
{
path:'*', //新增
component:Error
}
//.......
]
});
//Error.vue
<template>
<div>
<h2>{{ msg }}</h2>
页面不存在!
</div>
</template>
<script>
export default {
data(){
return{
msg:'Error:404'
}
}
}
</script>
路由中的钩子
有两个:①进路由前 ②离开路由前
配置也有两种方法:①在路由配置文件(index.js)中写钩子函数(在这个文件只能写beforeEnter,不能写“离开路由前”) ②在模板中写钩子函数(两个钩子函数都能写,比较通用)
钩子函数的参数:to,from,next。next相当于一个开关,指定能否跳转next(true) or next(false)以及跳转到哪里next({path:"/"})。
编程式导航
在App.vue里的script里写跳转链接。比如栗子一:实现“前进”、“后退”:this.$router.go(-1);页面的按钮。栗子二:登录成功后跳转到某一页面:this.$router.push('/xxx');
P42Vuex
组件之间的所有通信都采用事件(events)方式(子组件往父组件通信)和属性(props)方式(父组件往子组件通信),简单的应用场合还行,但稍微复杂一点就不太行了。
vuex:数据仓库,管理的是状态,也叫状态管理器。应用在中大型项目、数据共用的地方。
state:访问状态对象
//@/vuex/store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);//vuex已经集成到我项目中啦!
// 状态对象
const state={
count:1
}
// 要改变state里的值需要用到mutations里的方法
// mutations:改变状态对象的方法
const mutations={
add(state){
state.count++;
},
reduce(state){
state.count--;
}
}
export default new Vuex.Store({
state,
mutations
})
// @/components/count.vue
<template>
<div>
<h2>{{msg}}</h2><hr>
<h3>{{$store.state.count}}</h3>
<p>
<button @click="$store.commit('add')">add</button>
<button @click="$store.commit('reduce')">reduce</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store';
export default{
data(){
return{
msg:'Hello Vuex'
}
},
store
}
</script>
问题来了:如何将count.vue的<template>里的{{$store.state.count}}转换成{{count}}使用呢?三种方法:
//count.vue
//方法一
<script>
import store from '@/vuex/store';
+ import { mapState } from 'vuex';
export default{
data(){
return{
msg:'Hello Vuex'
}
},
store,
+ computed:{
count(){
return this.$store.state.count;
}
}
}
//方法二
computed:mapState({
count: state=>state.count
})
//方法三
computed:mapState(['count'])
对于mutations有两点:①传参 ②简化
①add(state, n)
//store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);//vuex已经集成到我的项目中啦!
// 状态对象
const state={
count:1
}
const mutations={
+ add(state,n){
+ state.count += n;
},
reduce(state){
state.count--;
}
}
export default new Vuex.Store({
state,
mutations
})
//count.vue
<template>
//...
<button @click="$store.commit('add',10)">add+10</button>
</template>
②简化 :将$store.commit('reduce')简化成reduce
//count.vue
//方法一
<script>
import store from '@/vuex/store';
+ import {mapState, mapMutations} from 'vuex';
export default{
data(){
return{
msg:'Hello Vuex'
}
},
store,
computed:mapState(['count']),
+ methods:mapMutations(['add','reduce'])
}
getter计算过滤操作:相当于对状态对象进行computed操作
actions异步修改状态(学的有点自闭了...学的点好多而且看起来没联系的东西
module模块组(小项目貌似没必要用)
【疑问】
$route和$router都有用到,有什么区别
https://blog.csdn.net/zzz_zed/article/details/78885944、https://www.jianshu.com/p/55d41142a147
$route为当前router跳转对象里面可以获取name、path、query、params等
$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法
返回上一个history也是使用$router.go方法
【webpack的笔记临时存放点】
dependencies:生产环境(对象是用户)
devDependencies:开发环境
Step1:npm init
Step2:npm install --save-dev webpack
如何更新webpack版本?
- 对新项目:将node_modules文件夹删了,重新npm install --save-dev webpack
- 对老项目:先在package.json中将webpack的版本号修改为最新版,然后删node_modules文件夹......
删除node_modules之后,重新npm install(此时会自动根据package.json新建一个node_modules文件夹)
【如何用vue-cli建项目】前提是已经安装了vue-cli,如何检测是否安装好了:vue -V。安装命令:npm install vue-cli -g
- vue init webpack XXX(文件名,可大写) 这个命令之后会要求填写一些东西,比如项目名,该名不要大写和斜杠
- cd XXX
- npm install(将安装package.json里所有的依赖包,放置在node_modules,上传github时node_modules不用上传)
- (引用vuex)npm install vuex --save(--save是为了让vuex放到生产环境中)