diff --git a/packages/taro-harmony/src/components/components-harmony/navigator/index.css b/packages/taro-harmony/src/components/components-harmony/navigator/index.css
new file mode 100644
index 000000000000..361795c5fddd
--- /dev/null
+++ b/packages/taro-harmony/src/components/components-harmony/navigator/index.css
@@ -0,0 +1,8 @@
+.navigate {
+ overflow: hidden;
+ transition: all linear 0.2s;
+}
+
+.navigator-hover {
+ background-color: #dedede;
+}
diff --git a/packages/taro-harmony/src/components/components-harmony/navigator/index.hml b/packages/taro-harmony/src/components/components-harmony/navigator/index.hml
new file mode 100644
index 000000000000..f66919327b0f
--- /dev/null
+++ b/packages/taro-harmony/src/components/components-harmony/navigator/index.hml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/packages/taro-harmony/src/components/components-harmony/navigator/index.js b/packages/taro-harmony/src/components/components-harmony/navigator/index.js
new file mode 100644
index 000000000000..d634e8955344
--- /dev/null
+++ b/packages/taro-harmony/src/components/components-harmony/navigator/index.js
@@ -0,0 +1,92 @@
+import router from '@system.router'
+import { createOption, queryToJson } from '../utils'
+
+export default createOption({
+ props: {
+ id: {
+ default: ''
+ },
+ openType: {
+ default: 'navigate'
+ },
+ url: {
+ default: ''
+ },
+ hoverStartTime: {
+ default: 50
+ },
+ hoverStayTime: {
+ default: 600
+ },
+ hoverClass: {
+ default: 'navigator-hover'
+ }
+ },
+
+ data () {
+ return {
+ targetObj: {
+ navigate: 'push',
+ redirect: 'replace',
+ switchTab: 'push',
+ reLaunch: 'replace',
+ navigateBack: 'back'
+ },
+ hover: false,
+ touch: false
+ }
+ },
+
+ computed: {
+ clsHover () {
+ return this.hover ? this.hoverClass : ''
+ }
+ },
+
+ onClick () {
+ const { openType = 'navigate', url = '' } = this
+ this.getRouterFunc(`${openType}`, url)
+ },
+
+ getRouterFunc (method, url) {
+ // switchTab目前实现不了
+ const methodName = this.targetObj[method]
+ const [uri, queryString = ''] = url.split('?')
+ const params = queryToJson(queryString)
+
+ const uriObj = url ? { uri: uri.replace(/^\//, '') } : {}
+
+ const paramsObj = queryString ? { params } : {}
+
+ if (method === 'reLaunch') {
+ router.clear()
+ }
+
+ router[methodName]({
+ ...uriObj,
+ ...paramsObj
+ })
+ },
+
+ onTouchStart () {
+ this.touch = true
+ if (this.hoverClass) {
+ setTimeout(() => {
+ if (this.touch) {
+ this.hover = true
+ }
+ }, this.hoverStartTime)
+ }
+ },
+
+ onTouchEnd () {
+ this.touch = false
+ if (this.hoverClass) {
+ setTimeout(() => {
+ if (!this.touch) {
+ this.hover = false
+ }
+ }, this.hoverStayTime)
+ }
+ }
+})
diff --git a/packages/taro-harmony/src/components/components-harmony/utils/index.js b/packages/taro-harmony/src/components/components-harmony/utils/index.js
index 062aeb52d80e..3e5b77afb487 100644
--- a/packages/taro-harmony/src/components/components-harmony/utils/index.js
+++ b/packages/taro-harmony/src/components/components-harmony/utils/index.js
@@ -8,3 +8,34 @@ export function createOption (option) {
}
return option
}
+
+export function queryToJson (str) {
+ const dec = decodeURIComponent
+ const qp = str.split('&')
+ const ret = {}
+ let name
+ let val
+ for (let i = 0, l = qp.length, item; i < l; ++i) {
+ item = qp[i]
+ if (item.length) {
+ const s = item.indexOf('=')
+ if (s < 0) {
+ name = dec(item)
+ val = ''
+ } else {
+ name = dec(item.slice(0, s))
+ val = dec(item.slice(s + 1))
+ }
+ if (typeof ret[name] === 'string') {
+ ret[name] = [ret[name]]
+ }
+
+ if (Array.isArray(ret[name])) {
+ ret[name].push(val)
+ } else {
+ ret[name] = val
+ }
+ }
+ }
+ return ret
+}