vue-cli3全⽅方位对⽐比vue-cli2
参考地址:https://cli.vuejs.org/zh/config/#vue-config-js
安装vue-cli
// 安装vue到全局中
npm install -g @vue/cli
npm install -g yarn
// 输出版本号即为安装成功
vue -V
生成的目录结构介绍
3.0的目录简单了很多,少了build、config两个目录。需要对webpack进行配置的话,要手动在根目录新建一个vue.config.js文件
vue.config.js常用配置
// vue.config.js 常用配置
module.exports = {
// 基本路径, vue.cli 3.3以前请使用baseUrl
publicPath: '/',
// 输出文件目录
outputDir: 'dist',
// 用于嵌套生成的静态资产(js,css,img,fonts)的目录。
assetsDir: '',
// 生产环境sourceMap
productionSourceMap: true,
// webpack配置
configureWebpack: () => {},
chainWebpack: () => {},
// css相关配置
css: {
// 启用 CSS modules
modules: false,
// 是否使用css分离插件
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {},
},
// webpack-dev-server 相关配置
devServer: {
host: '0.0.0.0',
port: 8080,
proxy: {}, // 设置代理
},
// 第三方插件配置
pluginOptions: {
// ...
}
}
在base-learn根目录中新建一个vue.config.js,内容如下
module.exports = {
devServer: {
port: 8088,
open: true
}
}
进入文件夹中,启动项目,自动在浏览器中打开网页
cd .\base-learn\
npm run serve
删除views下的.vue文件
app.vue只留下如下代码
router下的index.js内容如下
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
// component: Home
},
{
// path: '/about',
// name: 'About',
// // 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/About.vue')
}
]
const router = new VueRouter({
// routes
})
export default router
写代码之前先安装vscode的一个插件Vue VSCode Snippets,能快速帮我们生成vue代码,官网如下:https://marketplace.visualstudio.com/items?itemName=sdras.vue-vscode-snippets
在页面中使用vb+tab快速生成代码
父子组件传值
示例一代码
Parent.vue代码
Parent
{
{msg}}
Child.vue代码
Child
{
{msg}}
示例二代码
Parent.vue代码
Parent
{
{msg}}
Child.vue代码
Child
{
{msg}}
非父子间传值
事件总线
// 原理上就是建立一个公共的js文件,专门用来传递消息
// bus.js
import Vue from 'vue'
export default new Vue;
// 在需要传递消息的地方引入
import bus from './bus.js'
// 传递消息
bus.$emit('msg', val)
// 接受消息
bus.$on('msg', val => {
this.childMsg = val
})
示例代码,完成通过app.vue传给child.vue数据
首先在项目中新建一个util文件夹,存放bus.js,内容如下
在app.vue中触发vue的方法
在child.vue中写入监听事件
Child
{
{childMsg}}
$attrs / $listeners
// 解决多级组件间传值的问题
// $attr 将父组件中不包含props的属性传⼊子组件,通常配合 interitAttrs 选项一起使用。
// 如果不想在dom上出现属性,可设置interitAttrs: false
// $listeners监听子组件中数据变化,传递给父组件
演示一个$attrs的例子,在app.vue中通过v-bind传给child.vue
app.vue的内容如下,把要传给child的msg通过父组件传入
父组件通过$attrs转一下转给子组件
Parent
子组件得到这个$attrs,内容就是app.vue传过来的内容
Child
基本参数
views文件夹下新加一个Home.vue
this is home
router-link标签跳转,这个很简单,只需要在router/index.js中进行配置
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/home',
name: 'Home',
// 使用路由懒加载的形式
component: () => import('../views/Home.vue'),
},
]
const router = new VueRouter({
routes
})
export default router
在app.vue中进行使用
home
访问http://localhost:8088/#/,点击页面的home超链接,就会在页面中渲染home的内容
编程式导航
// route可以是对象,或者是字符串
// 对象的时候可通过路由的path或者name进行跳转
// 字符串的话只能是路由的path
this.$router.push(route)
// 路由传递参数, query和path配合, params和name配合
query: this.$router.push({path: '/', query: {id: 2}})
params: this.$router.push({name: 'home', params: {id: 2}})
一个按钮跳转的例子
什么是动态路由
{
path: '/home/:id',
component: home
}
一个例子app.vue内容如下
Home.vue,展示出传过来的参数的值,内容如下
this is home
{
{$route.query.name}}
index.js主要是配置路由
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/home', // 进入的是一个需要传递参数的页面
// path: '/home/:name',
name: 'Home',
// 使用路由懒加载的形式
component: () => import('../views/Home.vue'),
},
]
const router = new VueRouter({
routes
})
export default router
⽬目的:组件中嵌套不同组件,一般用来实现头部和尾部
实现
// 在需要嵌套的路由中补充children字段
{
path: '/home/:id',
component: home,
children: []
}
修改Home.vue只需要加入
即可完成占坑
this is home
{
{$route.query.name}}
在router/index.js中,对路由/home指定一个children
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/home', // 进入的是一个需要传递参数的页面
// path: '/home/:name',
name: 'Home',
// 使用路由懒加载的形式
component: () => import('../views/Home.vue'),
children: [{
path: 'child',
component: () => import('../views/1Child.vue')
}],
},
]
const router = new VueRouter({
routes
})
export default router
这样我们访问http://localhost:8088/#/home/child,坑就渲染出来了
通过router中的beforeEach注册全局守卫,每次切换路由时触发,常用来做权限判断
// to, from是路由对象,我们在路由里定义的参数都可以在这里取到,例如to.path或
from.name
router.beforeEach((to, from, next) => {
// ...
next()
})
参数
在main.js中加入以下代码,每次访问链接都会输出路径
router.beforeEach((to, from, next) => {
console.log(to.path)
next()
})
提高页面加载速度
避免进入项目后加载全部组件
在路由中的component中设置函数,用import方式进行使用
State
数据,存放一些公用部分的数据
Mutations
数据怎么改变,定义改变state的一些方法(主要是定义一些同步的方法)
Actions
异步改变, 如果需要异步改变state,则在这书写(主要是定义一些异步的方法,当然也可以定义一些同步的方法)
vuex里包含的基本参数
export default {
// 组件间公共数据部分
state: {},
// 需要改变state中的数据时,要在mutation里定义改变的方法
mutations: {},
// 当改变state中的数据是异步操作时,在action里里定义
actions: {}
}
示例代码
在store/index.js添加如下函数的代码
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0,
},
mutations: { // 简单理解成组件的methods,一般是同步的方法
add (state) {
state.count++
},
decrease (state) {
state.count--
}
},
actions: { // 可以定义同步和异步的方法,一般是异步的方法
delayAdd (context) {
setTimeout(() => {
context.commit('add')
}, 1000);
}
},
modules: {
}
})
在router/index.js中添加测试的vue页面
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/', // 进入的是一个需要传递参数的页面
// 使用路由懒加载的形式
component: () => import('../views/5Parent.vue'),
}
]
const router = new VueRouter({
routes
})
export default router
5Parent.vue内容如下,测试改变vuex中的数据
Parent
vuex {
{count}}
更多使用方法参考官网:https://vuex.vuejs.org/zh/guide
vuex中的计算属性—Getters
state: {
count: 0,
},
// 根据state中的count进⼀一步处理理,计算双倍值
getters: {
doubleCount (state) {
return state.count * 2
}
},
示例代码,在store/index.js下添加getters
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0,
},
getters: {
doubleCount (state) {
return state.count * 2
}
},
mutations: { // 简单理解成组件的methods,一般是同步的方法
add (state) {
state.count++
},
decrease (state) {
state.count--
}
},
actions: { // 可以定义同步和异步的方法,一般是异步的方法
delayAdd (context) {
setTimeout(() => {
context.commit('add')
}, 1000);
}
},
modules: {
}
})
在5Parent.vue去使用这个getters
Parent
vuex {
{count}}
getters {
{showDoneCount}}
可以看到showDoneCount的值是跟着count改变的
模块化概念—Modules
import Vue from 'vue'
import Vuex from 'vuex'
// 第一步 引⼊入模块
import text from './text'
Vue.use(Vuex)
// 第二步 在初始化store时,加载模块
export default new Vuex.Store({
modules: {
text
}
})
在store文件夹下创建一个text.js,把之前index.js定义的内容移动过去
export default {
state: {
count:0,
},
getters: {
doubleCount (state) {
return state.count * 2
}
},
mutations: { // 简单理解成组件的methods,一般是同步的方法
add (state) {
state.count++
},
decrease (state) {
state.count--
}
},
actions: { // 可以定义同步和异步的方法,一般是异步的方法
delayAdd (context) {
setTimeout(() => {
context.commit('add')
}, 1000);
}
},
}
现在index.js的内容就比较少了
import Vue from 'vue'
import Vuex from 'vuex'
import text from './text'
Vue.use(Vuex)
export default new Vuex.Store({
modules:{
text
}
})
我们在5Parent.vue使用的,只需要修改变量信息,方法和getters都不需要改
Parent
vuex {
{count}}
getters {
{showDoneCount}}
打开页面,同样可以看到和上面没修改之前一样的效果