20200115
笔试
输入一堆人名,然后输出格式化的名字比如:list([{name:'Bart'},{name:'Lisa'},{name:'Maggie'}]) return 'Bert,Lisa & Maggie';list([]) return ''
function list(arr){
if(Object.prototype.toString.call(arr) !== '\[object Array\]') return 'arr is not an Array';
let newArr=\[\];
arr.forEach(element=>{
if(element.name){
newArr.push(element.name)
}else{
console.log('arr is not contained name');
}
});
let last=newArr.pop();
let str=newArr.join(',');
if(last===undefined) return '';
if(newArr.length===0) return last;
str+=' & '+last;
return str;
}
输入一个字符串,找出其中最长的不重复的子字符串,并返回子字符串长度。例如:字符长'abcabcbb',最长的不重复的子字符串是'abc',长度是3 写一个函数,参数是一个字符串,返回值是其中最长的不重复的子字符串的长度
function maxStrLength(str){
let i=0,res=0,n=0;
for(let j=0;j<str.length;j++){
n=str.slice(i,j).indexOf(str\[j\]);
if(n==-1){
res=Math.max(res,j+1-i);
}else{
i+=n+1;
}
}
return res;
}
行内元素有哪些?块级元素有哪些?空(void)元素有哪些?
行内元素:a、b、span、img、input、strong、select、label、em、button、textarea
块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote
空元素:即系没有内容的HTML元素,例如:br、meta、hr、link、input、img
css选择符有哪些?优先级如何计算?
\- 选择器类型:
- ID #id
- class .class
- 标签 p
- 通用 \*
- 属性 \[type="text"\]
- 伪类 :hover
- 伪元素 ::first-line
- 子选择器、相邻选择器
\- 权重计算规则:
- 第一等:代表内联样式,如: style=””,权值为1000。
- 第二等:代表ID选择器,如:#content,权值为0100。
- 第三等:代表类,伪类和属性选择器,如.content,权值为0010。
- 第四等:代表类型选择器和伪元素选择器,如div p,权值为0001。
- 通配符、子选择器、相邻选择器等的。如\*、>、+,权值为0000。
- 继承的样式没有权值。
使用原生方式或熟悉的JS库写一个AJAX调用,请用JSON数据格式传输和返回
function getXHR() { //html元素事件触发的函数
var myXMLHttpRequest = null;
if (window.ActiveXObject) {
myXMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} else {
myXMLHttpRequest = new XMLHttpRequest();
}
var url = "xxx.php";
var data = "key=val"; //val一般是从某个html元素中取出的value值
myXMLHttpRequest.open("post", url, true);
myXMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
myXMLHttpRequest.onreadystatechange = function(){
if (myXMLHttpRequest.readyState == 4 && myXMLHttpRequest.status == 200) {
var res = myXMLHttpRequest.responseText;
var jsonObj = eval("("+res+")");
//接下来就可以使用jsonObj这个json对象取出其中的属性值,做一些修改html元素value值等操作了。
}
}
myXMLHttpRequest.send(data);
}
jQuery
response.write("{ username : '"+username+"' , content : '"+content+"'}")
由于服务器端返回的数据格式是JSON文档,因此也需要对文档的数据进行处理,但是JSON文档比较XML文档更容易解析。
$.ajax({
type:"POST",
url:"Handler.ashx",
dataType:json,
data:{username:$("#name").val(),password:$("#pwd").val()},
success:function(data){
var username = data.username;
var content = data.content;
var txtHtml = "<div class='comment'><h6>"+ username+":</h6><p class='para'>"+content+"</p></div>";
$("#result").html(txtHtml)
}
}
\`\`\`
#### 请用伪代码描述一个排序算法
快速排序
\`\`\`
function quickSort(arr,left,right){
let len=arr.length,
partitionIndex,
left=typeof left != 'number' ? 0 : left,
right=typeof right != 'number' ? len-1 : right;
if(left<right){
partitionIndex=partition(arr,left,right);
quickSort(arr,left,partitionIndex-1);
quickSort(arr,partitionIndex+1,right);
}
return arr;
}
function partition(arr,left,right){
let pivot=left,
index=pivot+1;
for(let i=index;i<=right;i++){
if(arr\[i\]<arr\[pivot\]){
swap(arr,i,index);
index++;
}
}
swap(arr,pivot,index-1);
return index-1;
}
function swap(arr,i,j){
let temp=arr\[i\];
arr\[i\]=arr\[j\];
arr\[j\]=temp;
}
JavaScript创建对象的方式有哪几种?
https://www.jianshu.com/p/1fb...
{}
new Object()
使用字面量
工厂模式
构造函数模式(constructor)
原型模式(prototype)
构造函数+原型模式
\`\`\`
### 原生js
#### 请简述一下js的原型和原型链
\`\`\`
什么是原型链:只要是对象就有原型, 并且原型也是对象, 因此只要定义了一个对象, 那么就可以找到他的原型, 如此反复, 就可以构成一个对象的序列, 这个结构就被称为原型链
所有的实例有一个内部指针(prototype),指向它的原型对象,并且可以访问原型对象上的所有属性和方法。
js继承有几种方式?
6种
方式一:借助构造函数实现继承
这里使用的原理就是在Child里面,把Parent的this指向改为是Child的this指向,从而实现继承
function Parent(name){
this.name=name;
}
Parent.prototype.saiHi=function(){
console.log("hello")
}
function Child(name,age,gender){
Parent.call(this,name)
this.age=age;
this.gender=gender;
}
let child=new Child("王磊",20,"男")
console.log(child.name);// 王磊
child.sayHi(); // Uncaught TypeError:child.sayHi is not a function
缺点:只能解决属性的继承,使用属性的值不重复,但是父级类别的方法不能继承
方式二:借助原型链实现继承
第二种方式就是把Child的原型改为是Parent的实例,从而实现继承
function Parent(name,gender){
this.name=name;
this.gender=gender;
this.list=\[1,2,3\]
}
Parent.prototype.eat=function(){
console.log("晚餐时间到")
}
function Child(age){
this.age=age;
}
Child.prototype=new Parent("李白","男");
var child=new Child(20);
var child2=new Child(30);
child.eat();
console.log(child.list,child2.list);// \[1,2,3\] \[1,2,3\]
child.list.push(4)
console.log(child.list);// \[1,2,3,4\]
console.log(child2.list);// \[1,2,3,4\]
缺点:因为Child的原型对象都是New Parent,所以实例化出来的对象的属性都是一样的,而且Parent上面的引用类型只要有一个实例对象修改了,其他也会跟着修改.因为他们原型对象都是共用的
方式三:组合型
方式三的话是结合了方式一和方式二来实现继承
function Person(school){
this.school=school;
}
Person.prototype.skill=function(){
console.log("学习");
}
function Student(school,name,age,gender){
Parent.call(this,school);
this.name=name;
this.age=age;
this.gender=gender;
}
Student.prototype=Person.prototype;
let student=new Student("广铁一中","王菲菲",14,"女");
console.log(Student.prototype===Person.prototype)
console.log(student.constructor)
缺点:父类的原型对象调用了两次,没有必要,而且student实例的构造函数是来自于Person
方式四:组合方式优化
function Parent(name,play){
this.name=name;
this.play=play;
}
function Child(name,play,age){
Parent.call(this,name,play);
this.age=age;
}
Child.prototype=Parent.prototype;
let child=new Child("张三","玩",20);
let child2=new Child("李四","吃",10)
console.log(child,child2)
console.log(child.prototype===child2.prototype); true
console.log(child.constructor); // 构造函数指向的是Parent
缺点:child实例的构造函数来自于Parent
方式五: 组方式优化
只是这种方式的话,你必须得理解Object.create()方法的使用,他创建的对象是在原型上面的
function Parent(name,play){
this.name=name;
this.play=play;
}
function Child(name,play,age){
Parent.call(this,name,play);
this.age=age;
}
Child.prototype=Object.create(Parent.prototype);// 隔离了父类和子类的构造函数,父类的添加到了\_\_proto\_\_属性上
Child.prototype.constructor=Child
let child=new Child("张三","玩",20);
let child2=new Child("李四","吃",10)
console.log(child.constructor)
如何实现promise
完整版
const PENDING='pending';
const FULFILLED='fulfilled';
const REJECTED='rejected';
function MyPromise(fn){
const self=this;
self.value=null;
self.error=null;
self.status=PENDING;
self.onFulfilledCallbacks=\[\];
self.onRejectedCallbacks=\[\];
function resolve(value){
if(value instanceof MyPromise){
return value.then(resolve,reject);
}
if(self.status===PENDING){
setTimeout(()=>{
self.status=FULFILLED;
self.value=value;
self.onFulfilledCallbacks.forEach((callback)=>callback(self.value));
},0)
}
}
function reject(error){
if(self.status===PENDING){
setTimeout(function(){
self.status=REJECTED;
self.error=error;
self.onRejectedCallbacks.forEach((callback)=>callback(self.error))
},0)
}
}
try{
fn(resolve,reject);
}catch(e){
reject(e);
}
}
function resolvePromise(bridgepromise,x,resolve,reject){
if(bridgepromise===x){
return reject(new TypeError('Circular reference'));
}
let called=false;
if(x instanceof MyPromise){
if(x.status===PENDING){
x.then(y=>{
resolvePromise(bridgepromise,y,resolve,reject)
},error=>{
reject(error);
})
}else{
x.then(resolve,reject)
}
}else if(x!=null && ((typeof x === 'object') || (typeof x === 'function'))){
try{
let then=x.then;
if(typeof then === 'function'){
then.call(x,y=>{
if(called) return;
called=true;
resolvePromise(bridgepromise,y,resolve,reject)
},error=>{
if(called) return;
called=true;
reject(error);
})
}else{
resolve(x);
}
}catch(e){
if(called) return;
called=true;
reject(e);
}
}else{
resolve(x);
}
}
MyPromise.prototype.then=function(onFulfilled,onRejected){
const self=this;
let bridgePromise;
onFulfilled=typeof onFulfilled==='function'?onFulfilled:value=>value;
onRejected=typeof onRejected==='function'?onRejected:error=>{throw error};
if(self.status===FULFILLED){
return bridgePromise=new MyPromise((resolve,reject)=>{
setTimeout(()=>{
try{
let x=onFulfilled(self.value);
resolvePromise(bridgePromise,x,resolve,reject);
}catch(e){
reject(e);
}
},0)
})
}
if(self.status===REJECTED){
return bridgePromise=new MyPromise((resolve,reject)=>{
setTimeout(()=>{
try{
let x=onRejected(self.error);
resolvePromise(bridgePromise,x,resolve,reject);
}catch(e){
reject(e);
}
},0)
})
}
if(self.status===PENDING){
return bridgePromise=new MyPromise((resolve,reject)=>{
self.onFulfilledCallbacks.push((value)=>{
try{
let x=onFulfilled(value);
resolvePromise(bridgePromise,x,resolve,reject)
}catch(e){
reject(e);
}
});
self.onRejectedCallbacks.push((error)=>{
try{
let x=onRejected(error);
resolvePromise(bridgePromise,x,resolve,reject);
}catch(e){
reject(e);
}
});
});
}
}
MyPromise.prototype.catch=function(onRejected){
return this.then(null,onRejected);
}
MyPromise.deferred=function(){
let defer={};
defer.promise=new MyPromise((resolve,reject)=>{
defer.resolve=resolve;
defer.reject=reject;
});
return defer;
}
try{
module.exports=MyPromise;
}catch(e){}
简版
function myPromise(constructor){
let self=this;
self.status='pending';
self.vlaue=undefined;
self.reason=undefined;
function resolve(value){
if(self.status==='pending'){
self.value=value;
self.status='resolved';
}
}
function reject(reason){
if(self.status==='pending'){
self.reason=reason;
self.status='rejected';
}
}
try{
constructor(resolve,reject);
}catch(e){
reject(e);
}
}
myPromise.prototype.then=function(onFullfilled,onRejected){
let self=this;
switch(self.status){
case 'resolved':
onFullfilled(self.value);
break;
case 'rejected':
onRejected(self.reason);
break;
default:
}
}
let和var的区别
\- const定义的变量不可以修改,而且必须初始化
\- var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
\- let是块级作用域,函数内部使用let定义后,对函数外部无影响。
css
水平垂直居中都有哪些方式?
\- 绝对定位水平垂直居中
<div color: rgb(212, 212, 212);"> width: 500px;
height: 300px;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: green;">水平垂直居中</div>
\- 水平垂直居中
<div color: rgb(212, 212, 212);"> width:400px;
height:200px;
top: 50%;
left: 50%;
margin: -100px 0 0 -200px;
background-color: red;">水平垂直居中</div>
\- 水平垂直居中
<div color: rgb(212, 212, 212);"> width:300px;
height:200px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: blue;">水平垂直居中</div>
\- flex 布局居中
<div >
<div >flex 布局</div>
</div>
如何实现一个烟花爆炸的效果
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>js烟花效果</title>
<script type="text/javascript">
document.onclick=function (ev)
{
var oEvent=ev||event;
var aDiv=\[\];
var oDiv=null;
var \_oDiv=document.createElement('div');
var i=0;
var x=oEvent.clientX;
var y=oEvent.clientY;
\_oDiv.style.position='absolute';
\_oDiv.style.background='red';
\_oDiv.style.width='3px';
\_oDiv.style.height='30px';
\_oDiv.style.left=oEvent.clientX+'px';
\_oDiv.style.top=document.documentElement.clientHeight+'px';
document.body.appendChild(\_oDiv);
var t=setInterval(function (){
if(\_oDiv.offsetTop<=y)
{
clearInterval(t);
show();
document.body.removeChild(\_oDiv);
}
\_oDiv.style.top=\_oDiv.offsetTop-30+'px';
}, 30);
function show()
{
var oDiv=null;
for(i=0;i<100;i++)
{
oDiv=document.createElement('div');
oDiv.style.width='3px';
oDiv.style.height='3px';
oDiv.style.background='#'+Math.ceil(Math.random()\*0xEFFFFF+0x0FFFFF).toString(16);
oDiv.style.position='absolute';
oDiv.style.left=x+'px';
oDiv.style.top=y+'px';
var a=Math.random()\*360;
//oDiv.speedX=Math.random()\*40-20;
//oDiv.speedY=Math.random()\*40-20;
oDiv.speedX=Math.sin(a\*180/Math.PI)\*20\*Math.random();
oDiv.speedY=Math.cos(a\*180/Math.PI)\*20\*Math.random();
document.body.appendChild(oDiv);
aDiv.push(oDiv);
}
}
setInterval(doMove, 30);
function doMove()
{
for(i=0;i<aDiv.length;i++)
{
aDiv\[i\].style.left=aDiv\[i\].offsetLeft+aDiv\[i\].speedX+'px';
aDiv\[i\].style.top=aDiv\[i\].offsetTop+aDiv\[i\].speedY+'px';
aDiv\[i\].speedY+=1;
if(aDiv\[i\].offsetLeft<0 || aDiv\[i\].offsetLeft>document.documentElement.clientWidth || aDiv\[i\].offsetTop<0 || aDiv\[i\].offsetTop>document.documentElement.clientHeight)
{
document.body.removeChild(aDiv\[i\]);
aDiv.splice(i, 1);
}
}
}
};
</script>
</head>
<body >
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css3实现烟花特效</title>
<style>
\* {
margin: 0;
padding: 0;
}
html{
width: 100%;
height: 100%;
}
body{
width: 100%;
height: 100%;
}
#container{
width: 100%;
height: 100%;
background-color: black;
position: relative;
}
#fireworks{
position: absolute;
left: 50%;
margin-left: -250px;
bottom: 60%;
margin-bottom: -180px;
transform: scale(0);
animation: fireworks 5s 3s;
}
@keyframes fireworks {
0%{
transform: scale(0);
}
80%{
transform: scale(1);
}
100%{
opacity: 0;
}
}
#firecracker{
position: absolute;
left: 50%;
bottom: 0%;
margin-left: -4px;
animation: firecracker 3s forwards;
}
@keyframes firecracker {
0%{
transform: scale(1);
bottom: 0%;
}
100%{
bottom: 60%;
transform: scale(0);
}
}
</style>
</head>
<body>
<div id="container">
<div id="fireworks"><img src="imgs/fireworks.png" alt=""></div>
<div id="firecracker"><img src="imgs/firecracker.png" alt="" width="8px"></div>
</div>
</body>
</html>
\`\`\`
### 框架
#### vue的生命周期都有哪些?
\`\`\`
Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
生命周期中有多个事件钩子,如下:
\- beforeCreate(创建前) 在数据观测和初始化事件还未开始
\- created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
\- beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
\- mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
\- beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
\- updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
\- beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
\- destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
封装组件需要考虑哪些内容?
开发通用组件是很基础且重要的工作,通用组件必须具备高性能、低耦合的特性
一、数据从父组件传入
为了解耦,子组件本身就不能生成数据。即使生成了,也只能在组件内部运作,不能传递出去。
父对子传参,就需要用到 props,但是通用组件的的应用场景比较复杂,对 props 传递的参数应该添加一些验证规则
二、在父组件处理事件
在通用组件中,通常会需要有各种事件,
比如复选框的 change 事件,或者组件中某个按钮的 click 事件
这些事件的处理方法应当尽量放到父组件中,通用组件本身只作为一个中转
三、记得留一个 slot
一个通用组件,往往不能够完美的适应所有应用场景
所以在封装组件的时候,只需要完成组件 80% 的功能,剩下的 20% 让父组件通过 solt 解决
四、不要依赖 Vuex
父子组件之间是通过 props 和 自定义事件 来传参,非父子组件通常会采用 Vuex 传参
但是 Vuex 的设计初衷是用来管理组件状态,虽然可以用来传参,但并不推荐
因为 Vuex 类似于一个全局变量,会一直占用内存
在写入数据庞大的 state 的时候,就会产生内存泄露
五、合理运用 scoped 编写 CSS
在编写组件的时候,可以在 <style> 标签中添加 scoped,让标签中的样式只对当前组件生效
但是一味的使用 scoped,肯定会产生大量的重复代码
所以在开发的时候,应该避免在组件中写样式
当全局样式写好之后,再针对每个组件,通过 scoped 属性添加组件样式
vue中数据传递都有哪些方式?
\- 父组件向子组件传值 --Props传递数据
在父组件中使用儿子组件
<template>
<div>
父组件:{{money}}
<Son1 :money="money"><Son1>
</div>
</template>
<script>
import Son1 from ''./Son1";
export default{
components:{
Son1
},
data(){
return { money: 100};
}
};
</script>
子组件接受数据
props:{
value:{
type:Number,
default:1
}
}
如果是数组
props:{
value:{
type:Array,
default: ()=>\[\]
}
}
\- 子组件通信父组件 $emit使用
<template>
<div>
父组件:{{money}}
<Son1 :money="money" @input="change"><Son1>
</div>
</template>
<script>
import Son1 from ''./Son1";
export default{
methods:{
change(data){
this.money = data
}
},
components:{
Son1
},
data(){
return { money: 100};
}
};
</script>
子组件触发绑定自己身上的方法
<template>
<div>
子组件1:{{money}}
<button @click="$emit('input',200)">修改父组件的值<Son1>
</div>
</template>
<script>
export default{
props:{
money:{
type:Number
}
}
};
</script>
\- $parent、$children(多层级传递)
<Grandson1 :value="value"></Grandson1>
<template>
<div>
孙子1:{{value}}
<---调用父组件的input事件-->
<button @click="$parent.$emit('input',200)">更改<Son1>
</div>
</template>
<script>
export default{
props:{
value:{
type:Number
}
}
};
</script>
\- $attrs、 $listeners:
$attrs批量向下传入属性:
<Son2 name="小明" age="18"></Son2>
<--可以在son2组件中使用$attrs,可以将属性继续向下传递-->
<div>
儿子2:{{ $attrs.name }}
<Grandson2 v-bind="$attrs"></Grandson2>
</div>
<tempalte>
<div>孙子:{{$attrs}}</div>
</template>
$listeners批量向下传入方法:
<Son2 name="小明" age="18" @click=“()=>{this.money =500}”></Son2>
<--可以在son2组件中使用$attrs,可以将属性继续向下传递-->
<Grandson2 v-bind="$attrs" v-on="$listeners"></Grandson2>
<button @click="$listeners.click()">更改<Son1>
\- Provide&Inject
Provide 在父级中注入数据
provide(){
return {parentMsg:'父亲'};
}
Inject
在任意子组件中可以注入父级数据
inject:\['parentMsg'\]//会将数据挂载在当前实例上
\- ref使用
<Grandson2 name="花花" ref="grand2"></Grandson2>
mounted(){
console.log(this.$refs.grand2.name);
}
\- EventBus:用于跨组件通知
Vue.prototype.$bus = new Vue();
Son2组件和Grandson1互相通信
mounted() {
//父亲组件注册
this.$bus.$on('my',data=>{
console.log(data)
})
}
mounted(){
//侄子组件调用
this.$nextTick(()=>{
this.$bus.$emit('my',"我是小红”);
})
}
vuex和eventBus的区别是什么?
http://dongfanker.coding.me/2...
为什么需要Bus
一般来说,都是利用父组件给子组件使用query或者params传递参数来实现子组件的数据显示
不过,当出现子组件需要向父组件传递数据的时候,就需要用到bus,bus可以自己创建,也可以通过装包来实现
直接创建Bus
在此处直接将Bus注入Vue对象中,成为全局的组件。
在子组件中通过this.$root.Bus.$on(key,method),this.$root.Bus.$emit(key,data)来调用
将$on放在mounted,created这些钩子函数中,相应的函数使用(e)=>{function}比较便捷
1
2
3
4
5
6
7
8
9
10
import Vue from 'vue'
const Bus = new Vue()
var app= new Vue({
el:'#app',
data:{
Bus
}
})
使用vue-bus
使用yarn或者npm安装vue-bus之后,在main.js中引用它
1
2
import VueBus from 'vue-bus';
Vue.use(VueBus);
于是调用直接可以写为 this.$bus.on(key, this.method),this.$bus.emit(key, { text: …… }
其中第一个字符串参数代表key,每个key都能够实现自己的独立传输,this.method为事先定义好的method,用于对传入的数据进行处理
为什么使用vuex
当我们的应用遇到多个组件共享状态时,会需要:
多个组件依赖于同一状态。
来自不同组件的行为需要变更同一状态。
经过我的观察,vuex在其中的作用就是组件与状态的捆绑剥离开来,使得组件状态的改变依赖于某个行为,这使得代码变得易于调试。
Vuex采用集中式存储管理应用的所有组件的状态,这里的关键在于集中式存储管理。这意味着本来需要共享状态的更新是需要组件之间通讯的,而现在有了vuex,就组件就都和store通讯了。
使用vuex
使用yarn或者npm安装vuex之后,在main.js中引用它
1
2
3
4
5
6
7
import Vuex from 'vuex'
import store from './vuex/store'
Vue.use(Vuex)
new Vue({
el: '#app',
store
})
随后创建vuex目录,将store.js放在目录下,定义state和mutation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
author: 'Wise Wrong'
},
mutations:{
newAuthor(state,msg){
state.author = msg
}
}
})
export default store
在使用的时候,不直接修改this.$store.state.author,而是使用this.$store.commit()来提交,可以让我们更好的跟踪每一个状态的变化,在大型项目中更为适用
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。