创建Vue脚手架

第一步(仅第一次执行):全局安装@Vue/cli

npm install -g @vue/cli

第二步:切换你要创建项目的目录,然后用命令创建项目

vue create xxxx

第三步:启动项目

npm run serve

如果下载缓慢请使用npm淘宝镜像

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

Vue脚手架隐藏了所有webpack相关的配置,若想查看具体配置

vue inspect > output.js

脚手架文件结构


├── node_modules

├── public

│ ├── favicon.ico: 页签图标

│ └── index.html: 主页面

├── src

│ ├── assets: 存放静态资源

│ │ └── logo.png

│ │── component: 存放组件

│ │ └── HelloWorld.vue

│ │── App.vue: 汇总所有组件

│ │── main.js: 入口文件

├── .gitignore: git版本管制忽略的配置

├── babel.config.js: babel的配置文件

├── package.json: 应用包配置文件

├── README.md: 应用描述文件

├── package-lock.json:包版本控制文件

关于不同版本的Vue

vue.js与vue.runtime.xxx.js的区别:

vue.js是完整版的Vue,包含:核心功能 + 模板解析器。

vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。

vue.config.js配置文件

使用vue inspect > output.js可以查看到Vue脚手架的默认配置。

使用vue.config.js可以对脚手架进行个性化定制,详情见:Vue CLI

ref 属性

被用来给元素或子组件注册引用信息(id的替代者)

应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)

使用方式:

① 打标识:# .....<School ref="xxx"></School>

② 获取:this.$refs.xxx

props配置项

功能:让组件接收外部传过来的数据

传递数据:<Demo name="xxx"/>

接收数据:

第一种方式(只接收):props:['name']

第二种方式(限制类型):props:{name:String}

第三种方式(限制类型、限制必要性、指定默认值):


props:{

name:{

type:String, //类型

required:true, //必要性

default:'老王' //默认值

}

}

备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

mixin(混入)

功能:可以把多个组件共用的配置提取成一个混入对象

使用方式:

第一步定义混合:


// 新建js文件,定义方法数据等,需要暴露

export default {

data(){....},

methods:{...}

...

}

第二步使用混入:

全局混入:


import mixina from './mixin'

Vue.mixin(mixina);

new Vue({

render: h => h(App),

}).$mount('#app')

局部混入:mixins:['xxx']

插件

功能:用于增强Vue

本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。

定义插件:


对象.install = function (Vue, options) {

// 1. 添加全局过滤器

Vue.filter(....)

// 2. 添加全局指令

Vue.directive(....)

// 3. 配置全局混入(合)

Vue.mixin(....)

// 4. 添加实例方法

Vue.prototype.$myMethod = function () {...}

Vue.prototype.$myProperty = xxxx

}

使用插件:Vue.use()

scoped样式

作用:让样式在局部生效,防止冲突。

写法:``

TodoList案例

组件化编码流程:

(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。

(2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:

1).一个组件在用:放在组件自身即可。

2). 一些组件在用:放在他们共同的父组件上(状态提升)。

(3).实现交互:从绑定事件开始。

props适用于:

(1).父组件 ==> 子组件 通信

(2).子组件 ==> 父组件 通信(要求父先给子一个函数)

使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!

props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

浏览器本地存储

Cookie是最早被提出来的本地存储方式,在此之前,服务端是无法判断网络中的两个请求是否是同一用户发起的,为解决这个问题,Cookie就出现了。

Cookie 是存储在用户浏览器中的一段不超过 4 KB 的字符串。它由一个名称(Name)、一个值(Value)和其它几个用 于控制 Cookie 有效期、安全性、使用范围的可选属性组成。

不同域名下的 Cookie 各自独立,每当客户端发起请求时,会自动把当前域名下所有未过期的 Cookie 一同发送到服务器。

Cookie的特性

Cookie一旦创建成功,名称就无法修改

Cookie是无法跨域名的,也就是说a域名和b域名下的cookie是无法共享的,这也是由Cookie的隐私安全性决定的,这样就能够阻止非法获取其他网站的Cookie

每个域名下Cookie的数量不能超过20个,每个Cookie的大小不能超过4kb

有安全问题,如果Cookie被拦截了,那就可获得session的所有信息,即使加密也于事无补,无需知道cookie的意义,只要转发cookie就能达到目的

Cookie在请求一个新的页面的时候都会被发送过去

客户端第一次请求服务器的时候,服务器通过响应头的形式,向客户端发送一个身份认证的 Cookie,客户端会自动 将 Cookie 保存在浏览器中。

随后,当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的 Cookie,通过请求头的形式发送给 服务器,服务器即可验明客户端的身份。

由于 Cookie 是存储在浏览器中的,而且浏览器也提供了读写 Cookie 的 API,因此 Cookie 很容易被伪造,不具有安全性。因此不建议服务器将重要的隐私数据,通过 Cookie 的形式发送给浏览器。

注意:千万不要使用 Cookie 存储重要且隐私的数据!比如用户的身份信息、密码等。

Session

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了session是一种特殊的cookie。cookie是保存在客户端的,而session是保存在服务端。

为什么要用session

由于cookie 是存在用户端,而且它本身存储的尺寸大小也有限,最关键是用户可以是可见的,并可以随意的修改,很不安全。那如何又要安全,又可以方便的全局读取信息呢?于是,这个时候,一种新的存储会话机制:session 诞生了

session原理

当客户端第一次请求服务器的时候,服务器生成一份session保存在服务端,将该数据(session)的id以cookie的形式传递给客户端;以后的每次请求,浏览器都会自动的携带cookie来访问服务器(session数据id)。

LocalStorage

LocalStorage是HTML5新引入的特性,由于有的时候我们存储的信息较大,Cookie就不能满足我们的需求,这时候LocalStorage就派上用场了。

LocalStorage的优点:

在大小方面,LocalStorage的大小一般为5MB,可以储存更多的信息

LocalStorage是持久储存,并不会随着页面的关闭而消失,除非主动清理,不然会永久存在

仅储存在本地,不像Cookie那样每次HTTP请求都会被携带

LocalStorage的缺点:

存在浏览器兼容问题,IE8以下版本的浏览器不支持

如果浏览器设置为隐私模式,那我们将无法读取到LocalStorage

LocalStorage受到同源策略的限制,即端口、协议、主机地址有任何一个不相同,都不会访问

LocalStorage的常用API


// 保存数据到 localStorage

localStorage.setItem('key', 'value');

// 从 localStorage 获取数据

let data = localStorage.getItem('key');

// 从 localStorage 删除保存的数据

localStorage.removeItem('key');

// 从 localStorage 删除所有保存的数据

localStorage.clear();

// 获取某个索引的Key

localStorage.key(index)

LocalStorage的使用场景

有些网站有换肤的功能,这时候就可以将换肤的信息存储在本地的LocalStorage中,当需要换肤的时候,直接操作LocalStorage即可

在网站中的用户浏览信息也会存储在LocalStorage中,还有网站的一些不常变动的个人信息等也可以存储在本地的LocalStorage中

SessionStorage

SessionStorage和LocalStorage都是在HTML5才提出来的存储方案,SessionStorage 主要用于临时保存同一窗口(或标签页)的数据,刷新页面时不会删除,关闭窗口或标签页之后将会删除这些数据。

SessionStorage与LocalStorage对比:

SessionStorage和LocalStorage都在本地进行数据存储;

SessionStorage也有同源策略的限制,但是SessionStorage有一条更加严格的限制,SessionStorage只有在同一浏览器的同一窗口下才能够共享;

LocalStorage和SessionStorage都不能被爬虫爬取;

SessionStorage的常用API


// 保存数据到 sessionStorage

sessionStorage.setItem('key', 'value');

// 从 sessionStorage 获取数据

let data = sessionStorage.getItem('key');

// 从 sessionStorage 删除保存的数据

sessionStorage.removeItem('key');

// 从 sessionStorage 删除所有保存的数据

sessionStorage.clear();

// 获取某个索引的Key

sessionStorage.key(index)

SessionStorage的使用场景

由于SessionStorage具有时效性,所以可以用来存储一些网站的游客登录的信息,还有临时的浏览记录的信息。当关闭网站之后,这些信息也就随之消除了。

组件的自定义事件

一种组件间通信的方式,适用于:子组件 => 父组件

使用场景

A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

绑定自定义事件:

第一种方式

在父组件中使用 <Demo @atguigu="test"/><Demo v-on:atguigu="test"/>


// app.vue





<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->

<Student @atguigu="getStudentName"/>







import Student from './components/Student'

export default {

name:'App',

components:{Student},

data() {

return {

msg:'你好啊!',

studentName:''

}

},

methods: {

getStudentName(name,...params){

console.log('App收到了学生名:',name,params)

this.studentName = name

}

}

}





.app{

background-color: gray;

padding: 5px;

}




// Student.vue





把学生名给App







export default {

name:'Student',

data() {

return {

name:'张三',

}

},

methods: {

sendStudentlName(){

//触发Student组件实例身上的atguigu事件

this.$emit('atguigu',this.name,666,888,900)

}

},

}





.student{

background-color: pink;

padding: 5px;

margin-top: 30px;

}



第二种方式

在父组件中使用 this.$refs.xxx.$on(),这样写起来更灵活,比如可以加定时器啥的。


<Demo ref="xxx"/>

mounted(){

this.$refs.xxx.$on('mydemo',this.test) // 利用标识绑定事件

}

若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

触发自定义事件:this.$emit('atguigu',数据)

使用 this.$emit() 就可以实现子组件向父组件传数据

解绑自定义事件this.$off(‘atguigu’)


this.$off('atguigu') //解绑一个自定义事件

// this.$off(['atguigu','demo']) //解绑多个自定义事件

// this.$off() //解绑所有的自定义事件

组件上也可以绑定原生DOM事件,需要使用native修饰符。


<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->

<Student ref="student" @click.native="show"/>

注意:通过this.$refs.xxx.$on('atguigu',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!