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

2次阅读

共计 18577 个字符,预计需要花费 47 分钟才能阅读完成。

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>

正文完
 0