npm init -y
npm install vue vue-router -S
npm install babel-loader babel-core vue-loader node-sass sass-loader css-loader style-loader webpack webpack-cli webpack-dev-server html-webpack-plugin vue-template-compiler -D
一些依赖的作用:
babel-core
的作用是把 js 代码分析成 ast ,方便各个插件分析语法进行相应的处理。有些新语法在低版本 js 中是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为 ast,分析其语法后再转为低版本 js。首先安装 babel-core。
babel-loader
作用:使用babel-loader处理js文件,会将es5以上的语法进行转义(无法转义es6 API) babel-loader必须和babel-core结合使用,babel-core封装了babel-loader需要用到的api
css-loader
是帮助webpack打包处理css文件的工具
html-webpack-plugin
- 为html文件中引入的外部资源如
script
、link
动态添加每次compile后的hash,防止引用缓存的外部文件问题- 可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个
html-webpack-plugin
可以生成N个页面入口
node-sass
允许用户以令人难以置信的速度将.scss文件本地编译为css,并通过连接中间件自动编译。Sass是一种预处理器脚本语言,可以解释或编译成层叠样式表(CSS)
sass-loader
就是为了转换和编译scss文件 node-sass是核心插件
style-loader
是将css-loader
打包好的css代码以标签的形式插入到html文件中
vue-loader
会解析文件,提取出每个语言块,如果有必要会通过其他loader处理,最后将他们组装成一个commonjs模块
vue-template-compiler
作用: 该模块可用于将 Vue 2.0 模板预编译为渲染函数(template => ast => render),以避免运行时编译开销和 CSP 限制。大都数场景下,与 vue-loader一起使用,只有在编写具有非常特定需求的构建工具时,才需要单独使用它。 内容安全策略 (CSP) 是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入等攻击。
webpack
模块打包工具
webpack-cli
用于在命令行中运行webpack,cli即命令行接口(Command Line Interface)
webpack-dev-server
可以为webpack打包生成的资源文件提供web服务
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --config webpack.config.js"
},
{
"name": "vue2",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --config webpack.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"vue": "^2.6.14",
"vue-router": "^3.5.3"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.1",
"html-webpack-plugin": "^5.5.0",
"node-sass": "^7.0.0",
"sass-loader": "^12.4.0",
"style-loader": "^3.3.1",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.6.0"
}
}
//index.html 在body元素下增加id为app的div元素,用于挂载vue实例
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>vue2title>
head>
<body>
<div id="app">div>
body>
html>
- App.vue
- main.js
- views/home.vue
- views/content.vue
- router/index.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
el: '#app',
router,
render: h => h(App)
})
// render: h => h(App)是ES6的写法,其实就是如下内容的简写:
// render: function (createElement) {
// return createElement(App);
// }
// 然后ES6写法,
// render: createElement => createElement(App)
// 然后用h代替createElement,使用箭头函数来写:
// render: h => h(App)
// 官方文档中是这样的,createElement 是 Vue.js 里面的 函数,这个函数的作用就是生成一个 VNode节点,
//render 函数得到这个 VNode 节点之后,返回给 Vue.js 的 mount 函数,渲染成真实 DOM 节点,并挂载到根节点上。
// 也就是说,createElement 函数是用来生成 HTML DOM 元素的,而上文中的 Hyperscript也是用来创建HTML结构的脚本,这样作者才把 createElement 简写成 h。
Home
Content
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
title: '首页',
component: () => import('../views/home.vue')
},
{
path: '/content',
name: 'content',
title: '内容',
component: () => import('../views/content.vue')
}
]
const router = new VueRouter({
routes
})
router.beforeEach((to, from, next) => {
console.log(to)
next()
})
export default router
//webpack 是一个用于现代 JavaScript应用程序的静态模块打包工具。当 webpack处理应用程序时,
//它会在内部构建一个依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
// loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
//想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。
//多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建一个插件实例。
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const config = {
//入口文件 入口起点(entry point)指示webpack应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。
//进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
entry: path.join(__dirname, 'src/main.js'),
//输出文件 output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。
output: {
filename: 'bundle.js',//filename: 配置输出文件名,可添加路径配置(例子中js/)
path: path.join(__dirname, 'dist')//path: 文件的输出路径,必须是绝对地址
},
//通过选择 development(生产模式), production(开发模式)或 none 之中的一个,来设置 mode 参数,你可以启用 webpack 内置在相应环境下的优化。
//其默认值为 production。
mode: 'development', // 设置mode,
module: {
rules: [
{
test: /\.vue$/,//test 属性,识别出哪些文件会被转换。
use: 'vue-loader',// use 属性,定义出在进行转换时,应该使用哪个 loader。
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
]
},
plugins: [
new VueLoaderPlugin(),
//生成html页面并导入bundle.js,如果配置了filename则以项目中filename指定的html为模版
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
})
]
}
module.exports = config
最后npm run dev 页面效果为
-----------------------------------------分割线-------------------------------------------------
接下来是添加vuex axios element-ui等
npm install vuex
在main.js中注入vuex
import Vuex from 'vuex'
import store from "./store";
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
(转载于:https://blog.csdn.net/Ed7zgeE9X/article/details/112165249)
index.html
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>Vuex Example - Jump Start Vue.jstitle>
<link rel="stylesheet" type="text/css"
href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css">
<style type="text/css">
body {
background-color: #FFFFFF;
}
.ui.menu .item img.logo {
margin-right: 1.5em;
}
.main.container {
margin-top: 7em;
}
style>
head>
<body>
<div id="app">div>
body>
html>
App.vue
src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
users: [],
selectedUserId: null,
isFetching: false
},
mutations: {
setUsers(state, { users }) {
state.users = users;
},
setSelectedUser(state, id) {
state.selectedUserId = id;
},
setIsFetching(state, bool) {
state.isFetching = bool;
}
},
getters: {
selectedUser: state =>
state.users.find(user => user.login.uuid === state.selectedUserId)
},
actions: {
fetchUsers({ commit }) {
commit("setIsFetching", true);
return axios
.get("https://randomuser.me/api/?nat=gb,us,au&results=5&seed=abc")
.then(res => {
setTimeout(() => {
commit("setIsFetching", false);
commit("setUsers", { users: res.data.results });
}, 2500);
})
.catch(error => {
commit("setIsFetching", false);
console.error(error);
});
}
}
});
src/views/Home.vue
<template>
<div class="ui main text container">
<h1 class="ui header">Vuex 数据管理</h1>
<p>This is a basic Vuex example app, to demo the concepts learned in the
➥accompanying chapter.</p>
<p>Go to <router-link to="/about">About</router-link></p>
</div>
</template>
<script>
export default {
name: "home"
}
</script>
src/views/About.vue
<template>
<div class="ui main text container">
<h1 class="ui header">About</h1>
<div class="ui active inverted dimmer" v-if="isFetching">
<div class="ui text loader">Loading</div>
</div>
<ul v-else>
<li v-for="(user, index) in users" :key="index">
<router-link :to="{ name: 'about', params: { id: user.login.uuid }}">
{{ user.name.title }} {{ user.name.first }} {{ user.name.last }}
</router-link>
</li>
</ul>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "About",
computed: {
...mapState([
'isFetching',
'users'
])
}
}
</script>
<style>
li {
text-transform: capitalize;
}
</style>
src/views/demo.vue
<template>
<div class="ui main text container" v-if="selectedUser">
<div class="ui items">
<div class="item">
<div class="image">
<img :src="selectedUser.picture.large">
</div>
<div class="content">
<a class="header">{{ fullName }}</a>
<div class="meta">
<span>{{ selectedUser.email }}</span>
</div>
<div class="description">
<p>{{ selectedUser.location.street }}, {{ selectedUser.location.city }},
{{ selectedUser.location.state }}, {{ selectedUser.location.postcode }}
</p>
</div>
<div class="extra">
{{ selectedUser.phone }}<br />
{{ selectedUser.cell }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
export default {
name: "Users",
computed: {
...mapGetters(["selectedUser"]),
fullName() {
return `${this.selectedUser.name.first} ${this.selectedUser.name.last}`;
}
},
methods: {
...mapMutations(["setSelectedUser"])
},
created() {
const userId = this.$route.params.id;
this.setSelectedUser(userId);
}
};
</script>
<style scoped>
a.header, p {
text-transform: capitalize;
}
</style>
src/router/index.js
import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import About from "./views/About.vue";
import Demo from "./views/Demo.vue";
Vue.use(Router);
export default new Router({
mode: "history",
linkActiveClass: "active",
routes: [
{
path: "/",
name: "home",
component: Home
},
{
name: "about",
path: "/about",
component: About
},
{
name: "demo",
path: "/about/:id",
component: Demo
}
]
});
npm install axios -S
在main.js 中引入
import axios from 'axios'
npm install element-ui -S
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
npm install element-ui -S
npm install babel-plugin-component -D
在根目录中创建文件.babelrc
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
在main.js中引入
import Vue from 'vue';
import 'element-ui/lib/theme-chalk/index.css'
import { Button, Card } from 'element-ui'
import App from './App.vue';
Vue.use(Button)
Vue.use(Card)
new Vue({
el: '#app',
render: h => h(App)
});