vue
VUE CLI
npm 软件包管理工具
环境搭建:
nodejs
配置环境变量:E:\nodejs\node-v12.19.1-win-x64
E:\nodejs\node-v12.19.1-win-x64\node_global
CMD窗口,执行命令node -v
查看node版本
最新版的node在安装时同时也安装了npm
,执行npm -v
查看npm
版本
修改默认路径:
npm config set prefix "E:\nodejs\node-v12.19.1-win-x64\node_global"
npm config set cache "E:\nodejs\node-v12.19.1-win-x64\node_cache"
上操作表示,修改全局包下载目录为E:\nodejs\node-v12.19.1-win-x64\node_global
,缓存目录为E:\nodejs\node-v12.19.1-win-x64\node_cache
,并会自动创建node_global
目录,而node_cache
目录是缓存目录,会在你下载全局包时自动创建
npm淘宝镜像:
npm config set registry https://registry.npm.taobao.org
全局安装一个vue-cli
脚手架
npm install @vue/cli -g
(nodejs 清空 npm 缓存)
npm cache clean -f
重新安装脚手架
npm install -g @vue/cli-init
打开存放新建项目的文件夹,创建项目
vue init webpack mytest
进入到项目中,安装依赖
cd mytest
npm install
运行
npm run dev
浏览器访问http://localhost:8080/
live server 插件(vsCode)实时同步代码
安装配置yarn
npm install yarn -g
yarn config set registry https://registry.npm.taobao.org
yarn config set disturl https://npm.taobao.org/dist --global
MVVM模式:
- Model:模型层,在这里表示javascript对象
- View:视图层,在这里表示DOM(HTML操作的元素)
- ViewModel:连接视图和数据的中间件。
核心:dom监听和数据绑定(双向绑定)
<h1>{{message}}</h1>
var vm = new Vue({
el:"#app",
//model:数据
data:{
message:"hello,vue!"
}
});
对象:
el 元素挂载点
“#”:id选择器(推荐)
”.“:class选择器
“div":div标签选择器
data 数据
methods 方法
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
v-bind
绑定(指令),可以简写,v-bind:title简写成:title
<span v-bind:title="message">鼠标悬停几秒显示动态绑定的信息</span>
v-if; v-else
<h1 v-if="ok">yes</h1>
<h1 v-else>no</h1>
var vm = new Vue({
el:"#app",//
//model:数据
data:{
ok: true
}
});
<h1 v-if="type==='A'">a</h1>
<h1 v-else-if="type==='B'">b</h1>
<h1 v-else-if="type==='d'">d</h1>
<h1 v-else>c</h1>
var vm = new Vue({
el:"#app",
//model:数据
data:{
type: 'A'
}
});
v-for
<li v-for="item in items">
{{item.message}}
</li>
var vm = new Vue({
el:"#app",
//model:数据
data:{
items:[
{message: 'firstLine'},
{message: 'secondLine'},
{message: 'thirdLine'},
]
}
});
- index
<li v-for="(item,index) in items">
{{item.message}}----{{index}}
</li>
事件v-on
v-on:click也可以简写成@click
<!--//view-->
<div id="app">
<button v-on:click="sayHi">click here</button>
</div>
var vm = new Vue({
el:"#app",
//model:数据
data:{
message: "么么哒"
},
methods: {//方法必须定义在vue的methods对象中,v-on绑定事件
sayHi: function (){
alert(this.message);//this指vm对象
}
}
});
v-model
双向绑定:
<div id="app">
<input text="text" v-model="message">{{message}}
</div>
var vm = new Vue({
el:"#app",
//model:数据
data:{
message: "么么哒"
},
});
<div id="app">
<textarea v-model="message"></textarea>{{message}}
</div>
var vm = new Vue({
el:"#app",
//model:数据
data:{
message: "么么哒"
},
});
<div id="app">
性别:
<input type="radio" name="sex" value="男" v-model="auto">男
<input type="radio" name="sex" value="女" v-model="auto">女
<p>
选中了谁:{{auto}}
</p>
</div>
var vm = new Vue({
el:"#app",
//model:数据
data:{
auto: ''
},
});
<div id="app">
下拉框:
<select v-model="selected">
<option value="" disabled>---请选择---</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>
value:{{selected}}
</span>
</div>
var vm = new Vue({
el:"#app",
//model:数据
data:{
selected: ''
},
});
组件
可复用的vue实例,重复使用的模板
<div id="app">
<comp></comp>
</div>
//定义一个vue组件component
Vue.component("comp",{
template:'<li>hello</li>'
});
<!--组件 传递给组件中的值:props-->
<comp v-for="item in items" v-bind:mid="item"></comp>
//定义一个vue组件component
Vue.component("comp",{ //注册一个组件
props:['mid'], //传递参数
template:'<li>{{mid}}</li>' //组件的模板
});
var vm = new Vue({
el:"#app",
//model:数据
data:{
items: ["java","vue","go"]
},
});
items(数组)–》item(遍历出来的数据) --》mid(把遍历出来的数据放进模板)
网络通信
Axios
浏览器端和nodeJS的异步通信框架,实现ajax异步通信。
安装axios:
终端页面输入
npm install axios
保存
npm install --save axios Vue-axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<!--//view-->
<div id="app" v-cloak><!--v-cloak解决屏幕闪动的问题-->
<div>{{info.name}}</div>
<div>{{info.version}}</div>
<div>{{info.scripts.start}}</div>
<a v-bind:href="info.url" >点点</a>
</div>
</body>
<script>
var vm = new Vue({
el:"#app",
//model:数据
data() {
return{
//请求的返回参数合适,必须和json字符串一样
info:{
name:null,
version:null,
scripts: {
start:null,
test:null
},
url: null
}
}
},
mounted(){ //钩子函数 链式编程
axios.get('test.json').then(response=>(this.info=response.data));//test.json为Jason文件
}
});
</script>
计算属性
计算出来的结果保存在属性中,内存中运行:虚拟dom
将不经常变化的计算结果进行缓存,节约系统开销(只有数据进行增删改查后才重新计算)
<body>
<!--//view-->
<div id="app">
<p>{{currentTime()}}</p> //methods
<p>{{currentTime2}}</p> //computed没有括号,是个属性,不是方法
</div>
</body>
<script>
var vm = new Vue({
el:"#app",
//model:数据
data:{
message: "hello"
},
methods:{
currentTime:function (){
return Date.now();// 返回一个时间戳
}
},
computed: { //计算属性
currentTime2:function (){ // methods和computed的方法名不能重,重之后,只能调methods的方法
this.message; //只有数据进行增删改查后才重新计算
return Date.now();// 返回一个时间戳
}
}
});
</script>
插槽
标签,动态的拔插
<!--//view 视图层-->
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
</todo>
</div>
</body>
<script>
//slot:插槽
Vue.component("todo",{
template:'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props:['title'],
template:'<div>{{title}}</div>'
});
Vue.component("todo-items",{
props:['item'],
template:'<li>{{item}}</li>'
});
var vm = new Vue({
el:"#app",
//model:数据
data:{
title:"letsgo",
todoItems: ['123','456','789']
},
});
</script>
自定义事件
solice()方法:
修改array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该元素添加若干元素;
arr.splice(2,3,‘go’); 从索引2开始删除3个元素,再添加’go‘。
$emit():
触发父组件的自定义事件
<!--//view 视图层-->
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in todoItems"
:item="item" v-bind:index="index" v-on:remove="removeItems(index)" :key="index"></todo-items>
</todo>
</div>
</body>
<script>
//slot:插槽
Vue.component("todo",{
template:'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props:['title'],
template:'<div>{{title}}</div>'
});
Vue.component("todo-items",{
props:['item','index'],
//只能绑当前组件的方法
template:'<li>{{index}}---{{item}} <button @click="remove">删除</button></li>',
methods: {
remove: function (index){
this.$emit('remove',index);//$emit 触发父组件的自定义事件removeItems()
}
}
});
var vm = new Vue({
el:"#app",
//model:数据
data:{
title:"letsgo",
todoItems: ['123','456','789']
},
methods: {
removeItems:function (index){
console.log("删除了"+this.todoItems[index]+"OK")
this.todoItems.splice(index,1);
}
}
});
</script>
webpack
静态打包器 模块化加载器兼打包工具
ES6模块
CommonsJS同步
exports:暴露接口
require:接收
module:模块,用于处理各种类型的文件
plugins:插件
resolve:设置路径指向
watch:监听,用于设置文件改动后直接打包
安装webpack:
npm install webpack -g
npm install webpack-cli -g
-g为全局
测试安装成功:
webpack -v
webpack-cli -v
vue router
路由管理器(a标签)
安装–保存配置:
npm install vue-router --save-dev
1.自定义组件
src/compoments/Content.vue
<template>
<h1>内容页</h1>
</template>
<script>
export default {
name: 'Content'
}
</script>
<style scoped>
</style>
src/compoments/Main.vue
<template>
<h1>首页</h1>
</template>
<script>
export default {
name: 'Main'
}
</script>
<style scoped>
</style>
2.src/router/index.js 安装路由
import Vue from 'vue'
import Router from 'vue-router'
// 导入上面自定义的组件
import Content from '../components/Content'
import Main from '../components/Main'
// 安装路由
Vue.use(Router)
// 配置路由
export default new Router({
routes: [
{
// 路由路径
path: '/content',
name: 'content',
// 跳转的组件
component: Content
},
{
// 路由路径
path: '/main',
name: 'main',
// 跳转的组件
component: Main
}
]
})
3.src/main.js中配置路由
import Vue from 'vue'
import App from './App'
// 导入路由配置目录
import router from './router' // 自动扫描里面的路由配置
import VueRouter from 'vue-router'
Vue.config.productionTip = false
// 显式声明使用vueRouter
Vue.use(router)
// eslint-disable-next-line no-new
new Vue({
el: '#app',
// 配置路由
router,
components: { App },
template: '<App/>'
})
4.src/App.vue 使用路由
<template>
<div id="app">
<h1>vue-router</h1>
<router-link to="/main">首页</router-link>
<router-link to="/content">内容页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
vue+ElementUI
创建工程
vue init webpack vue-ElemenUI
进入工程目录
cd vue-ElemenUI
安装vue-router
npm install vue-router --save-dev
安装 element-ui
npm i element-ui -S
安装依赖
npm install
安装SASS加载器
cnpm install sass-loader node-sass --save-dev
启动测试
npm run dev
mai.js
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(router);
Vue.use(ElementUI);
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App) // ElementUI
})
嵌套路由
import Vue from 'vue'
import Router from 'vue-router'
// 导入上面自定义的组件
import Login from '../components/Login'
import Main from '../components/Main'
import UserList from '../components/user/List'
import UserProfile from '../components/user/Profile'
// 安装路由
Vue.use(Router)
// 配置路由
export default new Router({
routes: [
{
// 路由路径
path: '/login',
name: 'login',
// 跳转的组件
component: Login
},
{
// 路由路径
path: '/main',
name: 'main',
// 跳转的组件
component: Main, //嵌套路由
children:[
{path: '/user/profile',component:UserProfile},
{path: '/user/list',component:UserList},
]
}
]
})
参数传递
main.js
<!--name传组件名 params传递参数 绑定对象-->
<router-link :to="{name: 'UserProfile',params: {id:1}}">个人信息</router-link>
<router-view></router-view>
router/index.js (name对应)
export default new Router({
routes: [
{
// 路由路径
path: '/login',
name: 'login',
// 跳转的组件
component: Login
},
{
// 路由路径
path: '/main',
name: 'main',
// 跳转的组件
component: Main, // 嵌套路由
children: [
// :id 接收参数
{path: '/user/profile/:id',
name: 'UserProfile',
component: UserProfile,
props: true // props
},
]
}
]
})
接收
1.profile.vue
<!--所有的元素必须不能直接在根节点下-->
<div>
<h1>个人信息</h1>
{{ $route.params.id }}
</div>
- props 绑定(常用)
<template>
<!--所有的元素必须不能直接在根节点下-->
<div>
<h1>个人信息</h1>
{{ id }}
</div>
</template>
<script>
export default {
props: ['id'], // props接收
name: 'UserProfile'
}
重定向
index.js
export default new Router({
routes: [
// 重定向到main
{
path: '/goHome',
redirect: '/main'
}
]
})
<router-link to="/goHome">回到首页</router-link>
路由模式
hash:路径带#(默认)
history:路径不带#
export default new Router({
mode: 'history', // 设置路由模式
})
路由钩子与异步请求
beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在路由离开前执行
export default {
props: ['id'],
name: 'UserProfile',
beforeRouteEnter:(to,from,next)=>{
console.log("进入路由之前");
next();
},
beforeRouteLeave:(to,from,next)=>{
console.log("离开路由之前");
next();
},
}
to:路由将要跳转的路径信息
from:路径跳转前的路径信息
next:路由的控制参数:
next()跳入下一关页面
next(’/path’) 改变路由的跳转方向,使其跳到另一路由
next(false)返回原来的页面
next((vm)=>{})仅在beforeRouteEnter中可用,vm是组件实例
Axios
npm install axios -s
npm install --save vue-axios
main.js
import Axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, Axios)
Profile.vue
<script>
export default {
props: ['id'],
name: 'UserProfile',
beforeRouteEnter: (to, from, next )=> {
console.log( "进入路由之前"); // 加载数据
next(vm => {
vm.getData(); // 进入路由之前执行getData
});
},
beforeRouteLeave: (to, from, next )=> {
console.log( "离开路由之前");
next();
},
methods: {
getData: function () {
this.axios({
method: 'get',
url: 'http://localhost:8081/static/mock/test.json'
}).then(function (response) {
console.log(response)
})
}
}
}
</script>
时间范围选择
<a-form-item label="测试时间">
<a-range-picker
v-decorator="['range-time-picker', rangeConfig]"
show-time
format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
Object.assign()是浅拷贝
注意,具有相同属性的对象,同名属性,后边的会覆盖前边的。
Object.assign(this.model, { publishstate: '实施完成' });
let formData = Object.assign(this.model, values);
表单提交
注册form
data() {
return {
form: this.$form.createForm(this), //注册form
url: {
edit: "/itsm.release/release/edit",
}
};
},
onSubmit() {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
let url = this.url.edit;
console.log(values);
// 修改发布状态
Object.assign(this.model, { publishstate: '实施完成' });
let formData = Object.assign(this.model, values);
console.log(formData);
httpAction(url, formData, 'put').then((res) => {
if (res.success) {
that.$message.success(res.message); // 设置成功消息
that.$emit('ok');
} else {
that.$message.warning(res.message); // 设置失败消息
}
}).finally(() => {
that.confirmLoading = false;
})
}
});
},
v-decorator绑定数据和校验
v-decorator="['publishtype', validatorRules.publishtype]"
校验需在data中设置rules
modal对话框
submitInfo:function(record){
const that = this;
this.$confirm({
title: '您确定要提交此条发布吗?',
onOk() {
let url = '/itsm.release/release/edit';
console.log('OK');
let formData = Object.assign(record, { publishstate: '待审核' });
httpAction(url, formData, 'put').then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('ok');
} else {
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
},
onCancel() {
console.log('Cancel');
},
class: 'test',
});
}