尤雨溪 (EvanYou)
美籍华人
Vue Technology LLC 创始人
高中:上海复旦大学附中
大学:纽约科尔盖特大学
发展历程
1.2014 年 2 月
尤雨溪开源了一个前端开发库 Vue.js。Vue.js 是构建 Web 界面的 JavaScript 库,也是一个通过简洁的 API 提供高效数据绑定和灵活组件的系统。
2.2016 年 9 月
在南京的 JSConf 上,尤雨溪正式宣布以技术顾问的身份加盟阿里巴巴 Weex 团队,来做 Vue 和 Weex 的 JavaScript runtime 整合,目标是让大家能用 Vue 的语法跨三端。
2020 年 4 月
Vue3.0beta版本测试发布。
Vue.js是一款轻量级的、以数据驱动的、前端JS框架,是一个通过简洁的API提供高效的数据绑定和灵活的组件系统。
旧:Jquery
操作DOM元素
jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的
复杂页面维护成本大
jquery则需要获取dom元素节点,并对dom进行添加一个标签的操作,如果dom结构特别复杂,或者添加的元素非常复杂,则代码会变得非常复杂且阅读性低。
很难达到组件化页面
JQuery 时代的代码大部分情况下是面条代码,耦合严重
性能损耗
损耗浏览器资源
新:Vue.js
数据与视图分离
Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。
数据双向绑定
这也就是vue.js最大的优点,通过MVVM思想实现数据的双向绑定,让开发者不用再操作dom对象,有更多的时间去思考业务逻辑。
灵活的组件化
Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件中,我们只要先在父级应用中写好各种组件标签,并且在组件标签中写好要传入组件的参数,然后再分别写好各种组件的实现,然后整个应用就算做完了。
虚拟DOM,运行更快
Virtual DOM,是一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM
轻量级的框架
能够自动追踪依赖的模板表达式和计算属性,提供 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API,使读者更加容易理解,能够更快上手。
双向数据绑定
声明式渲染是数据双向绑定的主要体现,同样也是 Vue.js 的核心,它允许采用简洁的模板语法将数据声明式渲染整合进 DOM。
客户端路由
Vue-router 是 Vue.js 官方的路由插件,与 Vue.js 深度集成,用于构建单页面应用。Vue 单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来
指令
Vue.js 与页面进行交互,主要就是通过内置指令来完成的,指令的作用是当其表达式的值改变时相应地将某些行为应用到 DOM 上。
组件化
可随时引用,通过传入参数实现不同的页面,可子父引用。
状态管理
状态管理实际就是一个单向的数据流,State 驱动 View 的渲染,而用户对 View 进行操作产生 Action,使 State 产生变化,从而使 View 重新渲染,形成一个单独的组件。
1.进入官网
https://nodejs.org/en/
2.安装msi,安装目录到C盘
安装好后,使用cmd执行 node- v npm -v看看是否都输出了版本号
3.在除C盘外创建一个nodejsFile文件夹,创建两个文件夹 node_global和node_cache,然后运行以下命令
npm config set prefix "D:\Program Files\nodejs\node_global"
npm config set cache "D:\Program Files\nodejs\node_cache"
4.检查当前系统变量中,path路径有没有叫C:\ProgramFiles\nodejs\node_modules
如果有,创建一个同名路径文件夹在C盘之外的盘符,如果没有就不用管了
- 在path变量中配置你的C:\Program Files\nodejs\node_modules路径
功能:和npm一样,npm是从海外镜像仓库下载,cnmp 是从阿里淘宝镜像仓库下载
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装完成使用:cnpm -v 查看版本
npm install webpack -g
安装完成使用:npm webpack -v 查看版本
1.下载脚手架资源
cnpm install -g [email protected]
2.去到你的gloab目录查看是否有vue开头的文件
- 到别的文件夹下创建一个空的文件夹,在文件夹中按住shift+鼠标右键,点击在此处打开pwershell窗口
- 打开窗口输入:vue init webpack
5.初始化构建vue脚手架
6.运行vue项目
在项目根目录下按住shift+鼠标右键,点击在此处打开pwershell窗口,执行 npm run dev
下载VsCode
https://code.visualstudio.com/
组件下载
创建vue项目
vue init webpack
会出现错误:not promite 。。。。 vsCode终端控制台没有系统写入权限
使用本机自带的cmd窗口使用管理员权限启动
将目录跳转至项目路径再执行vue init webpack指令
5.启动项目
npm run dev
6.退出运行
ctrl+c
文件–》首选项—》配置用户代码片段
{
"Print to console": {
"prefix": "myvue",// 代码段名称
"body": [ //代码内容
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
],
"description": "myvue"
}
}
作用:vue项目首页,可以编写全局项目中公共的样式
注意:一般如果项目集成了路由功能,app.vue只会写一个路由标签
作用:配置通用组件的引入、vue通用配置
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
// 创建vue,绑定主视图
// 脚手架项目中vue实例只会有一个,存在main.js中
new Vue({
el: '#app',
router,
components: { App },
template: ' '
})
每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例 启动的
- 实例化组件
- beforeCreate 创建前
- 开启数据监听
- 初始化vue内部方法
- created 创建完成
vue中使用钩子函数
123
vue选择渲染模板,是要使用vue组件的方式渲染还是只是渲染部分html
1.beforeMount - dom元素渲染之前
开始渲染
- mounted - dom挂载结束
123
监听器会监听所有data值的变化
1.beforUpdate - 数据更新之前
使用VDom手段动态渲染html
- updated - 数据渲染完成
{{ name }}
注意:组件默认情况下不会主动销毁,需要借助v-if指令或者,Vue.$destroy()才会触发vue的销毁流程
- 组件是否进入销毁流程(v-if指令或者,Vue.$destroy())
- beforeDestroy - 销毁之前
- 进行销毁 - 组件中所有的data值缓存都会消失、vdom缓存也会清除
- destroyed - 销毁结束
#取消 Vue 所有的日志与警告 - 开发不要配,生产环境配
Vue.config.silent = true
#配置是否允许 vue-devtools 检查代码 - 开发不要配,生产环境配
Vue.config.devtools = true
#指定组件的渲染和观察期间未捕获错误的处理函数-全局异常处理回调
Vue.config.errorHandler = function (err, vm, info){}
#设置为 false 以阻止 vue 在启动时生成生产提示 - 开发不要配true,生产环境配
Vue.config.productionTip = false
语法:{{ 数据变量名称 }}
是将vue绑定的数据渲染到视图产生关联,实现双向绑定
大家好我叫:{{ name }}
编写位置:插值表达式存在的开始标签中
作用:让插值表达式里的值不会根据data的变化而渲染,永远保持第一次加载的值
{{ name }}
// 蔡徐坤123
大家好我叫:{{ name }}
// 蔡徐坤
注意:{{ XXX }}解析的过程只会按照纯文本方式解析,如果要解析html代码段加载到dom中,需要使用v-html指令
// XXX.html("xxx")
注意:title={{ xxxx }}不行,插值表达式不能使用在属性值以及属性名称上,标签位置上都不能使用插值表达式
那如果需要动态绑定一个数据给标签的属性值怎么办?就要使用v-bind指令
欢迎访问网站
v-bind指令可以简写为":"
欢迎访问网站
当点击时动态绑定一段js代码
借助v-bind来实现
欢迎访问网站
编写的位置:开始标签中在标签的属性位置编写
复杂写法:
欢迎访问网站
简单写法:v-on用@替代
如:当点击时触发函数 @click=“函数”
欢迎访问网站
敲击回车,实现方法调用
欢迎访问网站
js中所有keycode列表
https://blog.csdn.net/fghyibib/article/details/120670221?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-1-120670221-blog-122497397.pc_relevant_multi_platform_whitelistv3&spm=1001.2101.3001.4242.2&utm_relevant_index=4
v-if:
true: 标签或者组件被挂载
false:标签或者组件删除或销毁v-show: 通过display样式控制组件显示隐藏
true: 标签或者组件 - 显示状态
false:标签或者组件 - 被隐藏
欢迎访问网站
欢迎访问网站2
当v-if值为true时:组件会进入创建阶段—渲染阶段
如果父组件加载子组件时,子组件被v-if=“false” 描述时,子组件是不会被加载
当v-if值为false是:组件会进入销毁阶段
当v-show值为true时:组件被显示-不会调用生命周期钩子
如果父组件加载子组件时,子组件被v-show=“false” 描述时,子组件会加载但是不显示而已
当v-show值为false是:组件被隐藏-不会调用生命周期钩子
多条件判断指令
注意:v-if v-els-if v-else要注意编写的顺序和数量,v-else只能有一个,v-else-if可以有多个
注意标签之间的顺序,不要有间隔
// 独立的判断
123
//2 行 一组判断逻辑
v-for=“(循环中的每个对象,循环遍历的下标) in 要循环的集合数组”
简写-只取出集合中的对象: v-for=“循环中的每个对象 in 要循环的集合数组”
循环中必填参数
key:描述循环的标签是独一无二的,只要绑定一个唯一值属性即可,提供给VDom更新元素
编号
姓名
年龄
{{item.id}}
{{item.name}}
{{item.age}}
v-for=“(对象的属性值,对象的属性名称,属性的序号) in 要迭代对象” :key=“唯一值”
[{{index}}]{{key}}====={{value}}
在传统H5开发的方式下,表单的值一般是用value属性控制,但是进过测试动态绑定表单标签的value属性无法实现表单值的变化,这时我们需要使用v-model指令实现表单数据的动态绑定
注意:使用vue后,表单元素绑定数据就要使用v-model而不要再使用value属性了
效果:当填写完成,选中效果移除之后数据才更新
<input v-model.lazy="name"/>
效果:在填写文本时,只能填写数字
注意:只有填写文字是数字开头才有用,而且从数字开头截取字符直到出现第一个非数字位置结束,如:1a2b ===> 1
<input v-model.number="name"/>
推荐如果是纯数字校验,使用type=“number”
<input type="number" v-model.number="name"/>
去除前后空格的方式
<input v-model.trim="name"/>
<select v-model="name">
<option :value="1">昆明option>
<option :value="true">临沧option>
<option value="3">蒙自option>
select>
男
女
吃鸡
lol
王者别嚣张
目的:可以改写插值表达式的显示内容
{{ userData.name | nameFilter | nameFilter2 }}
点击查看用户信息
计算属性使用场景:
和过滤器比较:
过滤器:参数只能是插值表达式中|之前的值注入到过滤器的参数中,过滤器无法访问data绑定的数据
计算属性:参数可以是在计算属性调用时的实参也可以访问data绑定的数据(this访问)
使用计算属性-无参的方法
{{ nameComputed }}
//计算属性
computed:{
//自定义计算属性
nameComputed:function(){
return this.userData.name.split('').reverse().join('');
}
}
使用计算属性-可以传递参数的方法
{{ nameComputed("1",1,3) }}
//计算属性
computed:{
//自定义计算属性
nameComputed(){
return function(value,value2,value3){
console.dir(value);
return this.userData.name.split('').reverse().join('');
}
}
}
是可以的,但是推荐使用计算属性完成
计算属性:
计算属性会使用浏览器缓存进行数据的存储和计算
计算属性可以根据行为是读取还是参数赋值区分出get和set两种方法模式
mycomputed:{
get:function(){// 无参调用计算属性时触发
console.dir("get");
return "get";
},
set:function(){// 有参调用计算属性触发
console.dir("set");
return "set";
}
}
而方法每次调用都需要经过函数执行的读写,没有任何缓存的实现,所以性能较差,当开发目的只是为了改变插值表达式的值内容的情景时,推荐使用计算属性完成
作用:监听data绑定数据的变化
注意:要监听的数据如果保存在对象中话写法有所区别
{{ userData.age }}
{{ aa }}
多组件共用data值的时候会使用
"userData.data.data.age":{
immediate:true,// 深度监听立即执行
deep: true,// 开启深度监听
handler(newVal,oldVal){
console.dir(newVal+"-----"+oldVal);
}
}
在昨天的学生信息列表功能下实现前端的:添加、编辑功能
- 添加功能:
- 在表格上方会有一个添加按钮
- 点击添加按钮弹出一个div,里面有学生信息添加内容的表单以及保存、重置表单按钮
- 填写完数据点击保存,弹窗关闭,表格数据刷新
- 编辑功能
- 表格中多一列操作列
- 操作列对应每一行中有编辑按钮
- 点击编辑弹出编辑div,里面有学生信息编辑内容的表单以及保存编辑
- 填写完数据点击保存,弹窗关闭,表格数据刷新
- 实现添加表单和编辑表单公用一个div和表单内容,通过判断实现
数组中可以使用表达式完成样式的选择
子组件代码
测试页面1
父组件代码
子组件要定义能接收的数据有些什么(组件参数)
props属性定义
注意:子父组件值传递是值的拷贝,不会传递地址
子组件写法
测试页面1{{ name }}
父组件传递方法
当子组件点击关闭按钮时,父组件要接收关闭事件的回调
需要子组件通知父组件,有事情发生,让父组件能够接收这个消息
能实现子组件将数据传递到父组件
案例:点击子组件的关闭按钮,实现父组件div隐藏
子组件代码
父组件代码
- 定义一个子组件,功能是:通过父组件传递的列表数据实现一个动态下拉框
- 当下拉框选中数据时,要回调一个时间给父组件(change\selected)
- 实现下拉框清空功能,点击清空清空select选择的内容,然后回调一个事件给父组件(clear\qingkong)
4.子组件定义好后,父组件引入组件,试用是否正常
route:首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;( 单个路由信息 )
routes:它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;所以我们记住了,routes表示多个数组的集合;(整个项目中的所有路由信息)
router:译为路由器,上面都是路由,这个是路由器,我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由;(对象,可以实现路由的多种功能跳转)
什么地址可以访问哪个组件,描述一下路由信息
- 编写组件页面
2.打开路由配置文件
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
//1. 导入需要配置路由的组件
import Test2 from '@/components/Test2.vue';
Vue.use(Router)
export default new Router({
// 所有路由信息-集合
routes: [// 第一个路由记录就是欢迎页
{
path: '/',
name: 'HelloWorld',
component: HelloWorld,
meta:{
index:0,
name:"首页"
}
},
{// 2.编写路由
path: '/test2',// 访问路径
name: 'Test2', //路由组件名称
component: Test2, //关联组件
meta:{
index:1, // 组件顺序-按照组件关系写
name:"测试页面2" // 路由组件名称-中文描述-提供面包屑使用
}
}
]
})
export default new Router({
mode: 'history',// 路由地址前面就不会有/#/
<router-link to="/test2">跳转到test2页面router-link>
puish方法- 是会把路由跳转的记录添加到浏览器的缓存记录中的,就可以使用浏览器的前进和后退功能
replace方法-则不会将访问的数据添加到记录中
和push用法相同
// 字符串
this.$router.replace('/home/first')
// 对象
this.$router.replace({ path: '/home/first' })
// 命名的路由
this.$router.replace({ name: 'home', params: { userId: wise }})
//前进一步 相当于history.forward()
this.$router.go(1)
、
//后退一步 相当于history.back()
this.$router.go(-1)
this.$router.go(10)
使用场景: 企业管理系统后端,左侧菜单右侧组件刷新的界面
主页:
主页
用户管理
角色管理
路由配置
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Main from '@/components/main'
//1. 引入组件
import User from '@/components/user'
import Role from '@/components/role'
Vue.use(Router)
export default new Router({
mode: 'history',// 路由地址前面就不会有/#/
// 所有路由信息-集合
routes: [// 第一个路由记录就是欢迎页
{
path: '/',
name: 'HelloWorld',
component: HelloWorld,
meta:{
index:0,
name:"登录页面"
}
},
{
path: '/main',
name: 'Main',
component: Main,
meta:{
index:1,
name:"首页"
},
children:[// 子路由!!!!!!!
{
path: '/user',
name: 'User',
component: User,
meta:{
index:1-1,
name:"用户管理"
}
},
{
path: '/role',
name: 'Role',
component: Role,
meta:{
index:1-2,
name:"角色管理"
}
}
]
}
]
})
路由配置文件中,在path属性上声明会出现参数的位置
{
path: '/:id', // 在/ 路径之后 会传递一个 名字叫id的参数
name: 'HelloWorld',
component: HelloWorld,
meta:{
index:0,
name:"登录页面"
}
},
调用路由跳转是传递参数
注意:只能传递简单的字符串和数值、boolean类型,不能传递对象
this.$router.push({ path:`/main/${this.param}`});
目标路由组件中获取参数
<!-- Dom页面 -->
<template>
<div id="Main">
<h1>主页</h1>
<h1>{{ $route.params.id }}</h1>
</div>
</template>
路由配置文件就不用修改了
调用路由跳转方法
该方法是支持对象传递的
// 想要使用params传递参数,路由跳转的方法必须使用name指定路由页面才行
this.$router.push({ name:"Main",params:this.param});
路由配置文件就不用修改了
调用路由跳转方法
该方法是支持对象传递的
this.$router.push({ path:"/main",query:this.param});
路由目标页面取参数,要通过query参数取得
this.loginUser = this.$route.query.name;
总结路由传参3种方法:
1.路径拼接法: 如果面有必须要初始化或者必须传递参数才能使用的场景时在使用
2.params方法:对传递的参数进行加密,但是数据传输是一次性的
3.query方法:对参数没有进行加密,直接暴露在url中
this.$router.options.routes
能够访问当前项目的所有路由信息
在项目的窗口中执行
cnpm install nprogress
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'// nprogress样式文件
两个钩子:路由跳转前和跳转后
// 路由的钩子函数是main.js中配置的
// 路由跳转之前
router.beforeEach((to, from , next) => {
// 开启进度条
NProgress.start();
// 这个一定要加,没有next()页面不会跳转的。这部分还不清楚的去翻一下官网就明白了
next();
});
//当路由跳转结束后
router.afterEach(() => {
// 关闭进度条
NProgress.done()
})
- 需要实现一个增删改查分页的表格组件
作用: 与ajax一样,底层实现就是js-ajax,写法要比之前学习的JQuery、js的ajax都要简单
//1. 在项目窗口中执行
cnpm install axios
main.js中配置axios内容
import axios from 'axios'
Vue.prototype.$axios = axios //全局属性
全局属性的定义方法
在main.js中定义
// 定义全局属性的方法
// Vue.prototype.自定义属性名 = 组件对象
// 属性命名规则:$+属性名
// 在组件中使用全局属性: this.$axios
Vue.prototype.$axios = axios //全局属性
什么是跨域?
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
注意: 协议+主机+端口有一个不相同就会出现跨域问题
1.配置BaseUrl,在main.js文件中
axios.defaults.baseURL = '/api' //关键代码,/api之后替换的就是 http://localhost:8090
2.配置代理,在config文件夹下的index.js文件中的proxyTable字段
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: { // 配置到这里!!!!
'/api': {// 配置了一个静态地址代理
target:'http://localhost:8090', // 后端服务地址以及端口号
changeOrigin:true, // 可以跨域
pathRewrite:{
'^/api': ''
}
}
},
- main.js 修改 axios全局属性的创建方法
Vue.prototype.$axios = axios.create({
baseURL:'/api',
timeout:30000
})
- 把项目停止,执行cnpm install ,再启动项目
- 测试案例
getData() {
console.dir(this);
// 在axios代码中要使用this关键字访问data或者方法等等vue组件内容的话需要定一个别名变量
let _this = this;
this.$axios
.get("goods/goods/getGoodsByID?id=101")
.then(function(res) {
_this.resData = res.data;
})
.catch(function(error) {
// 请求失败处理
console.log(error);
});
}
- 参数拼接在url后面
// 直接在 URL 上添加参数 ID=12345
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
- 传入一个有params属性的参数
this.$axios
.get("goods/goods/getGoodsByID",{
params:{// 写键值对参数内容
id:101
}
})
请求已经将数据封装为json数据发送后端了,所以在后端编写controller方法时,记得要使用@RequestBody注解接收参数
put\delete请求写法和post一致
this.$axios
.post("goods/goods/testpost",{ // 参数传递的方法和GET不同
name:"张三",
price:18.9
})
需要使用的是axios组件对象的all方法,而以上案例中使用的$axios对象是通过组件对象.create创建的实例
所以我们需要从新定义一个全局的axios组件对象
main.js中定义组件对象全局属性
Vue.prototype.$VueAxios = axios; // all 再用该对象 新配置的组件对象
Vue.prototype.$axios = axios.create({// get post delete put
baseURL:'/api',
timeout:30000
})
批量接口调用方法
getData1() {
return this.$axios
.post("goods/goods/testpost",{
name:"张三",
price:18.9
});
},
getData2() {
return this.$axios.get("goods/goods/getGoodsByID?id=101");
},
//合并提交方法
getAllData(){
let _this = this;
console.dir(this.$axios);
this.$VueAxios.all([_this.getData1(),_this.getData2()]) // 按照数组顺序调用
.then(_this.$VueAxios.spread(function (res1, res2) { // 根据调用方法的数量定义接收对应方法返回的数据参数
// 当所有的方法执行完成且都有返回值之后
console.dir("请求完成");
console.dir(acct);
console.dir(perms);
}));
}
请求拦截器的作用
在axios发送请求到后端之前进行拦截,可以修改请求的参数等内容
写在main.js中
// http request 请求拦截器
axios.interceptors.request.use(config => {
// 在发送请求之前做些什么
return config;
}, error => {
// 对请求错误做些什么
return Promise.reject(error);
});
作用:
所有的请求返回响应时都会进入改拦截器
// 响应拦截器
Vue.prototype.$axios.interceptors.response.use(response => {
console.dir(response);
if(response.data.code == "9999"){//系统异常
// 统一错误提示弹窗
}else if(response.data.code == "-1"){ // 登录会话失效
// 使用路由返回到登录页面
}
return response;
},error => {
if (error.response) {
// 返回接口返回的错误信息
return Promise.reject(error.response.data);
}
});
v-model: 只能在表单功能上出现
案例:子组件实现性别单选,v-model实现绑定性别的code值,子父组件修改v-model绑定的子父数据都会改变
子组件写法
男
女
父组件
<Test1 v-model="data" />
作用:能够将指定的标签放置在组件的插槽容器中,可以规范组件内容组成也可以灵活配置组件内容
<slot>。。slot>
也叫无具名插槽,一般用在父组件快速批量替换子组件默认内容时使用
子组件定义
<template>
<div id="Test1">
<div class="div1">
<slot>默认插槽的文字1slot>
div>
<div class="div2">
<slot>默认插槽的文字2slot>
div>
div>
template>
父组件改变默认插槽方法
<Test1 v-model="sexCode" >
<h1>XXXh1>
<h1>XXX222h1>
Test1>
子组件定义
<template>
<div id="Test1">
<div class="div1">
<slot name="one">插槽的文字1slot>
div>
<div class="div2">
<slot name="two">插槽的文字2slot>
div>
div>
template>
父组件
<Test1 v-model="sexCode" >
<template v-slot:one>
<h1>XXXh1>
template>
Test1>
slot属性赋值具名插槽方法
<div slot="one">
<h1>XXXh1>
div>
子组件
<template>
<div id="Test1">
<div class="div1">
<slot :obj2="objData" :obj="objData">插槽的文字1slot>
div>
div>
template>
<script>
export default {
name: "Test1",
data() {
return {
objData:{
name:"张三",
age:18
}
};
},
methods:{
}
};
script>
父组件
<Test1 v-model="sexCode" >
<template v-slot="objData">
<h1>{{ objData.obj2.name }}h1>
template>
Test1>
在项目cmd窗口中执行
cnpm install vuex
创建一个store.js的文件,
在src目录下创建vuex文件夹,在文件夹中创建store.js文件
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state:{
},
getters:{
},
mutations:{
},
actions:{
}
});
在main.js中导入组件
//导入vuex组件内容
import Vuex from 'vuex';
import store from './vuex/store'
Vue.use(Vuex);
Vue.prototype.$store = store;
// 修改原有的new Vue构造器
new Vue({
el: '#app',
router,
store, // 添加到全局组件
components: { App },
template: ' '
})
在state对象中描述要保存的数据
export default new Vuex.Store({
state:{// 共享的数据
count:0
},
actions:{// 操作state里的数据方法
addCount(){// 每次调用让count数据+1
this.state.count++;
},
调用方法
// 调用了vuex中action中的addCount方法,无参调用
this.$store.dispatch("addCount"); // 字符串的action方法名
// 形参1: vuex对象
// 形参2: 传入的数据(如果要传递多个参数,就封装到对象中---map、集合)
addCount2(obj,param){
this.state.count += param;
}
调用的方法
this.$store.dispatch("addCount2",123);
mutations:{
m_addCount(){
this.state.count++;
}
},
调用方法
this.$store.commit("m_addCount");
// 形参1: state对象
// 形参2: 传入的数据(如果要传递多个参数,就封装到对象中---map、集合)
m_addCount2(obj,param){
console.log(obj); // state对象
this.state.count += param;
}
调用方法
this.$store.commit("m_addCount2",123);
getters
getters:{// 获取值的操作
getCount(obj){// 参数注入了当前vuex的state对象
console.dir(obj.count);
return obj.count; // $store.getters.getCount
}
},
调用方法
this.$store.getters.getCount
如果需要异步快速执行就使用action方法,如果是需要保证数据读写安全通过等待就使用mutations方法
action方法是会返回promise函数,可以使用then和catch描述方法调用成功或失败的节点
而 mutations方法没有,就只是一个简单的函数调用
推荐使用mutations方法,因为同步安全
项目cmd窗口执行
cnpm install element-ui
在main.js中导入el组件内容
//导入elementui
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);
测试el组件能否使用