终端执行:
|-- dist # 打包后文件夹
|-- public # 静态文件夹
| |-- favicon.ico
| |-- index.html #入口页面
|-- src # 源码目录
| |--assets # 模块资源
| |--components # vue组件
| |--views # 视图文件
| |--App.vue # 公共主组件
| |--main.js # 入口文件,加载公共组件
| |--router.js # 路由配置
|-- vue.config.js # 配置文件
|-- .gitignore
|-- babel.config.js # babel语法编译
|-- package.json # 项目基本信息 ,npm包管理
以vuecli3为例,配置vue.config.js中的proxy
module.exports = {
devServer: {
proxy: {
'/api': {
target:'http://xxxxxx',//api地址
changeOrigin:true, //是否跨域
secure: false, //https改为true
pathRewrite: {'^/api' : ''},
}
},
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080,
},
publicPath: './',
}
利用Object.defineProperty()这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。
或者调用this.$forceUpdate()方法
1.什么是vue.js的生命周期:Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
2.各个生命周期的作用
mounted和created下都可以,本人建议是在created下调用。
因为组件可能被用来创建多个实例,如果data仍然是一个纯粹的对象,则所有的实例将共享引用一个数据对象,通过提供data函数,每次创建一个新的实例之后,我们能够调用data函数从而返回一个全新的副本数据对象,这样每一个实例都有自己私有的数据空间不会互相影响
常用的路由模式有hash和history;
最直观的区别是hash模式url上会携带有一个#,而history不携带;
即地址栏URL中的#符号,它的特点在于hash值虽然出现在URL中,但不会被包括在HTTP请求中,对服务端完全没影响,因此改变hash值不会重新加载页面。
利用了HTML5 History interface 中新增的pushState() 和 replaceState()方法。
这两个方法应用于浏览器历史记录栈,提供了修改历史记录的功能,执行修改时虽然改变了URL但是不会立即的向服务端发起请求。
因此可以说
hash和history模式都属于浏览器自身的特性,vue-router只是利用了这两个特性来实现前端路由
但是在history模式下会出现刷新404的问题,对于这个问题,我们只需要在服务器配置nginx如果URL匹配不到任何静态资源,就跳转到默认的index.html
location /{
root /data/nginx/html;
index index.html index.htm;
if (!-e $request_filename) {
rewrite ^/(.*) /index.html last;
break;
}
}
守卫的种类:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
router.afterEach((to, from) => {
// ...
})
在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫;
这和 router.beforeEach 类似;
区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
const router = new VueRouter({
routes: [
{
path: '/',
component: Index,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
第一步安装
npm install vuex -S
第二步创建store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
//创建Vuex实例对象
const store = new Vuex.Store({
strict:debug,//在不是生产环境下都开启严格模式
state:{
},
getters:{
},
mutations:{
},
actions:{
}
})
export default store;
第三步注入vuex
import Vue from 'vue';
import App from './App.vue';
import store from './store';
const vm = new Vue({
store:store,
render: h => h(App)
}).$mount('#app')
一共有5个核心属性,分别是:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
store.commit('increment')
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
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 的状态
存储: sessionStorage.setItem( '名', JSON.stringify(值) )
使用: sessionStorage.getItem('名') ---得到的值为字符串类型,用JSON.parse()去引号;
action 是用this.store.dispatch('ACTION_NAME',data)来提交。
mutation是用this.$store.commit('SET_NUMBER',10)来提交
{
state, // 等同于 `store.state`,若在模块中则为局部状态
rootState, // 等同于 `store.state`,只存在于模块中
commit, // 等同于 `store.commit`
dispatch, // 等同于 `store.dispatch`
getters, // 等同于 `store.getters`
rootGetters // 等同于 `store.getters`,只存在于模块中
}
需要通过computed计算属性来转换。
// ...
computed: {
message: {
get () {
return this.$store.state.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 display 属性进行切换。
所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。
1.Class 可以通过对象语法和数组语法进行动态绑定:
data: {
isActive: true,
hasError: false
}
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
2.Class 可以通过对象语法和数组语法进行动态绑定:
data: {
activeColor: 'red',
fontSize: 30
}
data: {
styleColor: {
color: 'red'
},
styleSize:{
fontSize:'23px'
}
}
在标签中加上ref='dom',然后在代码中this.$refs.dom这样就拿到了页面元素
例如:
让你好的颜色显示为红色:this.$refs.myBox.style.color = 'red
1.加载渲染过程:
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate
-> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted 2.子组件更新过程:
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated 3.父组件更新过程:
父 beforeUpdate -> 父 updated 4.销毁过程:
父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
@hook:监听的生命周期 = "自定义事件名"
// Parent.vue
doSomething() {
console.log('父组件监听到 mounted 钩子函数 ...');
},
// Child.vue
mounted(){
console.log('子组件触发 mounted 钩子函数 ...');
},
// 以上输出顺序为:
// 子组件触发 mounted 钩子函数 ...
// 父组件监听到 mounted 钩子函数 ...