1.vuex的使用

  vuex是vue的状态管理中心,vuex来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新,常用于:

1.多个视图依赖同一状态(l例:菜单导航)

2.来自不同视图的行为需要变更同一状态(例如评论弹幕)

上篇创建的vue项目目录结构:

  在上一节我们已经安装了vuex模块。查看store/index.js内容,如下:

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
},
});

  上面引入Vue模块和Vuex模块,并将Vuex安装到Vue中。

下面使用vuex。在Test路由中改变值,在about模块中接收,代码如下:

(1)修改store/index.js

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({
state: {
count: 0,
},
mutations: {
increase() {
this.state.count = this.state.count + 1;
},
},
actions: {
},
modules: {
},
});

  定义一个状态count,mutations中是修改状态的唯一入口。

(2)修改Test.vue

<template>
<div class="test">
这是Test
<button tybe="button" @click="addOne()">点击我</button>
</div>
</template> <script>
import store from '@/store'; export default {
name: 'Test',
store,
methods: {
addOne() {
console.log('add');
store.commit('increase');
},
},
};
</script>

  点击按钮的时候调用方法addOne()。addOne()中调用store.commit("increase") 提交该方法进行修改状态,相当于调用 Vuex.Store 实例的 increase() 方法。

(3)修改About.vue接收状态count

<template>
<div class="about">
<h1>This is an about page</h1>
{{msg}}
</div>
</template> <script>
import store from '@/store'; export default {
name: 'About',
store,
data() {
return {
msg: store.state.count,
};
},
};
</script>

(4)测试:

补充:关于vuex调用函数传递参数。比如我们传递一个username参数到vuex中,如:

store/index.js:

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({
state: {
username: ''
},
mutations: {
setLoginUsername(state, username) {
state.username = username
},
},
actions: {
setLoginUsernameFun(context, username) {
context.commit("setLoginUsername", username);
},
},
modules: {
},
});

调用方法如下:(登录成功之后跳转到首页并记录登录的用户)=如下面红色代码

    login() {
this.isReg = false;
var nameLocal = localStorage.getItem("name");
var passwordLocal = localStorage.getItem("name");
if (nameLocal == '' || passwordLocal == '') {
alert("您还没注册!");
return;
} if (nameLocal === this.name || passwordLocal === this.password) {
store.dispatch("setLoginUsernameFun", nameLocal);
this.$router.push('/home')
return;
} alert("账号或者密码错误");
},

补充:vueX的五个核心属性

(1)state:

state即Vuex中的基本数据!
state就是用来存放数据,若是对数据进行处理输出,比如数据要过滤,一般我们可以写到computed中。

(2)getters(相当于State的计算属性) :

基础用法:

index.js

const store = new Vuex.Store({
state: {
list: [1, 3, 5, 7, 9, 20, 30]
},
getters: {
filteredList: state => {
return state.list.filter(item => item > 5)
},
listCount: (state, getters) => {
return getters.filteredList.length;
}
}
})

vue中:

<template>

  <div>
过滤后的列表:{{list}}
<br>
列表长度:{{listCount}}
</div>
</template> <script>
export default {
name: "index.vue",
computed: {
list() {
return this.$store.getters.filteredList;
},
listCount() {
return this.$store.getters.listCount;
}
}
}
</script>

(3)mutation(提交更改数据的方法,同步!必须是同步函数)

使用vuex修改state时,有两种方式:
1)可以直接使用 this.$store.state.变量 = xxx;
2)this.$store.dispatch(actionType, payload)或者 this.$store.commit(commitType, payload)
异同点:
1)共同点: 能够修改state里的变量,并且是响应式的(能触发视图更新)
2)不同点:
若将vue创建 store 的时候传入 strict: true, 开启严格模式,那么任何修改state的操作,只要不经过mutation的函数,
vue就会 throw error : [vuex] Do not mutate vuex store state outside mutation handlers。

(4)action(像一个装饰器,包裹mutations,使之可以异步。)

action的功能和mutation是类似的,都是去变更store里的state,不过action和mutation有两点不同:
1)action主要处理的是异步的操作,mutation必须同步执行,而action就不受这样的限制,也就是说action中我们既可以处理同步,也可以处理异步的操作
2)action改变状态,最后是通过提交mutation。

  Action 通过 store.dispatch 方法触发。

(5)modules ( 模块化Vuex):

  在Vue中State使用是单一状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理。
  modules:可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理

const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
} const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
} const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
}) store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

2. 打包vue项目并制作成app

  vue-cli3之后的打包与之前不一样,配置文件在vue.config.js中,并且这个文件需要自己创建置于与package.json同目录。关于其配置项可参考:

如果想打包之后静态页面直接点击运行需要将路由改为hash路由:

(1)修改router/index.js

const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
routes,
});

(2)vue.config,js修改打包的默认路径:

module.exports = {
publicPath: './',
lintOnSave: false
}

  如果将来我们将页面置于项目中,项目名称为exam,我们将publicPath修改为exam即可。默认是/,./是相对路径。

  lintOnSave: false 是关闭eslint验证(这个验证太烦了)

  接下来到项目根路径运行打包命令即可得到正常的html、css等文件。如下:

E:\HBuilderSpace\vue-demo>npm run build

> vue-demo@0.1.0 build E:\HBuilderSpace\vue-demo
> vue-cli-service build - Building for production... DONE Compiled successfully in 51657ms File Size Gzipped dist\js\chunk-vendors.ae7fcf93.js 125.21 KiB 43.38 KiB
dist\js\app.628ec198.js 7.19 KiB 2.75 KiB
dist\js\about.672d2588.js 1.32 KiB 0.59 KiB
dist\css\about.b0b00f5a.css 0.57 KiB 0.31 KiB
dist\css\app.59544d79.css 0.21 KiB 0.15 KiB

打包后会生成dist目录,并且对文件都进行了压缩,如下:

index.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">
<link rel=icon href=favicon.ico>
<title>vue-demo</title>
<link href=css/about.b0b00f5a.css rel=prefetch>
<link href=js/about.672d2588.js rel=prefetch>
<link href=css/app.59544d79.css rel=preload as=style>
<link href=js/app.628ec198.js rel=preload as=script>
<link href=js/chunk-vendors.ae7fcf93.js rel=preload as=script>
<link href=css/app.59544d79.css rel=stylesheet>
</head>
<body>
<noscript><strong>We're sorry but vue-demo doesn't work properly without JavaScript enabled. Please enable it to
continue.</strong></noscript>
<div id=app></div>
<script src=js/chunk-vendors.ae7fcf93.js></script>
<script src=js/app.628ec198.js></script>
</body>
</html>

2.制作一个简单的基于localStorage本地登录的小app

  用vue制作一个简单的基于本地登录的app,基于hash的路由。

1.目录结构:

2.附上主要代码:

App.vue:只定义了入口,在router/index.js中设置默认路由

<template>
<div id="app">
<router-view/>
</div>
</template> <style lang="scss">
*{
padding: 0px;
text-align: center;
}
</style>

Main.js

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store'; Vue.config.productionTip = false; new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');

router/index.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import Login from '../views/Login.vue'; Vue.use(VueRouter); const routes = [
{
path: '/',
name: 'login',
component: Login,
},
{
path: '/home',
name: 'home',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/Home.vue'),
redirect: '/home/user',
children: [{
path: 'user',
name: 'user',
component: () => import(/* webpackChunkName: "about" */ '../views/User.vue')
}, {
path: 'contact',
name: 'contact',
component: () => import(/* webpackChunkName: "about" */ '../views/Contact.vue')
}]
},
]; const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
linkActiveClass: 'active',
routes,
}); export default router;

  定义了默认路由是Login,Login采用一次性加载,其他采用懒加载。登录成功之后的/home重定向到子路由/home/user。

store/index.js

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({
state: {
username: ''
},
mutations: {
setLoginUsername(state, username) {
state.username = username
},
},
actions: {
setLoginUsernameFun(context, username) {
context.commit("setLoginUsername", username);
},
},
modules: {
},
});

  vuex管理组件定义了一个属性与修改属性的方法

vies/Login.vue

<template>
<div class="login">
<form v-if="!isReg">
<h1>欢迎来到XXX系统</h1>
<br/>
<br/>
<div>用户名: <input type="text" v-model="name"/> </div>
<br/>
<div>密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码: <input type="password" v-model="password"/> </div>
<div class="rowBtn" @click="login()">登录</div>
<div class="rowBtn regBtn" @click="reg()">注册</div>
</form>
<form v-else>
<h1>注册</h1>
<br/>
<br/>
<div>用户名: <input type="text" v-model="name"/> </div>
<br/>
<div>密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码: <input type="password" v-model="password"/> </div>
<br/>
<div>确认密码: <input type="password" v-model="passwordRepeat"/> </div>
<div class="rowBtn" @click="addUser()">注册</div>
<div class="rowBtn regBtn" @click="cancel()">取消</div>
</form> </div>
</template> <script>
import store from '@/store'; export default {
name: 'login',
store,
data() {
return {
isReg: false,
name: '',
password: '',
};
},
methods: {
login() {
this.isReg = false;
var nameLocal = localStorage.getItem("name");
var passwordLocal = localStorage.getItem("name");
if (nameLocal == '' || passwordLocal == '') {
alert("您还没注册!");
return;
} if (nameLocal === this.name || passwordLocal === this.password) {
store.dispatch("setLoginUsernameFun", nameLocal);
this.$router.push('/home')
return;
} alert("账号或者密码错误");
},
reg() {
this.isReg = true;
},
addUser() {
if (this.name == '' || this.password == '') {
alert("必填用户名密码!!!");
return;
} if (this.password !== this.passwordRepeat) {
alert("两次密码不一致!!!");
return;
} localStorage.setItem("name", this.name);
localStorage.setItem("password", this.password);
this.name = '';
this.password = '';
alert("注册成功!");
this.isReg = false;
},
cancel() {
this.isReg = false;
}
},
};
</script> <style scoped lang="scss">
.rowBtn{
width: 100%;
height: 40px;
font-size: 20px;
text-align: center;
line-height: 40px;
margin-top: 10px;
background: #87CEEB; &.regBtn{
background: #20B2AA;
}
}
</style>

  定义了两个表单,登录和注册用的,用isReg属性进行切换。注册成功保存到本地localStorage。

views/Home.vue

<template>
<div class="home">
<router-view/>
<ul class="footer">
<router-link class="icons" to="/home/user">个人中心</router-link>
<router-link class="icons" to="/home/contact">通讯录</router-link>
</ul>
</div>
</template> <script>
export default {
name: 'home',
};
</script> <style scoped lang="scss">
li{
list-style: none;
}
.footer{
position: fixed;
width: 100%;
height: 60px;
line-height:60px;
left: 0px;
bottom: 0px;
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
}
.icons{
font-size: 16px;
flex: 1;
text-align:center;
border-top: 1px solid #42b983;
} a {
color: #42b983;
&.active{
color: #fff;
background:#42b983;
}
}
</style>

  定义了两个子路由,并用secc语法定义了样式。例如样式 a 里面的&.active 会被解析为 a.active,&代表当前选择器。 scoped  代表默认的css作用域是当前页面,如果不写会影响全局css样式,一般为当前页面。

views/Uer.vue

<template>
<div class="user">
个人中心。欢迎您: {{getLoginUsername()}}
</div>
</template> <script>
import store from '@/store'; export default {
name: 'User',
store,
methods: {
getLoginUsername() {
return store.state.username
},
},
};
</script>

Contact.vue:

<template>
<div class="user">
通讯录
</div>
</template>

3.效果

(1)登录

(2)登录之后主页面

4.制作成app-利用hbuilder制作app

(1)执行 npm run build 之后生成dist文件。

(2)在hbuilder新建一项目将dist下文件考进去:W表示web项目,A表示APP项目

(3)右键dist项目然后选择 转换成移动APP

(4)然后发行为原生app即可。之前已经发行过一个mui的app。

  参考:https://www.cnblogs.com/qlqwjy/p/10428546.html

(5)手机端效果如下:

补充:项目中引入jquery

1.安装jquery

cnpm install jquery --save-dev

2.vue.config.js头部声明

const webpack = require("webpack")
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
jQuery: "jquery",
$: "jquery"
})
]
}
}

3.使用的地方引入即可:

import $ from 'jquery'

git地址:https://github.com/qiao-zhi/vue-demo.git

vue-cli安装以及创建一个简单的项目(二)(vuex使用、发行一个简单的app)的更多相关文章

  1. Vue Cli安装以及使用

      因为公司项目要用vue框架,所以会用vue-cli来新建项目.用过vue的都知道,要全局安装vue以及脚手架vue-cli,然后执行vue init webpack projectname来新建v ...

  2. Vue技术点整理-Vue CLI安装详解

     一,脚手架安装 Node 版本要求 Vue CLI 需要 Node.js +).你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本. 1,全局安装Vue CLI ...

  3. 基于vue cli 3.0创建前端项目并安装cube-ui

    前提条件: 安装node.js. 国内的开发者最好先配置淘宝镜像. 之后用cnpm来代替npm命令. 项目创建过程: 打开cmd,输入命令进入目标工作空间,以本机项目为例: cd /d d: cd D ...

  4. vue cli 3.0创建项目

    .npm i -g @vue/cli .vue create my-project 此处有两个选择: 1.default (babel, eslint)默认套餐,提供babel和eslint支持 2. ...

  5. Vue Cli 3:创建项目

    一 简介 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,有几个独立的部分. 1 CLI (@vue/cli) 是一个全局安装的 npm 包,提供了终端里的 vue 命令.(vue ...

  6. Vue CLI安装报错 npm ERR! Exit handler never called!

    安装Vue CLI时报错: npm install –g vue-cli 试了四种办法 1.把全局安装-g放到后面 npm install @vue/cli –g 2.命令行输入 npm 缓存清理命令 ...

  7. VUE环境安装和创建项目

    1.首先要安装nodejs和npm. 下载nodejs安装,下载地址:https://nodejs.org/en/ 安装很简单一路next即可. 安装完成后可以在cmd窗口输入node -v 和 np ...

  8. 使用Vue CLI 3快速创建项目

    首先 vue create ant-design-vue-pro 执行命令会显示两个选项,1默认,2自定义 我么选择自定义 选择好自定义的插件回车就等待下安装成功然后进入项目文件夹 cd ant-de ...

  9. vue cli 安装element-ui

    1.安装elment-ui --save 参数:上线打包 MacBookPro:vue_test zhangxm$ npm install element-ui axios --save npm WA ...

随机推荐

  1. python基础(25):面向对象三大特性二(多态、封装)

    1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...

  2. MySQL学习——数据类型

    MySQL学习——数据类型 摘要:本文主要学习了MySQL数据库的数据类型. 整数类型 MySQL主要提供的整数类型有tinyint.smallint.mediumint.int.bigint,其属性 ...

  3. Java8 日期和时间API

    LocalDate.LocalTime.Instant.Duration.Period 1.1使用LocalDate和LocalTime 1.1.1LocalDate的创建方式和相关方法使用示例 @T ...

  4. 远程连接docker

    vim /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix: ...

  5. image-webpack-loader包安装报错解决

    在家里安装这个包,总是报错安装失败,换成最快的淘宝镜像也是如此,先卸载重新安装亦是如此,于是想到了原因,到了公司,公司的网是可以连接国外的,安装成功了! 也就是说,需要翻墙才可以装成功.

  6. vuejs之路由应用之二

    现在我们开始一个应用: 一个应用中包含4个组件,我们暂且可以想象是4个页面,首先是App.vue,App.vue中又包含3个子组件:About.vue,Home.vue,Document.vue Ap ...

  7. 关于OC中直接打印结构体(CGRectCGSize、CGPoint、UIOffset)等数据类型

    关于OC直接打印结构体,点(CGRect,CGSize,CGPoint,UIOffset)等数据类型,我们完全可以把其转换为OC对象来进项打印调试,而不必对结构体中的成员变量进行打印.就好比我们可以使 ...

  8. Android TextView文本处理库推荐

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/115 Android TextView文本处理库推荐 现在 ...

  9. rust语法

    目录 rust语法 前言 一.数据类型 1.1 标量scalar 1.2 复合compound 1.3 切片slice 1.4 引用(借用)reference 1.5 智能指针smart pointe ...

  10. liteos CPU占用率(十六)

    1. 概述 1.1 基本概念 CPU(中央处理器, Central Processing Unit)占用率可以分为系统CPU占用率和任务CPU占用率两种. 系统CPU占用率(CPU Percent)是 ...