关于vue.js:vue30vitetypescript入门到精通

vue3.0入门到精通
vue3.0beta+vite+typescript+vue-router4beta+vuex4beta基于compositionAPI入门到实战
附B站视频解说:vue3.0收费视频教程vite+CompositionAPI+typescript入门到精通

www.bilibili.com
图标
vue3.0 装置
前装置过vue的2.0版本,你须要把2.0相干的删除
npm uni -g vue-cli
装置vue/cli脚架
npm i -g @vue/cli
查看版本号,目前装置vuecli 4.5.4
vue -V
创立:在命令窗口输出指令
抉择default vue 3
vue create 项目名称
vue composition API
vue3.0 侧重于解决代码组织与逻辑复用问题
目前,咱们应用的是“options”API 构建组件。 为了将逻辑增加到Vue组件中,咱们填充(options)属性,如data、methods、computed等。 这种办法最大的毛病是,它自身不是一个工作的JavaScript代码。 您须要确切地晓得模板中能够拜访哪些属性以及this关键字的行为。在底层,Vue编译器须要将此属性转换为工作代码。正因为如此,咱们无奈从主动倡议或类型查看中获益。
Composition API心愿将通过以后组件属性、可用的机制公开为JavaScript函数来解决这个问题。 Vue外围团队将组件Composition API形容为“一套附加的、基于函数的api,容许灵便地组合组件逻辑”。 应用Composition API编写的代码更易读,并且场景不简单,这使得浏览和学习变得更容易。
让咱们看到一个非常简单的组件示例,它应用新的组件Composition API来了解它是如何工作的。
<template>
<div id=”app”>

![](./assets/logo.png)
<div>{{msg}}年龄为{{age}}</div>
<button @click="add"> + </button>

</div>
</template>

<script>


export default {
name: ‘App’,
data() {

return {
  msg:'王大合',
  age:18
}

},
methods:{

add() {
  this.age += 1
}

}

}
</script>

setup
vue3.0将组件的逻辑都写在了函数外部,setup()会取代vue2.x的data()函数,返回一个对象,裸露给模板,而且只在初始化的时候调用一次,因为值能够被跟踪,所以咱们通过vue3来扭转编程习惯
首先引入ref
应用数据须要return
import {ref} from ‘vue’

setup() {

const msg = ref('王大合')
const age = ref(18)
function add() {
  age.value +=1
}
return {msg,age,add}

}
computed
<template>
<div id=”app”>

![](./assets/logo.png)
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<button @click="add">+</button>

</div>
</template>

<script>
import {computed, ref} from ‘vue’

export default {

name: ‘App’,
setup() {

const msg = ref('王大合')
const age = ref(18)
const double = computed(() =>{
  return age.value * 2
})
function add() {
  age.value += 1
}
return {msg,age,add,double}

}
}
</script>


reactive
在 setup 函数外面, 咱们适应了 Vue3.0 的第一个新接口 reactive 它次要是解决你的对象让它通过 Proxy 的加工变为一个响应式的对象,

toRefs
用于将响应式对象变成一般对象
<template>
<div id=”app”>

![](./assets/logo.png)
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<button @click="add">+</button>

</div>
</template>

<script>
import {computed, reactive,toRefs} from ‘vue’

export default {

name: ‘App’,
setup() {

const state = reactive({
    msg:'王大合',
    age:18,
    double : computed(() =>{
  return state.age * 2
})
})

function add() {
  state.age += 1
}
return {...toRefs(state),add}

}
}
</script>



props 和 context
在 Vue2.0 中咱们能够应用 props 属性值实现父子通信,在这里咱们须要定义 props 属性去定义承受值的类型,而后咱们能够利用 setup 的第一个参数获取 props 应用。
export default {

name: ‘App’,
components:{

Content

},
setup() {

const state = reactive({
    msg:'王大合',
    age:18,
    double : computed(() =>{
  return state.age * 2
})
})

function add() {
  state.age += 1
}
return {...toRefs(state),add}

}
}
咱们在 App.vue 外面就能够应用该头部组件,有了下面的 props 咱们能够依据传进来的值,让这个头部组件出现不同的状态。
<template>
<div id=”app”>

![](./assets/logo.png)
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<Content :msg='msg' />
<button @click="add">+</button>

</div>
</template>
这里我新建一个新的组件content,在app.vue中引入
<!– –>
<template>
<div>{{data}}</div>
</template>

<script>
import {ref} from ‘vue’
export default {
name:’content’,
props:{

 msg:String

},
setup(props) {

 const data = ref(props.msg)
 return {data}

}
}

</script>
setup 函数的第二个参数是一个上下文对象,这个上下文对象中蕴含了一些有用的属性,这些属性在 Vue2.0 中须要通过 this 能力拜访到,在 vue3.0 中,拜访他们变成以下模式:
setup(props, ctx) {
console.log(ctx) // 在 setup() 函数中无法访问到 this
console.log(this) // undefined
}
具体能拜访到以下有用的属性:

  • slot
  • attrs
  • emit

父组件
<template>
<div id=”app”>

![](./assets/logo.png)
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<Content :msg='msg' @change='showName' />
<button @click="add">+</button>

</div>
</template>

<script>
import {computed, reactive,toRefs} from ‘vue’
import Content from ‘./components/content.vue’
export default {

name: ‘App’,
components:{

Content

},

setup() {

const state = reactive({
    msg:'王大合',
    age:18,
    double : computed(() =>{
      return state.age * 2
    })
})
function showName(params) {
    alert(params)
}

function add() {
  state.age += 1
}
return {...toRefs(state),add,showName}

}
}
</script>



子组件
<!– –>
<template>
<div>{{data}}</div>
<button @click=”changeName”>打个招呼!</button>
</template>

<script>
import {ref} from ‘vue’
export default {
name:’content’,
props:{

 msg:String

},
setup(props,context) {

 const data = ref(props.msg)
function changeName() {
    context.emit('change','Hello,王大合!')
}
 return {data,changeName}

}
}

</script>
watch
监听ref
不指定数据源
const a = ref(18)

watch(()=>{

console.log(a.value)

})
指定数据源
const a = ref(18)

watch(a,()=> {

console.log(a.value)

})
监听reactive
const state = reactive({

    msg:'王大合',
    age:18,
    double : computed(() =>{
      return state.age * 2
    })
})

不指定数据源
watch(()=>{

console.log(state.age)

})
指定数据源
watch(()=>state.age,()=>{

console.log(state.age)

})
回调函数参数以及watche clean,应用clean时候是解决重复性的watch监听事件
watch(() => state.age,(newVal,oldVal,clean)=> {

 console.log(state.msg + "去年年纪:"+oldVal +"往年年纪:" + newVal)
 clean(
   ()=>{
     console.log('clean')
   }
 )

})
vue3.X+vite+typescript
放弃webpack,应用vite装置vue3.0
这个是尤大开发的新工具,目标是当前代替webpack,原理是利用浏览器当初曾经反对es6的import了,遇到import会发送一个http申请去加载文件,vite拦挡这些申请,做一些预编译,省去了webpack简短打包的工夫,晋升开发体验
npm install -g create-vite-app
create-vite-app vue3-vite
cd vue3-vite
npm install
npm run dev

或者应用yarn

yarn add -g create-vite-app
yarn create vite-app <project-name>
装置依赖
yarn
应用yarn启动我的项目
yarn dev

引入typescript

装置 typescript


yarn add typescript -D
初始化tsconfig.json

而后在控制台执行上面命令

npx tsc –init
将main.js批改为main.ts,同时将index.html外面的援用也批改为main.ts,
而后在script 里增加 lang=”ts”
<template>

<HelloWorld msg=”Hello Vue 3.0 + Vite” />
</template>

<script lang=”ts”>
import HelloWorld from ‘./components/HelloWorld.vue’

export default {
name: ‘App’,
components: {

HelloWorld

}
}
</script>

批改完之后,重启就能够拜访我的项目了。尽管这样配置是能够了,然而关上main.ts会发现import App from App.vue会报错:Cannot find module ‘./App.vue’ or its corresponding type declarations.,这是因为当初ts还没有辨认vue文件,须要进行上面的配置:
在我的项目根目录增加shim.d.ts文件

powerShell终端,也能够手动创立

New-Item shim.d.ts
增加以下内容
declare module “*.vue” {
import { Component } from “vue”;
const component: Component;
export default component;
}

装置vue-router
yarn add vue-router@4.0
这样能够抉择最新的vue-router 4.0.0的测试版本,这里更新到beta.13
配置vue-router
在我的项目src目录上面新建router目录,而后增加index.ts文件,在文件中增加以下内容
import {createRouter, createWebHashHistory} from ‘vue-router’

// 在 Vue-router新版本中,须要应用createRouter来创立路由
export default createRouter({
// 指定路由的模式,此处应用的是hash模式
history: createWebHashHistory(),
// 路由地址
routes: []
})
装置vuex
同上
yarn add vuex@4.0
目前只能抉择最新测试版
在我的项目src目录上面新建store目录,并增加index.ts文件,文件中增加以下内容
import { createStore } from ‘vuex’

interface State {
userName: string
}

export default createStore({

state:{
userName:'王大合'
}

});
main.ts中引入vuex和vue-router
import { createApp } from ‘vue’
import App from ‘./App.vue’
import ‘./index.css’
import router from ‘./router/index’
import vuex from ‘./store/index’

const app = createApp(App)

app.use(router)
app.use(vuex)
app.mount(‘#app’)

上线小我的项目todoList
app.vue
<template>
<div id=”app”>

<div id="nav">
  <router-link to="/">todoList</router-link> | 
  <router-link to="/about">About</router-link>
</div>
<router-view/>

</div>
</template>

<script lang=”ts”>

export default {
name: ‘App’
}
</script>

<style lang=”scss”>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}

nav {

padding: 30px;

a {

font-weight: bold;
color: #2c3e50;

&.router-link-exact-active {
  color: #42b983;
}

}
}
</style>
配置路由 router/index.ts
import {createRouter, createWebHashHistory} from ‘vue-router’

// 在 Vue-router新版本中,须要应用createRouter来创立路由
export default createRouter({
// 指定路由的模式,此处应用的是hash模式
history: createWebHashHistory(),
// 路由地址
routes: [

{
path: '/',
// 必须增加.vue后缀
component: () => import('../views/todo-list.vue')
  },
{
    path: '/about',
    name: 'About',
   
    component: () => import('../views/About.vue')
  }

]
})
store的index.ts新建vuex
import { createStore } from ‘vuex’

interface State {
userName: string
taskList: any[]

}

export default createStore({
state: {


  userName: "王大合",
  taskList: []
  

},
mutations:{


createTask (state:any, newTask:string) {
    state.taskList.push(newTask)
  },
  deleteTask (state:any, index:number) {
    state.taskList.splice(index, 1)
  },
  updateStatus (state:any, payload:any) {
    const { index, status } = payload

    state.taskList[index].isfinished = status
  }

}
});
在src目录新建view文件夹,创立todoList和about
todoList

<template>
<div class=”home”>

<!-- input输出list内容 -->
<div>
   <input
@keyup.enter="addTask"
  class="input"
  type="text"
  v-model="inputValue"
  placeholder="请输出" />
</div>
<!-- todoList内容展现和删除 -->
 <ul class="ul">
  <li class="item" v-for="(item, index) in taskList" :key="index">
    <p
    @click="updateStatus(index, !item.isfinished)"
    class="content"
    :class="item.isfinished ? 'active' : ''"
    >{{item.lable}}</p>
    <div class="item-delete" @click="deleteTask(index)">X</div>
  </li>
  <li v-if="taskList.length === 0" class="item-none">暂无数据</li>
</ul>

</div>
</template>


<script lang=”ts”>

import { ref, computed } from ‘vue’;
import { useStore } from “vuex”;
export default {

setup() {

const store = useStore()
const taskList = computed(() => store.state.taskList);
const inputValue = ref('');
const addTask = () => {
  store.commit('createTask', {
    lable: inputValue.value,
    isfinished: false
  })

  inputValue.value = ''
}

const updateStatus = (index, status) => {
  store.commit('updateStatus', {
    index,
    status
  })
}

const deleteTask = (index) => {
  store.commit('deleteTask', index)
}

return {
  inputValue,
  taskList,
  addTask,
  updateStatus,
  deleteTask
};

}
}
</script>

<style scoped lang=’scss’>

  • {
    box-sizing: border-box;
    margin: 0;
    padding: 0;

}
ul,
li {
list-style: none;

text-align: left;
}
.home {
max-width: 400px;
margin: 0 auto;
.input {

width: 100%;
height: 40px;
border-radius: 5px;
outline-style: none;
border: 2px solid #999;
padding: 5px 10px;

}
.ul {

margin-top: 10px;

}

.item {

height: 40px;
line-height: 40px;
padding-bottom: 5px;
border-bottom: 1px solid #dcdfe6;
color: #333333;

}
.item-none {

height: 40px;
line-height: 40px;
padding-bottom: 5px;
color: #333333;
text-align: center;

}
.content {

float: left;
height: 40px;
line-height: 40px;
cursor: pointer;

}
p.active {

text-decoration:line-through; 
color: #999999;

}
.item-delete {

float: right;
width: 25px;
text-align: center;
cursor: pointer;

}
}
</style>
about
<template>
<div class=”about”>

<h1>{{name}}</h1>

</div>
</template>

<script lang=’ts’>
import { ref, watch } from ‘vue’;

export default {
name: ‘about’,
setup() {

const name = ref('王大合出品');




return {
  name,
 
};

}
};
</script>

vue3.0入门到精通

vue3.0beta+vite+typescript+vue-router4beta+vuex4beta基于compositionAPI入门到实战

附B站视频解说:

vue3.0收费视频教程vite+CompositionAPI+typescript入门到精通_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com

vue3.0 装置

前装置过vue的2.0版本,你须要把2.0相干的删除

npm uni -g vue-cli

装置vue/cli脚架

npm i -g @vue/cli

查看版本号,目前装置vuecli 4.5.4

vue -V

创立:在命令窗口输出指令

抉择default vue 3

vue create 项目名称

vue composition API

vue3.0 侧重于解决代码组织与逻辑复用问题

目前,咱们应用的是“options”API 构建组件。 为了将逻辑增加到Vue组件中,咱们填充(options)属性,如data、methods、computed等。 这种办法最大的毛病是,它自身不是一个工作的JavaScript代码。 您须要确切地晓得模板中能够拜访哪些属性以及this关键字的行为。在底层,Vue编译器须要将此属性转换为工作代码。正因为如此,咱们无奈从主动倡议或类型查看中获益。

Composition API心愿将通过以后组件属性、可用的机制公开为JavaScript函数来解决这个问题。 Vue外围团队将组件Composition API形容为“一套附加的、基于函数的api,容许灵便地组合组件逻辑”。 应用Composition API编写的代码更易读,并且场景不简单,这使得浏览和学习变得更容易。

让咱们看到一个非常简单的组件示例,它应用新的组件Composition API来了解它是如何工作的。

<template>
<div id=”app”>

<img alt="Vue logo" src="./assets/logo.png">
<div>{{msg}}年龄为{{age}}</div>
<button @click="add"> + </button>

</div>
</template>

<script>


export default {
name: ‘App’,
data() {

return {
  msg:'王大合',
  age:18
}

},
methods:{

add() {
  this.age += 1
}

}

}
</script>

setup

vue3.0将组件的逻辑都写在了函数外部,setup()会取代vue2.x的data()函数,返回一个对象,裸露给模板,而且只在初始化的时候调用一次,因为值能够被跟踪,所以咱们通过vue3来扭转编程习惯

首先引入ref

应用数据须要return

import {ref} from ‘vue’

setup() {

const msg = ref('王大合')
const age = ref(18)
function add() {
  age.value +=1
}
return {msg,age,add}

}

computed

<template>
<div id=”app”>

<img alt="Vue logo" src="./assets/logo.png">
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<button @click="add">+</button>

</div>
</template>

<script>
import {computed, ref} from ‘vue’

export default {

name: ‘App’,
setup() {

const msg = ref('王大合')
const age = ref(18)
const double = computed(() =>{
  return age.value * 2
})
function add() {
  age.value += 1
}
return {msg,age,add,double}

}
}
</script>


reactive

在 setup 函数外面, 咱们适应了 Vue3.0 的第一个新接口 reactive 它次要是解决你的对象让它通过 Proxy 的加工变为一个响应式的对象,

toRefs

用于将响应式对象变成一般对象

<template>
<div id=”app”>

<img alt="Vue logo" src="./assets/logo.png">
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<button @click="add">+</button>

</div>
</template>

<script>
import {computed, reactive,toRefs} from ‘vue’

export default {

name: ‘App’,
setup() {

const state = reactive({
    msg:'王大合',
    age:18,
    double : computed(() =>{
  return state.age * 2
})
})

function add() {
  state.age += 1
}
return {...toRefs(state),add}

}
}
</script>


props 和 context

在 Vue2.0 中咱们能够应用 props 属性值实现父子通信,在这里咱们须要定义 props 属性去定义承受值的类型,而后咱们能够利用 setup 的第一个参数获取 props 应用。

export default {

name: ‘App’,
components:{

Content

},
setup() {

const state = reactive({
    msg:'王大合',
    age:18,
    double : computed(() =>{
  return state.age * 2
})
})

function add() {
  state.age += 1
}
return {...toRefs(state),add}

}
}

咱们在 App.vue 外面就能够应用该头部组件,有了下面的 props 咱们能够依据传进来的值,让这个头部组件出现不同的状态。

<template>
<div id=”app”>

<img alt="Vue logo" src="./assets/logo.png">
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<Content :msg='msg' />
<button @click="add">+</button>

</div>
</template>

这里我新建一个新的组件content,在app.vue中引入

<!– –>
<template>
<div>{{data}}</div>
</template>

<script>
import {ref} from ‘vue’
export default {
name:’content’,
props:{

 msg:String

},
setup(props) {

 const data = ref(props.msg)
 return {data}

}
}

</script>

setup 函数的第二个参数是一个上下文对象,这个上下文对象中蕴含了一些有用的属性,这些属性在 Vue2.0 中须要通过 this 能力拜访到,在 vue3.0 中,拜访他们变成以下模式:

setup(props, ctx) {
console.log(ctx) // 在 setup() 函数中无法访问到 this
console.log(this) // undefined
}

具体能拜访到以下有用的属性:

  • slot
  • attrs
  • emit

父组件

<template>
<div id=”app”>

<img alt="Vue logo" src="./assets/logo.png">
<div>{{msg}}的年龄为{{age}}</div>
<div>{{double}}</div>
<Content :msg='msg' @change='showName' />
<button @click="add">+</button>

</div>
</template>

<script>
import {computed, reactive,toRefs} from ‘vue’
import Content from ‘./components/content.vue’
export default {

name: ‘App’,
components:{

Content

},

setup() {

const state = reactive({
    msg:'王大合',
    age:18,
    double : computed(() =>{
      return state.age * 2
    })
})
function showName(params) {
    alert(params)
}

function add() {
  state.age += 1
}
return {...toRefs(state),add,showName}

}
}
</script>


子组件

<!– –>
<template>
<div>{{data}}</div>
<button @click=”changeName”>打个招呼!</button>
</template>

<script>
import {ref} from ‘vue’
export default {
name:’content’,
props:{

 msg:String

},
setup(props,context) {

 const data = ref(props.msg)
function changeName() {
    context.emit('change','Hello,王大合!')
}
 return {data,changeName}

}
}

</script>

watch

监听ref

不指定数据源

const a = ref(18)

watch(()=>{

console.log(a.value)

})

指定数据源

const a = ref(18)

watch(a,()=> {

console.log(a.value)

})

监听reactive

const state = reactive({

    msg:'王大合',
    age:18,
    double : computed(() =>{
      return state.age * 2
    })
})

不指定数据源

watch(()=>{

console.log(state.age)

})

指定数据源

watch(()=>state.age,()=>{

console.log(state.age)

})

回调函数参数以及watche clean,应用clean时候是解决重复性的watch监听事件

watch(() => state.age,(newVal,oldVal,clean)=> {

 console.log(state.msg + "去年年纪:"+oldVal +"往年年纪:" + newVal)
 clean(
   ()=>{
     console.log('clean')
   }
 )

})

vue3.X+vite+typescript

放弃webpack,应用vite装置vue3.0

这个是尤大开发的新工具,目标是当前代替webpack,原理是利用浏览器当初曾经反对es6的import了,遇到import会发送一个http申请去加载文件,vite拦挡这些申请,做一些预编译,省去了webpack简短打包的工夫,晋升开发体验

npm install -g create-vite-app
create-vite-app vue3-vite
cd vue3-vite
npm install
npm run dev

或者应用yarn

yarn add -g create-vite-app
yarn create vite-app <project-name>

装置依赖

yarn

应用yarn启动我的项目

yarn dev

引入typescript

装置 typescript


yarn add typescript -D

初始化tsconfig.json

而后在控制台执行上面命令

npx tsc –init

将main.js批改为main.ts,同时将index.html外面的援用也批改为main.ts,

而后在script 里增加 lang=”ts”

<template>
<img alt=”Vue logo” src=”./assets/logo.png” />
<HelloWorld msg=”Hello Vue 3.0 + Vite” />
</template>

<script lang=”ts”>
import HelloWorld from ‘./components/HelloWorld.vue’

export default {
name: ‘App’,
components: {

HelloWorld

}
}
</script>

批改完之后,重启就能够拜访我的项目了。尽管这样配置是能够了,然而关上main.ts会发现import App from App.vue会报错:Cannot find module ‘./App.vue’ or its corresponding type declarations.,这是因为当初ts还没有辨认vue文件,须要进行上面的配置:

在我的项目根目录增加shim.d.ts文件

powerShell终端,也能够手动创立

New-Item shim.d.ts

增加以下内容

declare module “*.vue” {
import { Component } from “vue”;
const component: Component;
export default component;
}

装置vue-router

yarn add vue-router@4.0

这样能够抉择最新的vue-router 4.0.0的测试版本,这里更新到beta.13

配置vue-router

在我的项目src目录上面新建router目录,而后增加index.ts文件,在文件中增加以下内容

import {createRouter, createWebHashHistory} from ‘vue-router’

// 在 Vue-router新版本中,须要应用createRouter来创立路由
export default createRouter({
// 指定路由的模式,此处应用的是hash模式
history: createWebHashHistory(),
// 路由地址
routes: []
})

装置vuex

同上

yarn add vuex@4.0

目前只能抉择最新测试版

在我的项目src目录上面新建store目录,并增加index.ts文件,文件中增加以下内容

import { createStore } from ‘vuex’

interface State {
userName: string
}

export default createStore({

state:{
userName:'王大合'
}

});

main.ts中引入vuex和vue-router

import { createApp } from ‘vue’
import App from ‘./App.vue’
import ‘./index.css’
import router from ‘./router/index’
import vuex from ‘./store/index’

const app = createApp(App)

app.use(router)
app.use(vuex)
app.mount(‘#app’)

上线小我的项目todoList

app.vue

<template>
<div id=”app”>

<div id="nav">
  <router-link to="/">todoList</router-link> | 
  <router-link to="/about">About</router-link>
</div>
<router-view/>

</div>
</template>

<script lang=”ts”>

export default {
name: ‘App’
}
</script>

<style lang=”scss”>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}

nav {

padding: 30px;

a {

font-weight: bold;
color: #2c3e50;

&.router-link-exact-active {
  color: #42b983;
}

}
}
</style>

配置路由 router/index.ts

import {createRouter, createWebHashHistory} from ‘vue-router’

// 在 Vue-router新版本中,须要应用createRouter来创立路由
export default createRouter({
// 指定路由的模式,此处应用的是hash模式
history: createWebHashHistory(),
// 路由地址
routes: [

{
path: '/',
// 必须增加.vue后缀
component: () => import('../views/todo-list.vue')
  },
{
    path: '/about',
    name: 'About',
   
    component: () => import('../views/About.vue')
  }

]
})

store的index.ts新建vuex

import { createStore } from ‘vuex’

interface State {
userName: string
taskList: any[]

}

export default createStore({
state: {


  userName: "王大合",
  taskList: []
  

},
mutations:{


createTask (state:any, newTask:string) {
    state.taskList.push(newTask)
  },
  deleteTask (state:any, index:number) {
    state.taskList.splice(index, 1)
  },
  updateStatus (state:any, payload:any) {
    const { index, status } = payload

    state.taskList[index].isfinished = status
  }

}
});

在src目录新建view文件夹,创立todoList和about

todoList


<template>
<div class=”home”>

<!-- input输出list内容 -->
<div>
   <input
@keyup.enter="addTask"
  class="input"
  type="text"
  v-model="inputValue"
  placeholder="请输出" />
</div>
<!-- todoList内容展现和删除 -->
 <ul class="ul">
  <li class="item" v-for="(item, index) in taskList" :key="index">
    <p
    @click="updateStatus(index, !item.isfinished)"
    class="content"
    :class="item.isfinished ? 'active' : ''"
    >{{item.lable}}</p>
    <div class="item-delete" @click="deleteTask(index)">X</div>
  </li>
  <li v-if="taskList.length === 0" class="item-none">暂无数据</li>
</ul>

</div>
</template>


<script lang=”ts”>

import { ref, computed } from ‘vue’;
import { useStore } from “vuex”;
export default {

setup() {

const store = useStore()
const taskList = computed(() => store.state.taskList);
const inputValue = ref('');
const addTask = () => {
  store.commit('createTask', {
    lable: inputValue.value,
    isfinished: false
  })

  inputValue.value = ''
}

const updateStatus = (index, status) => {
  store.commit('updateStatus', {
    index,
    status
  })
}

const deleteTask = (index) => {
  store.commit('deleteTask', index)
}

return {
  inputValue,
  taskList,
  addTask,
  updateStatus,
  deleteTask
};

}
}
</script>

<style scoped lang=’scss’>

  • {
    box-sizing: border-box;
    margin: 0;
    padding: 0;

}
ul,
li {
list-style: none;

text-align: left;
}
.home {
max-width: 400px;
margin: 0 auto;
.input {

width: 100%;
height: 40px;
border-radius: 5px;
outline-style: none;
border: 2px solid #999;
padding: 5px 10px;

}
.ul {

margin-top: 10px;

}

.item {

height: 40px;
line-height: 40px;
padding-bottom: 5px;
border-bottom: 1px solid #dcdfe6;
color: #333333;

}
.item-none {

height: 40px;
line-height: 40px;
padding-bottom: 5px;
color: #333333;
text-align: center;

}
.content {

float: left;
height: 40px;
line-height: 40px;
cursor: pointer;

}
p.active {

text-decoration:line-through; 
color: #999999;

}
.item-delete {

float: right;
width: 25px;
text-align: center;
cursor: pointer;

}
}
</style>

about

<template>
<div class=”about”>

<h1>{{name}}</h1>

</div>
</template>

<script lang=’ts’>
import { ref, watch } from ‘vue’;

export default {
name: ‘about’,
setup() {

const name = ref('王大合出品');




return {
  name,
 
};

}
};
</script>

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理