<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
{{message}}
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
<script>
var vm=new Vue({
el:"#app",
data:{
message:"hello.vue!"
}
});
script>
body>
html>
VScode中!+enter能够创建html的架构
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
head>
<body>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
head>
<body>
<div class="app">
{{message}}
div>
<script>
var vm=new Vue({
el:".app",
data:{
message:"hello.vue!"
}
});
script>
body>
html>
{
"vue":{
"scope": "html",
"prefix": "vuehtml",//
"body": [
"",
"",
"",
"",
" ",
" ",
" ",
" Document ",
" ",
"",
"",
" ",
" {{message}}",
"",
"",
" ",
"",
"",
]
}
}
记得要导入cdn哦。
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
1、Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。
2、只有文本传值才要加{{}},v-bind,v-if属性中的传值不用加{{}},
<div id="app">
{{message}}
div>
<script>
var vm=new Vue({
el:"#app",
data:{
message:"hello.vue!"//定义属性和默认初始值,不想要默认初始值就置为message: ''
}
});
script>
v-bind:index通常会简写为:index,这样是为了能够识别其中的变量和运算符。
Vue绑定数据v-bind缩写:字段名双向绑定v-model缩写:model 监听动作v-on缩写@
<div id="app">
<div v-bind:title="message">
鼠标悬停此处查看状态
div>
div>
<script type="text/javascript">
new Vue({
el: '#app',
data:{
message:'页面加载与'+new Date().toLocaleString()
}
});
script>
==会将数据类型转化》,最后比较值;
===比较数据类型和值
<div id="app">
<h1 v-if="type==='a' ">ah1>
<h1 v-else-if="type==='b' ">bh1>
<h1 v-else>elseh1>
div>
<script>
var app=new Vue(
{
el:"#app",
data:{
ok: true,
type: 'd'
}
}
)
script>
<div id="app">
<li v-for="item in items">
{{ item.message}}
li>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
<script>
new Vue({
el: '#app',
data:{
items:[{message:"aaaaaa"},{message: "bbbbbbb"}]
}
});
script>
也可以多加一个值作为该循环时数组的下标。可以用{{index+1}}来使得下标加1
<div id="app">
<li v-for="(item,index) in items">
{{ item.message}}-0{{index+1}}
li>
div>
<script>
new Vue({
el: '#app',
data:{
items:[{message:"aaaaaa"},{message: "bbbbbbb"}]
}
});
script>
<div id="app">
<button v-on:click="sayHi">click mebutton>
div>
<script>
new Vue({
el: '#app',
data:{
message: "你好呀!"
},
methods:{//方法一定要定义在Vue的Methods对象中
sayHi: function (event){
alert(this.message);
}
}
});
script>
用v-model 指令使得input的值和vue对象实现数据双向绑定的效果。
<div id="app">
输入的文本1:<input type="text" v-model="message">
<hr>
输入的文本2:<input type="text" v-model="message">
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
<script>
new Vue({
el: '#app',
data:{
message: "你好呀!"//定义属性和默认初始值,不想要默认初始值就置为message: ''
},
methods:{//方法一定要定义在Vue的Methods对象中
sayHi: function (event){
alert(this.message);
}
}
});
script>
<div id="app">
输入的文本:<textarea name="" id="" cols="" rows="" v-model="message">textarea> {{message}}
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
<script>
new Vue({
el: '#app',
data:{
message: "你好呀!"//定义属性和默认初始值,不想要默认初始值就置为message: ''
},
});
script>
<div id="app">
<select name="" id="" v-model="hah">
<option>Aoption>
<option>Boption>
<option>Coption>
select>
value:{{hah}}
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
<script>
new Vue({
el: '#app',
data:{
hah: 'C'
},
});
script>
<div id="app">
<aaa>aaa> //3、组件的使用
div>
<script>
//1、定义vue的作用标签(作用域)
var vm=new Vue({
el:'#app',
components:{//2、定义vue组件,aaa是组件名,template是组件的内容
'aaa':{
template:'- java
- python
'
}
}
})
script>
可以通过导入全局组件来达到整个工程都能使用该全局组件的效果。
<div id="app">
<hhh v-for="item in items" v-bind:aaa="item"/>
div>
<script>
//1.定义一个vue的主键component
Vue.component("hhh",{
props: ['aaa'],//2.通过props向template中传递数据
template: '{{aaa}} '
});
//3.定义vue的作用标签(作用域)
var vm=new Vue({
el:'#app',
data:{
items: ["java","linux","python"]
}
})
script>
<div id="app">
hello
div>
<script src="vue.min.js">script>
<script>
new Vue({
el: '#app',
data: {
},
created() {//在页面渲染之前会调用created()。
debugger
console.log('created....')
},
mounted() {//在页面渲染之后会调用mounted()。
debugger
//在页面渲染之后执行
console.log('mounted....')
}
})
script>
1、前端路由实现前端局部组件更换。
自己下载vue-router.min.js;先引入vue.min.js,再引入vue-router.min.js
2、实现原理:router-link导航(即目录)—>
<div id="app">
<h1>Hello App!h1>
<p>
<router-link to="/">首页router-link>
<router-link to="/student">会员管理router-link>
<router-link to="/teacher">讲师管理router-link>
p>
<router-view>router-view>
div>
<script src="vue.min.js">script>
<script src="vue-router.min.js">script>
<script>
// 2. 定义路由映射关系的数组,以下固定格式才能被vue服务器通过内部接口成功读取数据
const xxx = [
{ path: '/', redirect: '/welcome' }, //设置默认指向的路径
{ path: '/welcome', component: Welcome },
{ path: '/student', component: Student },
{ path: '/teacher', component: Teacher }
]
// 3. 定义路由跳转到的组件的内容,也可以从其他文件 import 进来组件
//template:'欢迎'就相当于4.3中的欢迎效果
const Welcome = { template: '欢迎' }
const Student = { template: 'student list' }
const Teacher = { template: 'teacher list' }
// 4. 通过路由映射关系创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
xxx // (缩写)相当于 routes: routes
})
//5、创建vue对象。确定路由的作用域。
const app = new Vue({
el: '#app',
router
})
script>
<div id="app">
<h1>Hello App!h1>
<p>
<router-link to="/">首页router-link>
<router-link to="/student">会员管理router-link>
<router-link to="/teacher">讲师管理router-link>
p>
<router-view>router-view>
div>
<script src="vue.min.js">script>
<script src="vue-router.min.js">script>
<script>
// 2、 通过路由映射关系的数组来创建路由器实例,这是个非常简单的实例,在项目中每个对象通常都非常复杂。
const router = new VueRouter({
// routes // (缩写)相当于 routes: routes
routes:[
{ path: '/', redirect: '/welcome' }, //配置默认指向的路径为第一个界面(/welcome)
{ path: '/welcome', component: { template: '欢迎'} },
{ path: '/student', component: { template: 'student list' } },
{ path: '/teacher', component: { template: 'teacher list' } }
]
})
//3、创建vue对象。确定路由的作用域。
new Vue({
el: '#app',
router
})
//或者使用以下简写
// new Vue({
// router
// }).$mount('#app')
script>
参考文章
路由的router-link标签通常不用了,而是用element-ui的的模板。即每当我们往Router中添加一个对象的时候,就会在菜单栏上体现
<template>
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:show-timeout="200"
:default-active="$route.path"
:collapse="isCollapse"
mode="vertical"
background-color="#304156"
text-color="#bfcbd9"
active-text-color="#409EFF"
>
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path"/>
el-menu>
el-scrollbar>
template>
<script>
import { mapGetters } from 'vuex'
import SidebarItem from './SidebarItem'
export default {
components: { SidebarItem },
computed: {
...mapGetters([
'sidebar'
]),
routes() {
return this.$router.options.routes
},
isCollapse() {
return !this.sidebar.opened
}
}
}
script>
import Vue from 'vue'
import Router from 'vue-router'
//1.Vue Router是Vue.js 官方的路由管理器。 它和Vue.js的核心深度集成,可以非常方便的用于SPA应用程序的开发。
//以下通过new Router创建路由器就是Vue.use(Router)的效果
Vue.use(Router)
//2、导入路由的布局样式,在views/layout/Layout下就有路由界面的布局风格的代码
import Layout from '../views/layout/Layout'
//3、这里用一个任意的对象数组,其中有效的属性才会被new Router读取成功
export const constantRouterMap = [
{
path: '/teacher',
component: Layout,//路由的布局样式(如侧边拦,颜色,宽度等等)
redirect: '/teacher/table',//默认重定向到table
name: '讲师管理',//显示在侧边拦
meta: { title: '讲师管理', icon: 'example' },//icron是图标,地址是src/icons/svg/example.svg
children: [
{
path: 'table',
name: '讲师列表',
//1、@代表src下,表示点击会跳转到src/views/edu/teacher/list
//2、src/views/edu/teacher/list下会有具体的...组件
component: () => import('@/views/edu/teacher/list'),
meta: { title: '讲师列表', icon: 'table' }
},
{
path: 'save',
name: '添加讲师',
component: () => import('@/views/edu/teacher/save'),
meta: { title: '添加讲师', icon: 'tree' }
}
]
},
{...},
...
]
//4、Router是import Router from 'vue-router'得到的。里面routes: constantRouterMap内的对象属性在vue-router中有语义规范(就是说只有import Router能够被读取数组的对象的属性中的有效值)
export default new Router({
// mode: 'history', //后端支持可开
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
import Vue from 'vue'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import locale from 'element-ui/lib/locale/lang/en' // lang i18n
import '@/styles/index.scss' // global css
import App from './App'
import router from './router'
import store from './store'
import '@/icons' // icon
import '@/permission' // permission control
Vue.use(ElementUI, { locale })
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
-----------路由的组件
<template>
<div id="app">
<router-view/>
div>
template>
<script>
export default {
name: 'App'
}
script>
1、我们能看到路由器的本质就是把程序中多个组件全部都导入到一个一个Vue对象中(即main.js中的new Vue({})),然后根据url将App.vue中标签渲染成我们想要的组件内容。一个vue项目的本质就是main.js中的一个Vue实例,路由的本质上起着components的效果,只是将所有被渲染的标签统一为< router-views/>
2、一个项目的本质就是一个Vue实例对象,里面通过路由导入了多个组件。本项目中所有的this都是指代本组件的内容,即export default{}这个作用域对象,不可通过this.调用其他对象的内容。
var vm=new Vue({
el:'#app',
components:{
'aaa':{
template:'- java
- python
'
}
'bbb':{
template:'- java
- python
'
}
}
})
我们用Axios来给服务器发送get请求,使用json模拟服务器返回的数据
----------data.json
{
"success":true,
"code":2000,
"message":"成功",
"data":{
"items":[
{"name":"lucy","age":20},
{"name":"mary","age":30},
{"name":"jack","age":40}
]
}
}
----------html
<script src="vue.min.js">script>
<script src="axios.min.js">script>
<script>
new Vue({
el: '#app',
//固定的结构
data: { //在data定义变量和初始值
//定义变量,值空数组
userList:[]
},
created() { //页面渲染之前执行
//调用methods中定义的方法
this.getUserList()
},
methods:{
//定义方法来查询所有用户数据
getUserList() {
//使用axios发送ajax请求:
//axios.提交方式("请求接口路径").then(箭头函数).catch(箭头函数)
//1.请求方式:get,post,delete
//2.接口路径如:http://localhost:8081/admin/ucenter/member
//3.给后端发出请求后若成功返回响应则执行then方法,请求失败则返回catch方法
axios.get("data.json")
.then(response =>{
//response就是请求之后返回数据的形参名,我们当然可以不使用response而使用aaa
console.log(response)
//通过response获取具体数据,赋值给定义空数组
//this.userList = response.data.data.items
//console.log(this.userList)
})
.catch(error =>{//error就是请求之后返回数据的形参名
})
}
}
})
script>
【注意】
1.安装Live Server插件
2.右键选择 Open with Live Server
3.进入浏览器控制台后,刷新浏览器就能显示出一下效果
Promise 是一个对象,它代表了一个异步操作的最终完成或者失败,如成功时回调函数1,失败时回调函数2。而我们通常会vue程序中用Promise来对axios.request产生的结果进行回调。
1、箭头函数的箭头看作return就好理解了,这里return {},
2、Promise的构造方法传入两个参数,通常用(resolve, reject),这里用(a,b)是为了说明这两个形参名是不固定。
- 当操作成功时,Promise的状态将置为fullfiled,构造方法的第一个参数将会被作为p.then()函数的传入参数
- 当操作失败时,Promise的状态置为rejected,构造方法的第二个参数将会被作为p.catch()函数的传入参数
3、我们通常会使用链式编程:即new Promise((a,b)=>{}).then((s)=>{}).catch((e)=>{});
//1、箭头函数的箭头看作return就好理解了,这里return {},
//2、Promise的构造方法传入两个参数,通常用(resolve, reject),这里用(a,b)是为了什么形参名不固定
//构造方法的第一个参数将会被作为p.then()函数的传入参数,
//构造方法的第二个参数将会被作为p.catch()函数的传入参数。
//3、我们通常会使用链式编程:即new Promise((a,b)=>{}).then((s)=>{}).catch((e)=>{});
let p = new Promise((a,b) => {
a("成功传出去的对象");
b("失败传出去的对象");
});
p.then(
(s) => {
console.log("s:"+s);//输出 s:成功传出去的对象
}
);
p.catch((e) => {
console.log("e:"+e);//当异常时就会输出 e:失败传出去的对象
})
其核心一套操作在项目中通常会被分开写,如果连续写则 如下所示:
new Promise((resolve, reject) => {axios.create({baseURL:’’}).request({url:’’,…}).then(response =>{}).catch(error =>{})}).then((resolve)=>{}).catch((reject)=>{})
其中resolve(response),reject(error)都是Promise内的静态方法。
// 1、在util上目录下:创建axios的基本信息
const xxx = create({//1、axios.create的略写 2、创建出来一个axiosInstance,这样才行使用baseURL
baseURL: "http://localhost:8001", // api 的 base_url
timeout: 5000 // 请求超时时间
})
--------------------------------分页:第二页----------------------------------------
import aaa from 'axios'
// 2、api目录:
//调用login函数就相当于调用以下request函数。当我们直接调用login(username, password)时就相当于service.request({...}),这里是进行了一些封装。
export function login(username, password) {
//1、其实是xxx.request()的略写,而不是axios.request的略写
//2、xxx(axios的实例对象)里面有request,get,post,delete,patch等静态方法
//3、get请求的传参params:{},post请求的传参是data:{}
return request({
url: '/hello',
method: 'get',
params: { username }+":xxx"
})
}
--------------------------分页:第三页----------------------------------------------------------------
// 3、在store目录下会调用api下的login函数,即给对应的url发送请求并得到响应
const user = {
actions: {
// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
login(username, userInfo.password).then(response => {//调用的是api/login.js中的login函数,login里面本质上就是server.request函数
const data = response.data
setToken(data.token)
commit('SET_TOKEN', data.token)
resolve()
}).catch(error => {
reject(error)
})
});//return语句结束
},
}
}
当我们通过一个url地址去访问另一个url地址,如果两者有以下任何一个地方不一样就会发生跨域问题。也就是说,跨域问题是不可避免的。如:
访问协议 http https
ip地址 192.168.1.2 172.33.1.1
端口号 953 80
vue中使用v-bind和v-on只适合小范围的数据共享,而大范围的数据共享则需要用到vuex。vuex是实现组件全局状态管理的一种机制,方便组件之间的数据共享。一般在vuex中存储共享的数据,在vue的data中存储自己的数据。
1、npm install -g @vue/cli控制台安装Vue CLI
2、通过vue ui打开vue界面【注意】
如果vue ui没有反应那可能是vue版本太低,要高于版本3才行
重装vue-cli的指令如下:
1、卸载:npm uninstall vue-cli -g
2、重装:npm install @vue/cli -g
-----------------------------在根目录下创建vue.config.js
module.exports = {
lintOnSave: false,
devServer: {
overlay: {
warnings: true,
errors: true
}
}
}
1、在 Vue3 中,新建 Vue 实例是通过 createApp 函数,而不是通过 new Vue。
2、new Vue().KaTeX parse error: Expected 'EOF', got '#' at position 8: mount('#̲app')的作用是vue实例挂…mount(’#app’)和是固定写法(不能改,如果更改$mount(’#xxx’)就会白屏)
3、import xxx from ‘./xxx’ 是import xxx from './xxx.vue’的简写,xxx就是我们写好的xxx.vue界面。
import Vue from 'vue'
//1、是import xxx from './xxx.vue'的简写,xxx就是我们写好的xxx.vue界面。
//2、为了区分,我是用import x from './xxx',然后render: h => h(x),最后也能一样实现挂载。
import x from './xxx'
import store from './store'
Vue.config.productionTip = false
new Vue({
// store,//为了避嫌,把它给先注释了。
//1、render是渲染的意思,可以通过修改xxx来更改我们所使用的.vue文件
//2、使用 Render 函数将 Template 里面的节点解析成虚拟的 Dom。简单的说,在 Vue 中我们使用模板 HTML 语法组建页面的,使用 Render 函数我们可以用 Js 语言来构建 DOM。因为 Vue 是虚拟 DOM,所以在拿到 Template 模板时也要转译成 VNode 的函数,而用 Render 函数构建 DOM,Vue 就免去了转译的过程。
render: h => h(x)
}).$mount('#app')
//1、new Vue().$mount('#app')的作用是vue实例挂载到#app的元素上,但是官方解释template将会替换挂载的class="app"元素(挂载id="app"元素的内容都将被省略不写)。
//所以在vue2中.$mount('#app')和是固定写法(不能改,如果更改$mount('#xxx')就会白屏)
//2、这语法实际上就是vue 1.x下的(使用App组件下的#app元素):
// new Vue({
// el: '#app',
// components: { App }
// });
//3、语法解释:
//1、render函数的官方定义如下
// render: function (createElement) {
// return createElement(
// 'h' + this.level, // tag name 标签名称,this是
// this.$slots.default // 子组件中的阵列,其中$只是一个特殊标记。用来区分的,来说明这是内置的实例方法属性。
// )
// }
// 2、h => h(App)就是一个箭头函数,我们完全可以改成 x => x(App) ,一样生效。如下:
// (function (h) { //其中h(指Hyperscript)vue作者对createElement的简写。
// return h(App);
// });
-------------xxx.vue(默认是App.vue,我这里是为了说明这个文件名不固定就特意用了xxx.vue来距离)
<template>
<div id="b">
hello12341234
<div id="c">
hello12341234
afds
div>
safsdfasfdsaf
div>
template>
<style>
#b {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #ff0000;
margin-top: 60px;
}
#c {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #52ff02;
margin-top: 60px;
}
style>
以下的state,mutation,action都有两中触发方式,但是在index.js中的定义方式就只有一种哦。
--------------------主面板:xxx.vue(这是被main.js所使用的vue)
<template>
<div>
<myAdd>myAdd>
<p>---------------------------p>
<mySub>mySub>
div>
template>
<script>
import A from '../src/components/Addition'
import S from '../src/components/Subtraction'
export default {
data(){
return {};
},
components:{//导入两个组件,并把它们注册为xxx的子组件
'myAdd':A,
'mySub':S
}
}
script>
-----------------store.index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//将vuex安装到项目中:
//1、调用vuex的install方法,判断Vuex是否已经注册过了,注册过了就直接返回,这里使用的是单例模式。
//2、调用applyMixin(Vue)
//3、将初始化vuex的方法(vuexInit)混入到vue的beforeCreate生命周期中;
//4、将$store绑定到每个vue实例中。
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})
-----------------store.index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//将vuex安装到项目中:
//1、调用vuex的install方法,判断Vuex是否已经注册过了,注册过了就直接返回,这里使用的是单例模式。
//2、调用applyMixin(Vue)
//3、将初始化vuex的方法(vuexInit)混入到vue的beforeCreate生命周期中;
//4、将$store绑定到每个vue实例中。
export default new Vuex.Store({
//1、提供唯一公共数据源,本项目的所有的公共数据都要统一发到Store的state中
//2、项目中访问数据的两种方法:
//第一种方式:this.$store.state.count
//第二种方式: 使用import {mapState} from 'vuex',然后通过...mapState(['count'])得到数据并存放在组件的computed属性中。
state: {
count: 0
},
mutations: {
},
actions: {
},
modules: {
}
})
-----------------------Addition.vue(模板类中)
<template>
<div>
<h3>当前最新的count值为:{{$store.state.count}}h3>
<button>+1button>
div>
template>
<script>
export default {
date(){
return {};
}
}
script>
--------------Subtraction.vue(模板类中)
<template>
<div>
<h3>当前最新的count值为:{{count}}h3>
<button>-1button>
div>
template>
<script>
import {mapState} from 'vuex'
export default {
date(){
return {};
},
computed: {
...mapState(['count'])//...是展开运算符。是指将某个全局数据(count)映射为当前组件的属性
}
}
script>
-----------------store.index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//将vuex安装到项目中:
//1、调用vuex的install方法,判断Vuex是否已经注册过了,注册过了就直接返回,这里使用的是单例模式。
//2、调用applyMixin(Vue)
//3、将初始化vuex的方法(vuexInit)混入到vue的beforeCreate生命周期中;
//4、将$store绑定到每个vue实例中。
export default new Vuex.Store({
//1、提供唯一公共数据源,本项目的所有的公共数据都要统一发到Store的state中
//2、在项目中的访问方式第一种方式:this.$store.state.count
//第二种方式: 使用import {mapState} from 'vuex',然后通过...mapState(['count'])得到数据并存放在组件的computed属性中。
state: {
count: 0
},
mutations: {//定义addN函数和subN函数
add(state){
state.count+=1
},
addN(state,step1){//有参
state.count+=step1
},
sub(state){
state.count-=1
},
subN(state,step){//有参
state.count-=step
}
},
actions: {
},
modules: {
}
})
直接使用this.$store.commit(‘add’)来调用
------------------Addition.vue
<template>
<div>
<h3>当前最新的count值为:{{$store.state.count}}h3>
<button @click="btnHandler01">+1button>
div>
template>
<script>
export default {
date() {
return {};
},
methods: {
btnHandler01() {
this.$store.commit('add');//通过commit函数能够调用mutations中的函数
}
}
}
script>
直接使用this.$store.commit(‘addN’,3);来调用
------------------Addition.vue
<template>
<div>
<h3>当前最新的count值为:{{$store.state.count}}h3>
<button @click="btnHandler01">+1button>
<button @click="btnHandler02">+Nbutton>
div>
template>
<script>
export default {
date() {
return {};
},
methods: {
btnHandler01() {
this.$store.commit('add');//通过commit函数能够调用mutations中的函数
},
btnHandler02() {
this.$store.commit('addN',3);//通过commit函数能够调用mutations中的函数
}
}
}
script>
1、展开运算符导入
2、调用this.sub()可以触发mutation中的sub函数。
------------------Subtraction.vue
<template>
<div>
<h3>当前最新的count值为:{{count}}h3>
<button @click="btnHandler01">-1button>
<button @click="btnHandler02">-Nbutton>
div>
template>
<script>
import {mapState,mapMutations} from 'vuex'
export default {
date(){
return {};
},
computed: {
...mapState(['count'])//...是展开运算符。mapState是把全局变量映射到当前组件的一个属性
},
methods:{
...mapMutations(['sub','subN']),//...是展开运算符。mapMutations是把全局函数映射到当前组件的函数
btnHandler01(){
this.sub()
},
btnHandler02(){
this.subN("3")
}
}
}
script>
<template>
<div>
<h3>当前最新的count值为:{{$store.state.count}}</h3> <!-- 原本是this.$store.state.count在template中this可以省略 -->
<button @click="btnHandler01">+1</button>
</div>
</template>
<script>
export default {
date() {
return {};
},
methods: {
btnHandler01() {
this.$store.state.count++;//不推荐使用
}
}
}
</script>
-----------------store.index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//1、提供唯一公共数据源,本项目的所有的公共数据都要统一发到Store的state中
//2、在项目中的访问方式第一种方式:this.$store.state.count
//第二种方式: 使用import {mapState} from 'vuex',然后通过...mapState(['count'])得到数据并存放在组件的computed属性中。
state: {
count: 0
},
//只有mutations中定义的函数才有权利修改state中的数据
mutations: {
add(state){//有参
state.count+=1
},
addN(state,step1){//有参
state.count+=step1
},
sub(state){//定义subN函数
state.count-=1
},
subN(state,step){
state.count-=step
}
},
//在actions中不能直接修改state中的数据,而是通过context.commit()来触发mutation来修改state中的数据
actions: {
addAsync(context){//使用this.$store.dispatch('addAsync')来触发actions函数
setTimeout(()=>{
context.commit('add')
},1000)
},
addNAsync(context,step){//传参
setTimeout(()=>{
context.commit('addN',step)
},1000)
},
subAsync(context){//传参
setTimeout(()=>{
context.commit('sub')
},1000)
},
subNAsync(context,step){//传参
setTimeout(()=>{
context.commit('subN',step)
},1000)
}
},
modules: {
}
})
直接调用全局变量:this.$store.dispatch(‘addAsync’)。
------------------Addition.vue
<template>
<div>
<h3>当前最新的count值为:{{$store.state.count}}</h3> <!-- 原本是this.$store.state.count在template中this可以省略 -->
<button @click="btnHandler01">+1</button>
<button @click="btnHandler02">+N</button>
<button @click="btnHandler03">+1 Async</button>
<button @click="btnHandler04">+N Async</button>
</div>
</template>
<script>
export default {
date() {
return {};
},
methods: {
btnHandler01() {
this.$store.commit('add');//通过commit函数能够调用mutations中的函数
},
btnHandler02() {
this.$store.commit('addN',3);//通过commit函数能够调用mutations中的函数
},
btnHandler03() {//异步让count自增+1
this.$store.dispatch('addAsync');//通过this.$store.dispatch来触发action中的函数
},
btnHandler04() {//异步传参
this.$store.dispatch('addNAsync',4);//通过this.$store.dispatch来触发action中的函数
}
}
}
</script>
1、导入:…mapActions([‘subAsync’,‘subNAsync’])
2、直接调用this.subAsync()
------------------Subtraction.vue
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
<button @click="btnHandler01">-1</button>
<button @click="btnHandler02">-N</button>
<button @click="btnHandler03">-1 Async</button>
<button @click="btnHandler04">-N Async</button>
</div>
</template>
<script>
import {mapState,mapMutations,mapActions} from 'vuex'
export default {
date(){
return {};
},
computed: {
...mapState(['count'])//...是展开运算符。mapState是把全局变量映射到当前组件的一个属性
},
methods:{
...mapMutations(['sub','subN',]),//...是展开运算符。mapMutations是把全局函数映射成当前组件的函数
...mapActions(['subAsync','subNAsync']),//...是展开运算符。把全局actions中方法映射成当前组件中的方法
btnHandler01(){
this.sub()
},
btnHandler02(){
this.subN(3)
},
btnHandler03(){
this.subAsync()
},
btnHandler04(){
this.subNAsync(3)
}
}
}
</script>
javascript的执行环境为单线程,所以程序在执行的时候只能按照顺序执行,而其中一个程序要占用大量的时间,会导致后面的程序过长的等待,造成阻塞的情况。当某些操作
需要花费大量时间但是并不怎么消耗资源
时,设计者就考虑把这些空出来的资源给其他操作使用,这就是异步操作的由来。javascrpt中的异步操作不同于多线程执行,当执行需要消耗大量资源的操作时,异步是可能会阻塞,而多线程就不会。常见的异步操作有:定时器、ajax、事件绑定、回调函数、async await、promise等,这些操作都是要需要花费大量时间等待但是并不怎么消耗资源的操作。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {//定义addN函数和subN函数
add(state){
setTimeout(()=>{//在mutations中设置计时器
state.count++
},1000)
},
addN(state,step1){//有参
state.count+=step1
},
sub(state){
state.count-=1
},
subN(state,step){//有参
state.count-=step
}
},
actions: {
},
modules: {
}
})
Getter不修改store中的原数据,而是对数据进行包装作用。当store中的数据进行变换之后,Getter中的数据也会发生变化。
我们可以把Getter当做state中数据的get方法,mutation当做state中数据的set方法,把actions用来定义程序需要调用的函数。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//1、提供唯一公共数据源,本项目的所有的公共数据都要统一发到Store的state中
//2、在项目中的访问方式第一种方式:this.$store.state.count
//第二种方式: 使用import {mapState} from 'vuex',然后通过...mapState(['count'])得到数据并存放在组件的computed属性中。
state: {
count: 0
},
//只有mutations中定义的函数才有权利修改state中的数据
mutations: {
add(state){//有参
state.count+=1
},
addN(state,step1){//有参
state.count+=step1
},
sub(state){//定义subN函数
state.count-=1
},
subN(state,step){
state.count-=step
}
},
//在actions中不能直接修改state中的数据,而是通过context.commit()来触发mutation来修改state中的数据
actions: {
addAsync(context){//使用this.$store.dispatch('addAsync')来触发actions函数
setTimeout(()=>{
context.commit('add')
},1000)
},
addNAsync(context,step){//传参
setTimeout(()=>{
context.commit('addN',step)
},1000)
},
subAsync(context,step){//传参
setTimeout(()=>{
context.commit('sub',step)
},1000)
},
subNAsync(context,step){//传参
setTimeout(()=>{
context.commit('subN',step)
},1000)
}
},
getters:{
showNum(state){//可以通过this.$store.getters.showNum来获取return的值。
return '当前最新的数量是【'+state.count+'】'
}
},
modules: {
}
})
使用 {{$store.getters.showNum}}
<template>
<div>
<h3>{{$store.getters.showNum}}</h3> <!-- 原本是this.$store.state.count在template中this可以省略 -->
<button @click="btnHandler01">+1</button>
<button @click="btnHandler02">+N</button>
<button @click="btnHandler03">+1 Async</button>
<button @click="btnHandler04">+N Async</button>
</div>
</template>
<script>
export default {
date() {
return {};
},
methods: {
btnHandler01() {
this.$store.commit('add');//通过commit函数能够调用mutations中的函数
},
btnHandler02() {
this.$store.commit('addN',3);//通过commit函数能够调用mutations中的函数,注意是加3而不是加'3'
},
btnHandler03() {//异步让count自增+1
this.$store.dispatch('addAsync');//通过this.$store.dispatch来触发action中的函数
},
btnHandler04() {//异步传参
this.$store.dispatch('addNAsync',4);//通过this.$store.dispatch来触发action中的函数
}
}
}
</script>
1、在computed中使用展开运算符导入,
2、直接通过{{showNum}}来传值
<template>
<div>
<h3>{{showNum}}</h3>
<button @click="btnHandler01">-1</button>
<button @click="btnHandler02">-N</button>
<button @click="btnHandler03">-1 Async</button>
<button @click="btnHandler04">-N Async</button>
</div>
</template>
<script>
import {mapState,mapMutations,mapActions,mapGetters} from 'vuex'
export default {
date(){
return {};
},
computed: {
...mapState(['count']),//...是展开运算符。mapState是把全局变量映射到当前组件的一个属性
...mapGetters(['showNum'])
},
methods:{
...mapMutations(['sub','subN',]),//...是展开运算符。mapMutations是把全局函数映射成当前组件的函数
...mapActions(['subAsync','subNAsync']),//...是展开运算符。把全局actions中方法映射成当前组件中的方法
btnHandler01(){
this.sub()
},
btnHandler02(){
this.subN(3)
},
btnHandler03(){
this.subAsync()
},
btnHandler04(){
this.subNAsync(3)
}
}
}
</script>
正如jdk是java的运行环境,node.js也是javascript的运行环境,有了node.js,我们就不需要浏览器来运行javascript了。实际上,node.js正是使用了google的javascript引擎(v8).
正如我们需要安装jdk一样,我们也需要在电脑上安装node.js
const http = require('http');
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据 "Hello World"
response.end('Hello Server');
}).listen(8888);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
在我们安装node.js时,npm会默认一起安装好了,因此不需要我们手动安装。
当我们在某个文件夹下使用 npm init指令后,会发现在本文件中出现了一个package.json文件,这就类似于后端的pom.xml文件。
npm init或npm init -y
1.npm config set registry https://registry.npm.taobao.org
2.npm config list
npm install jquery下载最新版本
npm install [email protected]下载指定版本
下载后能得到如下的一个文件夹
npm install
es5兼容性更好。
babel init
npm install --global babel-cli
get-ExecutionPolicy
set-ExecutionPolicy RemoteSigned
babel --version
.babelrc
文件---------01.js
let input = [1,2,3]
input = input.map(item=>item + 1)
console.log(input)
-------------- .babelrc
{
"presets": ["es2015"],
"plugins": []
}
npm install --save-dev babel-preset-es2015
如果下载失败或下载了很久,就ctrl+c关闭,然后重新下载。
以下实现02.js调用01.js中的加法函数却没有调用成功减法函数
---------01.js
//1、创建js方法
// 加法函数
const sum=function(a,b){
return parseInt(a)+parseInt(b)
}
// 减法函数
const subtract=function(a,b){
return parseInt(a)-parseInt(b)
}
//2、设置加法能够被其他js文件调用,减法不能
module.exports={
sum
}
---------02.js
//1、引入01.js文件
const m = require("./01.js")
//2、调用方法
console.log(m.sum(1,3))
console.log(m.subtract(3,1))
需要转换成es5,再进行模块化
---------01.js
//定义方法,加上export 就可以被其他js文件调用
export function getList(){
console.log("getList.....")
}
export function save(){
console.log("save.......")
}
---------02.js
//引入可以调用的方法
import {getList,save} from "./01.js"
//调用方法
getList()
save()
---------01.js
//定义可以被其他js文件调用
export default{
getList(){
console.log("getList.....")
},
save(){
console.log("save.......")
}
}
---------02.js
//引入可以调用的方法
import m1 from "./01.js"
//调用方式
m1.getList()
m1.save()
-------- .babelrc
{
"presets": ["es2015"],
"plugins": []
}
npm install --save-dev babel-preset-es2015
babel es6module -d es6module2
被转换的文件内容如下,我们发现完全符合es5的语法
------01.js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getList = getList;
exports.save = save;
//定义方法,加上export 就可以被其他js文件调用
function getList() {
console.log("getList.....");
}
function save() {
console.log("save.......");
}
-------02.js
"use strict";
var _ = require("./01.js");
//调用方法
(0, _.getList)(); //引入可以调用的方法
(0, _.save)();
Webpack是一个前端资源加载、打包工具,他能将多种css,js,less等静态资源文件打包成一个静态文件,减少了多文件页面调用请求而浪费资源。
npm init 生成package.json文件
npm install -g webpack webpack-cli
webpack --version:查看是否安装
-----------common.js
//exports说明可导出
exports.add=function(a,b){
return a + b;
}
-----------utils.js
//exports说明可导出
exports.info=function(str){
console.log()
document.write(str);//浏览器中输出
}
-----------main.js
const common=require("./common")
const utils=require("./utils")
common.info('hello common'+utils.add(1,2))
配置文件名固定
---------webpack.config.js
const path=require("path");//Node.js内置模块
module.exports={
entry:'./src/main.js',//配置文件入口
output:{
path:path.resolve(_dirname,'./dist'),//输出文件夹路径,需要自己创建
filename:'bundle.js'//输出的一个文件名
}
}
---------webpack4以上用一下命令
const path = require('path')
module.exports = {
entry: path.join(__dirname, 'src/main.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
}
}
执行webpack命令
------------得到的bundle.js文件内是如下一行代码
(()=>{var o={648:(o,n)=>{n.info=function(o){console.log(),document.write(o)}},555:(o,n)=>{n.add=function(o,n){return o+n}}},n={};function r(t){var e=n[t];if(void 0!==e)return e.exports;var i=n[t]={exports:{}};return o[t](i,i.exports,r),i.exports}(()=>{const o=r(648),n=r(555);o.info("hello common"+n.add(1,2))})()})();
--------a.html
<script src="dist/bundle.js">script>
>
const common=require("./common")
const utils=require("./utils")
require("./style.css")
common.info('hello common'+utils.add(1,2))
npm install --save-dev style-loader css-loader
const path = require('path')
module.exports = {
entry: path.join(__dirname, 'src/main.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
}
}
webpack:输出文件会将覆盖存在的一个同名文件
<script src="dist/bundle.js">script>
>